tc_http.cpp 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271
  1. #include "util/tc_http.h"
  2. #include "util/tc_port.h"
  3. #include "util/tc_common.h"
  4. #include "util/tc_clientsocket.h"
  5. #include "util/tc_network_buffer.h"
  6. #include <string.h>
  7. namespace tars
  8. {
  9. // const char* strnstr(const char* s1, const char* s2, int pos1)
  10. // {
  11. // int l1, l2;
  12. //
  13. // l2 = strlen(s2);
  14. // if (!l2)
  15. // return (char *)s1;
  16. // l1 = strlen(s1);
  17. //
  18. // pos1 = (pos1 > l1)?l1:pos1;
  19. //
  20. // while (pos1 >= l2) {
  21. // pos1--;
  22. // if (!memcmp(s1, s2, l2))
  23. // return (char *)s1;
  24. // s1++;
  25. // }
  26. // return NULL;
  27. // }
  28. unordered_map<string, int> TC_Http::HEADER = {
  29. {"GET", TC_HttpRequest::REQUEST_GET},
  30. {"POST", TC_HttpRequest::REQUEST_POST},
  31. {"PUT", TC_HttpRequest::REQUEST_PUT},
  32. {"PATCH", TC_HttpRequest::REQUEST_PATCH},
  33. {"OPTIONS", TC_HttpRequest::REQUEST_OPTIONS},
  34. {"PRI", TC_HttpRequest::REQUEST_PRI},
  35. {"DELETE", TC_HttpRequest::REQUEST_DELETE},
  36. {"HEAD", TC_HttpRequest::REQUEST_HEAD},
  37. };
  38. unordered_map<int, string> TC_Http::HEADER_REVERSE = {
  39. {TC_HttpRequest::REQUEST_GET, "GET"},
  40. {TC_HttpRequest::REQUEST_POST, "POST"},
  41. {TC_HttpRequest::REQUEST_PUT, "PUT"},
  42. {TC_HttpRequest::REQUEST_PATCH, "PATCH"},
  43. {TC_HttpRequest::REQUEST_OPTIONS, "OPTIONS"},
  44. {TC_HttpRequest::REQUEST_PRI, "PRI"},
  45. {TC_HttpRequest::REQUEST_DELETE, "DELETE"},
  46. {TC_HttpRequest::REQUEST_HEAD, "HEAD"},
  47. };
  48. bool TC_Http::CmpCase::operator()(const string &s1, const string &s2) const
  49. {
  50. if (TC_Port::strcasecmp(s1.c_str(), s2.c_str()) < 0)
  51. {
  52. return true;
  53. }
  54. else
  55. {
  56. return false;
  57. }
  58. }
  59. bool TC_URL::isValid() const
  60. {
  61. return !_sURL.empty();
  62. }
  63. string TC_URL::getURL() const
  64. {
  65. return _sURL;
  66. }
  67. string TC_URL::type2String() const
  68. {
  69. switch (_iURLType)
  70. {
  71. case HTTP:
  72. return "http";
  73. case HTTPS:
  74. return "https";
  75. case FTP:
  76. return "ftp";
  77. }
  78. return "http";
  79. }
  80. string TC_URL::getDefaultPort() const
  81. {
  82. switch (_iURLType)
  83. {
  84. case HTTP:
  85. return "80";
  86. case HTTPS:
  87. return "443";
  88. case FTP:
  89. return "21";
  90. }
  91. return "80";
  92. }
  93. bool TC_URL::isDefaultPort() const
  94. {
  95. return _sPort == getDefaultPort();
  96. }
  97. string TC_URL::toURL()
  98. {
  99. _sURL.clear();
  100. _sURL = _sScheme;
  101. _sURL += "://";
  102. if (!_sUser.empty())
  103. _sURL += _sUser;
  104. if (!_sUser.empty() && !_sPass.empty())
  105. {
  106. _sURL += ":";
  107. _sURL += _sPass;
  108. }
  109. if (!_sUser.empty())
  110. _sURL += "@";
  111. _sURL += _sDomain;
  112. if (!isDefaultPort())
  113. {
  114. _sURL += ":";
  115. _sURL += _sPort;
  116. }
  117. _sURL += getRequest();
  118. return _sURL;
  119. }
  120. string TC_URL::getRequest() const
  121. {
  122. string sURL;
  123. if (!_sPath.empty())
  124. sURL += _sPath;
  125. if (!_sQuery.empty())
  126. sURL += "?" + _sQuery;
  127. if (!_sRef.empty())
  128. sURL += "#" + _sRef;
  129. return sURL;
  130. }
  131. bool TC_URL::parseURL(const string &originRequest)
  132. {
  133. if (originRequest.empty())
  134. {
  135. return false;
  136. }
  137. clear();
  138. int iPos = 0;
  139. if (TC_Port::strncasecmp(originRequest.c_str(), "http://" , 7) == 0)
  140. {
  141. //http开头
  142. _iURLType = HTTP;
  143. iPos = 7;
  144. _sScheme = "http";
  145. }
  146. else if (TC_Port::strncasecmp(originRequest.c_str(), "https://" , 8) == 0)
  147. {
  148. //https开头
  149. _iURLType = HTTPS;
  150. iPos = 8;
  151. _sScheme = "https";
  152. }
  153. else if (TC_Port::strncasecmp(originRequest.c_str(), "ftp://", 6) == 0)
  154. {
  155. //ftps开头
  156. _iURLType = FTP;
  157. iPos = 6;
  158. _sScheme = "ftp";
  159. }
  160. else
  161. {
  162. //默认用http
  163. _iURLType = HTTP;
  164. iPos = 0;
  165. _sScheme = "http";
  166. }
  167. string::size_type index = originRequest.find("/", iPos);
  168. string::size_type nQuestionIndex = originRequest.find("?", iPos);
  169. string::size_type nNumbersignIndex = originRequest.find("#", iPos);
  170. string sUrlAuthority;
  171. string sUrlPath;
  172. if (nQuestionIndex < index)
  173. {
  174. sUrlAuthority = originRequest.substr(iPos, nQuestionIndex - iPos);
  175. sUrlPath += '/';
  176. sUrlPath += originRequest.substr(nQuestionIndex);
  177. }
  178. else if (nNumbersignIndex < index)
  179. {
  180. sUrlAuthority = originRequest.substr(iPos, nNumbersignIndex - iPos);
  181. sUrlPath += '/';
  182. sUrlPath += originRequest.substr(nNumbersignIndex);
  183. }
  184. else
  185. {
  186. if (index == string::npos)
  187. {
  188. sUrlAuthority = originRequest.substr(iPos, index);
  189. sUrlPath = "";
  190. }
  191. else
  192. {
  193. sUrlAuthority = originRequest.substr(iPos, index - iPos);
  194. sUrlPath = originRequest.substr(index);
  195. }
  196. }
  197. //////解析Authority
  198. index = sUrlAuthority.find("@");
  199. if (index != string::npos)
  200. {
  201. _sUser = sUrlAuthority.substr(0, index);
  202. _sDomain = sUrlAuthority.substr(index + 1);
  203. }
  204. else
  205. {
  206. _sDomain = sUrlAuthority;
  207. }
  208. //////解析User:Pass
  209. index = _sUser.find(":");
  210. if (index != string::npos)
  211. {
  212. _sPass = _sUser.substr(index + 1);
  213. _sUser = _sUser.substr(0, index);
  214. }
  215. //////解析Host:Port
  216. index = _sDomain.find(":");
  217. if (index != string::npos)
  218. {
  219. _sPort = _sDomain.substr(index + 1);
  220. _sDomain = _sDomain.substr(0, index);
  221. }
  222. else
  223. {
  224. _sPort = getDefaultPort();
  225. }
  226. //////解析Path Query Ref
  227. index = sUrlPath.find("?");
  228. if (index != string::npos)
  229. {
  230. _sPath = sUrlPath.substr(0, index);
  231. _sQuery = sUrlPath.substr(index + 1);
  232. index = _sQuery.rfind("#");
  233. if (index != string::npos)
  234. {
  235. _sRef = _sQuery.substr(index + 1);
  236. _sQuery = _sQuery.substr(0, index);
  237. }
  238. }
  239. else
  240. {
  241. _sPath = sUrlPath;
  242. _sQuery = "";
  243. index = _sPath.rfind("#");
  244. if (index != string::npos)
  245. {
  246. _sRef = _sPath.substr(index + 1);
  247. _sPath = _sPath.substr(0, index);
  248. }
  249. }
  250. if (_sPath.empty())
  251. {
  252. _sPath = "/";
  253. }
  254. toURL();
  255. if(_sPort == "0")
  256. {
  257. //unix local套接字模式
  258. _sDomain = TC_Common::replace(_sDomain, "$", FILE_SEP);
  259. return true;
  260. }
  261. //域名或者IP必须包含一个点
  262. if (_sDomain.find(".") == string::npos)
  263. {
  264. return false;
  265. }
  266. return true;
  267. }
  268. void TC_URL::specialize()
  269. {
  270. //规整化路径
  271. /*string sUrlPath = simplePath(getPath());
  272. _fragment["path"] = sUrlPath;*/
  273. _sPath = simplePath(getPath());
  274. _sURL = toURL();
  275. }
  276. void TC_URL::clear()
  277. {
  278. _sScheme = "";
  279. _sUser = "";
  280. _sPass = "";
  281. _sDomain = "";
  282. _sPort = "";
  283. _sPath = "";
  284. _sQuery = "";
  285. _sRef = "";
  286. _sURL.clear();
  287. }
  288. string TC_URL::getScheme() const
  289. {
  290. return _sScheme;
  291. }
  292. string TC_URL::getUserName() const
  293. {
  294. return _sUser;
  295. }
  296. string TC_URL::getPassword() const
  297. {
  298. return _sPass;
  299. }
  300. string TC_URL::getDomain() const
  301. {
  302. return _sDomain;
  303. }
  304. string TC_URL::getPort() const
  305. {
  306. return _sPort;
  307. }
  308. string TC_URL::getPath() const
  309. {
  310. return _sPath;
  311. }
  312. string TC_URL::getQuery() const
  313. {
  314. return _sQuery;
  315. }
  316. string TC_URL::getRef() const
  317. {
  318. return _sRef;
  319. }
  320. string TC_URL::getRelativePath() const
  321. {
  322. string sURL = getPath();
  323. string::size_type pos;
  324. pos = sURL.rfind("/");
  325. if (pos == string::npos)
  326. {
  327. return "/";
  328. }
  329. else
  330. {
  331. return sURL.substr(0, pos + 1);
  332. }
  333. }
  334. string TC_URL::getRootPath() const
  335. {
  336. string sURL = _sScheme;
  337. sURL += "://";
  338. if (!_sUser.empty())
  339. sURL += _sUser;
  340. if (!_sUser.empty() && !_sPass.empty())
  341. {
  342. sURL += ":";
  343. sURL += _sPass;
  344. }
  345. if (!_sUser.empty())
  346. sURL += "@";
  347. sURL += _sDomain;
  348. if (!isDefaultPort())
  349. {
  350. sURL += ":";
  351. sURL += _sPort;
  352. }
  353. sURL += "/";
  354. return sURL;
  355. }
  356. TC_URL TC_URL::buildWithRelativePath(const string &sRelativePath) const
  357. {
  358. string sURL;
  359. if (!sRelativePath.empty() && sRelativePath[0] == '/')
  360. {
  361. //如果链接是用"/"开头的相对地址,那么应该用Host+相对地址
  362. sURL = sRelativePath.substr(1);
  363. }
  364. else if (sRelativePath[0] == '#')
  365. {
  366. //#
  367. sURL = getPath().substr(1);
  368. if (!getQuery().empty())
  369. sURL += "?" + getQuery();
  370. sURL += sRelativePath;
  371. }
  372. else
  373. {
  374. //相对地址
  375. sURL = getRelativePath().substr(1) + sRelativePath;
  376. }
  377. sURL = getRootPath() + simplePath("/" + sURL).substr(1);
  378. TC_URL url;
  379. url.parseURL(sURL);
  380. return url;
  381. }
  382. string TC_URL::simplePath(const string &sPath) const
  383. {
  384. //所有./都去掉
  385. size_t pos = 0;
  386. string sNewPath = sPath;
  387. while (true)
  388. {
  389. size_t dotPos = sNewPath.find("./", pos);
  390. if (dotPos != string::npos)
  391. {
  392. if ((dotPos == 0) || (sNewPath.at(dotPos - 1) == '/'))
  393. {
  394. sNewPath.erase(dotPos, 2);
  395. }
  396. else
  397. {
  398. pos = dotPos + 2;
  399. }
  400. }
  401. else
  402. {
  403. break;
  404. }
  405. }
  406. //如果路径是以.结尾的, 则.去掉
  407. if (((sNewPath.length() >= 2) && (sNewPath.substr(sNewPath.length() - 2) == "/.")) || (sNewPath == "."))
  408. {
  409. sNewPath.erase(sNewPath.length() - 1);
  410. }
  411. //处理/../的形式
  412. pos = 0;
  413. size_t startPos = 0;
  414. while (1)
  415. {
  416. size_t slashDot = sNewPath.find("/../", pos);
  417. if (slashDot != string::npos)
  418. {
  419. if (0 == slashDot)
  420. {
  421. sNewPath.erase(0, 3);
  422. continue;
  423. }
  424. if ( (slashDot > 1) && (sNewPath.substr(slashDot - 2, 2) == "..") )
  425. {
  426. pos = slashDot + 4;
  427. continue;
  428. }
  429. startPos = sNewPath.rfind('/', slashDot - 1);
  430. if (startPos == string::npos) startPos = 0;
  431. sNewPath.erase(startPos, slashDot + 4 - startPos - 1);
  432. }
  433. else
  434. {
  435. break;
  436. }
  437. }
  438. //处理/..结尾的情况
  439. if ((sNewPath.size() >= 3) && (sNewPath.substr(sNewPath.size() - 3, 3) == "/.."))
  440. {
  441. size_t slashDot = sNewPath.size() - 3;
  442. if (!((slashDot > 1) && (sNewPath.substr(slashDot - 2, 2) == "..")))
  443. {
  444. startPos = sNewPath.rfind ('/', slashDot - 1);
  445. if (startPos == string::npos) startPos = 0;
  446. sNewPath.erase (startPos + 1);
  447. }
  448. }
  449. return sNewPath;
  450. }
  451. ////////////////////////////////////////////////////////////////////
  452. void TC_Http::setHeader(const string &sHeadName, const string &sHeadValue)
  453. {
  454. //Set-Cookie和Cookie可以有多个头
  455. const char * pStr1 = "SET-COOKIE";
  456. const char * pStr2 = "COOKIE";//原则上COOKIE只有一个,担心有兼容性问题,保留
  457. if ((TC_Port::strcasecmp(sHeadName.c_str(), pStr1) != 0) && (TC_Port::strcasecmp(sHeadName.c_str(), pStr2) != 0))
  458. {
  459. _headers.erase(sHeadName);
  460. }
  461. _headers.insert(multimap<string, string>::value_type(sHeadName, sHeadValue));
  462. }
  463. bool TC_Http::hasHeader(const char *sHeader) const
  464. {
  465. http_header_type::const_iterator it = _headers.find(sHeader);
  466. if (it == _headers.end())
  467. {
  468. return false;
  469. }
  470. return true;
  471. }
  472. bool TC_Http::checkHeader(const char *sHeader, const char *value) const
  473. {
  474. http_header_type::const_iterator it = _headers.find(sHeader);
  475. if (it == _headers.end())
  476. {
  477. return false;
  478. }
  479. return TC_Port::strcasecmp(it->second.c_str(), value) == 0;
  480. }
  481. string TC_Http::getHeader(const string& sHeader) const
  482. {
  483. http_header_type::const_iterator it = _headers.find(sHeader);
  484. if (it == _headers.end())
  485. {
  486. return "";
  487. }
  488. return it->second;
  489. }
  490. string TC_Http::getContentType() const
  491. {
  492. return getHeader("Content-Type");
  493. }
  494. string TC_Http::getHost() const
  495. {
  496. return getHeader("Host");
  497. }
  498. size_t TC_Http::getContentLength() const
  499. {
  500. string s = getHeader("Content-Length");
  501. if (s.empty())
  502. {
  503. return 0;
  504. }
  505. return TC_Common::strto<size_t>(s);
  506. }
  507. string TC_Http::genHeader() const
  508. {
  509. string sHttpHeader;
  510. for (http_header_type::const_iterator it = _headers.begin(); it != _headers.end(); ++it)
  511. {
  512. if (it->second != "")
  513. {
  514. sHttpHeader += it->first;
  515. sHttpHeader += ": ";
  516. sHttpHeader += it->second;
  517. sHttpHeader += "\r\n";
  518. }
  519. }
  520. return sHttpHeader;
  521. }
  522. void TC_Http::genHeader(string &sHttpHeader) const
  523. {
  524. for (http_header_type::const_iterator it = _headers.begin(); it != _headers.end(); ++it)
  525. {
  526. if (it->second != "")
  527. {
  528. sHttpHeader += it->first;
  529. sHttpHeader += ": ";
  530. sHttpHeader += it->second;
  531. sHttpHeader += "\r\n";
  532. }
  533. }
  534. }
  535. vector<string> TC_Http::getHeaderMulti(const string &sHeadName) const
  536. {
  537. vector<string> v;
  538. http_header_type::const_iterator itEnd = _headers.end();
  539. for ( http_header_type::const_iterator it = _headers.begin(); it != itEnd; ++it)
  540. {
  541. if (TC_Port::strcasecmp(it->first.c_str(), sHeadName.c_str()) == 0)
  542. {
  543. v.push_back(it->second);
  544. }
  545. }
  546. return v;
  547. }
  548. void TC_Http::reset()
  549. {
  550. _headers.clear();
  551. _version.clear();
  552. _headLength = 0;
  553. _content.clear();
  554. _bIsChunked = false;
  555. _headComplete = false;
  556. }
  557. void TC_Http::getHeaders(map<string, string> &header) const
  558. {
  559. for(auto it = _headers.begin(); it != _headers.end(); ++it)
  560. {
  561. header.insert(map<string, string>::value_type(it->first, it->second));
  562. }
  563. }
  564. /********************* TC_HttpCookie ***********************/
  565. bool TC_HttpCookie::matchDomain(const string &sCookieDomain, const string &sDomain)
  566. {
  567. string sCookieDomainNew = TC_Common::lower(sCookieDomain);
  568. //没有点的自动加点
  569. if (sCookieDomainNew.find(".") != 0)
  570. {
  571. sCookieDomainNew = "." + sCookieDomainNew;
  572. }
  573. string::size_type pos = sCookieDomainNew.find(".");
  574. //sCookieDomain串至少有两个点
  575. if (pos == string::npos || (pos == 0 && sCookieDomainNew.rfind(".") == 0))
  576. {
  577. return false;
  578. }
  579. string sLowerDomain = TC_Common::lower(sDomain);
  580. //后边是子域名
  581. if (sDomain.length() >= sCookieDomainNew.length() &&
  582. sLowerDomain.compare(sDomain.length() - sCookieDomainNew.length(), sCookieDomainNew.length(), sCookieDomainNew) == 0)
  583. {
  584. return true;
  585. }
  586. //去掉.相等
  587. if (sLowerDomain == sCookieDomainNew.substr(1))
  588. {
  589. return true;
  590. }
  591. return false;
  592. }
  593. size_t TC_HttpCookie::matchPath(const string &sCookiePath, const string &sPath)
  594. {
  595. if (sCookiePath.empty() || sPath.empty()) return 0;
  596. //都在最后加/再匹配
  597. string sCookiePath1 = (sCookiePath.at(sCookiePath.length() - 1) == '/') ? sCookiePath : sCookiePath + "/";
  598. string sPath1 = (sPath.at(sPath.length() - 1) == '/') ? sPath : sPath + "/";
  599. if (sPath1.find(sCookiePath1) == 0)
  600. {
  601. return sCookiePath1.length();
  602. }
  603. return 0;
  604. }
  605. void TC_HttpCookie::clear()
  606. {
  607. _cookies.clear();
  608. }
  609. bool TC_HttpCookie::fixDomain(const string &sDomain, string &sFixDomain)
  610. {
  611. if (sDomain.empty())
  612. {
  613. return false;
  614. }
  615. sFixDomain = sDomain;
  616. //自动加.
  617. if (sDomain.at(0) != '.')
  618. {
  619. sFixDomain = "." + sDomain;
  620. }
  621. //domain至少两段
  622. if (sFixDomain.find(".") == sFixDomain.rfind("."))
  623. return false;
  624. return true;
  625. }
  626. void TC_HttpCookie::addCookie(const Cookie &cookie, list<Cookie> &cookies)
  627. {
  628. string sDomain;
  629. Cookie cookieNew = cookie;
  630. if (!fixDomain(cookieNew._domain, sDomain))
  631. return;
  632. cookieNew._domain = sDomain;
  633. if (cookieNew._path.empty())
  634. return;
  635. list<Cookie>::iterator it = cookies.begin();
  636. string sName;
  637. if (cookieNew._data.size() >= 1)
  638. {
  639. sName = cookieNew._data.begin()->first;
  640. }
  641. while (it != cookies.end())
  642. {
  643. //检查Cookie是否过期
  644. if (isCookieExpires(*it))
  645. {
  646. cookies.erase(it++);
  647. }
  648. else if (TC_Port::strcasecmp(it->_domain.c_str(), cookieNew._domain.c_str()) == 0
  649. && strcmp(it->_path.c_str(), cookieNew._path.c_str()) == 0
  650. && it->_isSecure == cookieNew._isSecure)
  651. {
  652. if (it->_expires == cookieNew._expires)
  653. {
  654. //domain/path/expires都匹配的情况下, 覆盖老cookie的数据
  655. cookieNew._data.insert(it->_data.begin(), it->_data.end());
  656. cookies.erase(it++);
  657. }
  658. else
  659. {
  660. //超时间不一样,但存在同样的key,需删除
  661. if (it->_data.find(sName) != it->_data.end())
  662. {
  663. it->_data.erase(sName);
  664. }
  665. ++it;
  666. }
  667. }
  668. else
  669. {
  670. ++it;
  671. }
  672. }
  673. cookies.push_back(cookieNew);
  674. }
  675. void TC_HttpCookie::addCookie(const Cookie &cookie)
  676. {
  677. addCookie(cookie, _cookies);
  678. }
  679. void TC_HttpCookie::addCookie(const list<Cookie> &cookie)
  680. {
  681. list<Cookie>::const_iterator it = cookie.begin();
  682. while (it != cookie.end())
  683. {
  684. addCookie(*it);
  685. ++it;
  686. }
  687. }
  688. void TC_HttpCookie::addCookie(const string &sRspURL, const vector<string> &vCookies)
  689. {
  690. TC_URL cURL;
  691. cURL.parseURL(sRspURL);
  692. string sRspURLDomain = TC_Common::lower(cURL.getDomain());
  693. string sRspURLPath = cURL.getPath();
  694. for (size_t i = 0; i < vCookies.size(); i++)
  695. {
  696. //处理一行SetCookie
  697. vector<string> v = TC_Common::sepstr<string>(vCookies[i], ";");
  698. Cookie cookie;
  699. cookie._isSecure = false;
  700. cookie._expires = 0;
  701. //解析Cookie数据
  702. for (size_t j = 0; j < v.size(); ++j)
  703. {
  704. string::size_type index = v[j].find("=");
  705. string name;
  706. string value;
  707. if (index != string::npos)
  708. {
  709. name = TC_Common::trim(v[j].substr(0, index), " ");
  710. value = TC_Common::trim(v[j].substr(index + 1));
  711. }
  712. else
  713. {
  714. name = TC_Common::trim(v[j]);
  715. }
  716. if (TC_Port::strcasecmp(name.c_str(), "secure") == 0)
  717. {
  718. cookie._isSecure = true;
  719. }
  720. else if (TC_Port::strcasecmp(name.c_str(), "expires") == 0)
  721. {
  722. struct tm stTm;
  723. //兼容时间格式
  724. //expires=Mon, 09-May-41 08:39:32 GMT
  725. //expires=Thu, 01-Jan-1970 01:00:00 GMT
  726. value = TC_Common::replace(value, "-", " ");
  727. if (value.length() == 27 && value.at(11) == ' ' && value.at(14) == ' ')
  728. {
  729. int year = TC_Common::strto<int> (value.substr(12, 2));
  730. if (year >= 69 && year <= 99)
  731. value = value.substr(0, 12) + "19" + value.substr(12);
  732. else
  733. value = value.substr(0, 12) + "20" + value.substr(12);
  734. }
  735. TC_Common::strgmt2tm(value, stTm);
  736. cookie._expires = TC_Port::timegm(&stTm);
  737. }
  738. else if (TC_Port::strcasecmp(name.c_str(), "path") == 0)
  739. {
  740. cookie._path = value;
  741. }
  742. else if (TC_Port::strcasecmp(name.c_str(), "domain") == 0)
  743. {
  744. cookie._domain = value;
  745. }
  746. else if (TC_Port::strcasecmp(name.c_str(), "httponly") == 0)
  747. {
  748. //TODO
  749. //cookie._isHttpOnly = true;
  750. }
  751. else
  752. cookie._data.insert(http_cookie_data::value_type(name, value));
  753. }
  754. ///修正和匹配domain/////////////////////////////////////////
  755. if (cookie._domain.empty())
  756. cookie._domain = sRspURLDomain;
  757. if (!fixDomain(cookie._domain, cookie._domain))
  758. continue;
  759. //匹配域名
  760. if (!matchDomain(cookie._domain, sRspURLDomain))
  761. continue;
  762. //修改和匹配path/////////////////////////////
  763. if (cookie._path.empty())
  764. {
  765. string sCookiePath;
  766. //缺省是全路径
  767. string sRequest = sRspURLPath;
  768. string::size_type pos = sRequest.rfind("/");
  769. if (pos == string::npos)
  770. sCookiePath = "/";
  771. else
  772. sCookiePath = sRequest.substr(0, pos + 1);
  773. cookie._path = sCookiePath;
  774. }
  775. //URL在Path范围内,Cookie 有效
  776. if (!matchPath(cookie._path, sRspURLPath))
  777. continue;
  778. //添加Cookie
  779. addCookie(cookie);
  780. }
  781. }
  782. bool TC_HttpCookie::isCookieExpires(const Cookie &cookie) const
  783. {
  784. //过期了
  785. if (cookie._expires != 0 && cookie._expires < time(NULL))
  786. return true;
  787. return false;
  788. }
  789. size_t TC_HttpCookie::isCookieMatch(const Cookie &cookie, const TC_URL &tURL) const
  790. {
  791. //域名没有匹配
  792. if (!matchDomain(cookie._domain, tURL.getDomain()))
  793. return 0;
  794. //路径没有匹配
  795. size_t len = matchPath(cookie._path, tURL.getPath());
  796. if (len == 0)
  797. return 0;
  798. //安全的cookie,不安全的URL
  799. if (cookie._isSecure && (tURL.getType() != TC_URL::HTTPS))
  800. return 0;
  801. return len;
  802. }
  803. void TC_HttpCookie::getCookieForURL(const string &sReqURL, list<TC_HttpCookie::Cookie> &cookies)
  804. {
  805. TC_URL tURL;
  806. tURL.parseURL(sReqURL);
  807. cookies.clear();
  808. list<Cookie>::iterator it = _cookies.begin();
  809. while (it != _cookies.end())
  810. {
  811. //检查Cookie是否过期
  812. if (isCookieExpires(*it))
  813. {
  814. _cookies.erase(it++);
  815. continue;
  816. }
  817. size_t len = isCookieMatch(*it, tURL);
  818. if (len == 0)
  819. {
  820. ++it;
  821. continue;
  822. }
  823. cookies.push_back(*it);
  824. ++it;
  825. }
  826. }
  827. void TC_HttpCookie::getCookieForURL(const string &sReqURL, string &sCookie)
  828. {
  829. list<Cookie> cookies;
  830. sCookie.clear();
  831. getCookieForURL(sReqURL, cookies);
  832. list<Cookie>::iterator it = cookies.begin();
  833. while (it != cookies.end())
  834. {
  835. http_cookie_data::iterator itd = it->_data.begin();
  836. while (itd != it->_data.end())
  837. {
  838. //被删除的cookie不输出
  839. if (itd->first != "" && itd->second != "" && TC_Common::lower(itd->second) != "null"
  840. && TC_Common::lower(itd->second) != "deleted")
  841. sCookie += itd->first + "=" + itd->second + "; ";
  842. ++itd;
  843. }
  844. ++it;
  845. }
  846. //去掉末尾的 "; "
  847. if (sCookie.length() >= 2)
  848. sCookie = sCookie.substr(0, sCookie.length() - 2);
  849. }
  850. list<TC_HttpCookie::Cookie> TC_HttpCookie::getSerializeCookie(time_t t)
  851. {
  852. list<Cookie> cookies;
  853. list<Cookie>::iterator it = _cookies.begin();
  854. while (it != _cookies.end())
  855. {
  856. if (isCookieExpires(*it))
  857. {
  858. _cookies.erase(it++);
  859. continue;
  860. }
  861. else if (it->_expires != 0) //非当前会话的
  862. {
  863. cookies.push_back(*it);
  864. ++it;
  865. }
  866. else
  867. ++it;
  868. }
  869. return cookies;
  870. }
  871. const list<TC_HttpCookie::Cookie> & TC_HttpCookie::getAllCookie()
  872. {
  873. deleteExpires(time(NULL));
  874. return _cookies;
  875. }
  876. void TC_HttpCookie::deleteExpires(time_t t, bool bErase)
  877. {
  878. list<Cookie>::iterator it = _cookies.begin();
  879. while (it != _cookies.end())
  880. {
  881. if (bErase && it->_expires == 0)
  882. {
  883. _cookies.erase(it++);
  884. continue;
  885. }
  886. else if (isCookieExpires(*it))
  887. {
  888. _cookies.erase(it++);
  889. continue;
  890. }
  891. else
  892. ++it;
  893. }
  894. }
  895. /********************* TC_HttpResponse ***********************/
  896. void TC_HttpResponse::reset()
  897. {
  898. TC_Http::reset();
  899. _status = 200;
  900. _about = "OK";
  901. _version = "HTTP/1.1";
  902. _iTmpContentLength = 0;
  903. _iRecvContentLength = 0;
  904. }
  905. vector<string> TC_HttpResponse::getSetCookie() const
  906. {
  907. return getHeaderMulti("Set-Cookie");
  908. }
  909. void TC_HttpResponse::addContent(const string &sBuffer)
  910. {
  911. _content += sBuffer;
  912. _iRecvContentLength += sBuffer.length();
  913. }
  914. void TC_HttpResponse::addContent(const char *buffer, size_t length)
  915. {
  916. _content.append(buffer, length);
  917. _iRecvContentLength += length;
  918. }
  919. size_t TC_HttpResponse::parseResponseHeaderString(const char *beginIt, const char *headerIt)
  920. {
  921. auto it = TC_Port::strnstr(beginIt, "\r\n", headerIt - beginIt);
  922. assert(it != NULL);
  923. auto f1 = TC_Port::strnstr(beginIt, " ", it - beginIt);
  924. if(f1 == NULL)
  925. {
  926. throw TC_HttpResponse_Exception("[TC_HttpResponse_Exception::parseResponeHeader] http response parse version format error : " + string(beginIt, headerIt - beginIt));
  927. }
  928. auto f2 = TC_Port::strnstr(f1 + 1, " ", it - (f1 + 1));
  929. if(f1 == NULL)
  930. {
  931. throw TC_HttpResponse_Exception("[TC_HttpResponse_Exception::parseResponeHeader] http response parse status format error : " + string(beginIt, headerIt - beginIt));
  932. }
  933. _headerLine = string(beginIt, it - beginIt);
  934. if(TC_Port::strncasecmp(_headerLine.c_str(), "HTTP/", 5) != 0)
  935. {
  936. throw TC_HttpResponse_Exception("[TC_HttpResponse_Exception::parseResponeHeader] http response version is not start with 'HTTP/' : " + _headerLine);
  937. }
  938. _version = string(beginIt, f1 - beginIt);
  939. _status = TC_Common::strto<int>(string(f1 + 1, f2));
  940. _about = string(f2 + 1, it);
  941. _headComplete = true;
  942. return parseHeaderString(beginIt, headerIt, _headers);
  943. }
  944. bool TC_HttpResponse::incrementDecode(TC_NetWorkBuffer &buff)
  945. {
  946. if(buff.empty())
  947. return false;
  948. buff.mergeBuffers();
  949. size_t length = buff.getBufferLength();
  950. auto sBuf = buff.getBuffer();
  951. bool flag = incrementDecode(*sBuf.get());
  952. buff.subLength(length - sBuf->length());
  953. return flag;
  954. }
  955. bool TC_HttpResponse::incrementDecode(TC_NetWorkBuffer::Buffer &data)
  956. {
  957. if(data.empty())
  958. return false;
  959. //解析头部
  960. if (_headLength == 0)
  961. {
  962. const char * p = TC_Port::strnstr(data.buffer(), "\r\n\r\n", data.length());
  963. if(p == NULL)
  964. {
  965. return false;
  966. }
  967. _headLength = p - data.buffer() + 4;
  968. _iTmpContentLength = parseResponseHeaderString(data.buffer(), data.buffer() + _headLength);
  969. //304的返回码中头里本来就没有Content-Length,也不会有数据体,头收全了就是真正的收全了
  970. if ( (204 == _status) || (304 == _status) )
  971. {
  972. return true;
  973. }
  974. data.addReadIdx(_headLength);
  975. // buff.moveHeader(_headLength);
  976. //重定向就认为成功了
  977. if ((_status == 301 || _status == 302) && hasHeader("Location"))
  978. {
  979. return true;
  980. }
  981. if(_iTmpContentLength > 0)
  982. {
  983. data.expansion(_headLength + _iTmpContentLength);
  984. }
  985. //是否是chunk编码
  986. _bIsChunked = checkHeader("Transfer-Encoding", "chunked");
  987. if(_bIsChunked) {
  988. //删除头部里面
  989. eraseHeader("Transfer-Encoding");
  990. }
  991. }
  992. if (_bIsChunked)
  993. {
  994. while (true)
  995. {
  996. const static string sep = "\r\n";
  997. char* sit = std::search(data.buffer(), data.buffer() + data.length(), sep.c_str(), sep.c_str() + sep.size());
  998. if (sit == data.buffer() + data.length())
  999. {
  1000. return false;
  1001. }
  1002. // string header = buff.iteratorToIterator<string>(buff.begin(), sit);
  1003. int iChunkSize = strtol(data.buffer(), &sit, 16);
  1004. if (iChunkSize <= 0)
  1005. {
  1006. break; //所有chunk都接收完毕
  1007. }
  1008. if (data.length() < sit - data.buffer() + 2 + (size_t)iChunkSize + 2)
  1009. {
  1010. //没有接收完整的chunk
  1011. return false;
  1012. }
  1013. //接收到一个完整的chunk了
  1014. data.addReadIdx(sit - data.buffer() + 2);
  1015. addContent(data.buffer(), iChunkSize);
  1016. // buff.moveHeader(header.size() + 2);
  1017. // addContent(buff.getHeader<string>(iChunkSize));
  1018. //删除一个chunk
  1019. data.addReadIdx(iChunkSize+2);
  1020. // buff.moveHeader(iChunkSize + 2);
  1021. }
  1022. data.clear();
  1023. // buff.clearBuffers();
  1024. //接收到buffer长度设置好
  1025. setContentLength(_iRecvContentLength);
  1026. return true;
  1027. }
  1028. else
  1029. {
  1030. if (_iTmpContentLength == 0)
  1031. {
  1032. //header长度为0, 但是有body数据
  1033. // addContent(buff.getBuffersString());
  1034. addContent(data.buffer(), data.length());
  1035. // buff.clearBuffers();
  1036. data.clear();
  1037. if(_iRecvContentLength > 0) {
  1038. setContentLength(_iRecvContentLength);
  1039. }
  1040. return true;
  1041. }
  1042. else if (_iTmpContentLength == (size_t) - 1)
  1043. {
  1044. //304的返回码中头没有Content-Length,不会有数据体
  1045. if (_status == 304 || _status == 302)
  1046. {
  1047. return true;
  1048. }
  1049. //header中没长度, 但是有body数据
  1050. // addContent(buff.getBuffersString());
  1051. addContent(data.buffer(), data.length());
  1052. // buff.clearBuffers();
  1053. data.clear();
  1054. if(_iRecvContentLength > 0) {
  1055. setContentLength(_iRecvContentLength);
  1056. }
  1057. // http 收包这里收包并没有收完应该return false
  1058. return false;
  1059. }
  1060. else
  1061. {
  1062. //头部有长度, 接收到长度大于头部为止
  1063. // addContent(buff.getBuffersString());
  1064. // buff.clearBuffers();
  1065. addContent(data.buffer(), data.length());
  1066. data.clear();
  1067. //头部的长度小于接收的内容, 还需要继续增加解析后续的buffer
  1068. if (_iTmpContentLength > _iRecvContentLength)
  1069. return false;
  1070. return true;
  1071. }
  1072. }
  1073. return true;
  1074. }
  1075. bool TC_HttpResponse::decode(const string &sBuffer)
  1076. {
  1077. return decode(sBuffer.c_str(), sBuffer.length());
  1078. }
  1079. bool TC_HttpResponse::decode(const char *sBuffer, size_t iLength)
  1080. {
  1081. assert(sBuffer != NULL);
  1082. const char *pHeader = sBuffer;
  1083. const char *p = TC_Port::strnstr(sBuffer, "\r\n\r\n", iLength);
  1084. if ( p == NULL)
  1085. {
  1086. return false;
  1087. }
  1088. //解析头部
  1089. _iTmpContentLength = parseResponseHeaderString(sBuffer, p + 2);
  1090. //304的返回码中头里本来就没有Content-Length,也不会有数据体,头收全了就是真正的收全了
  1091. if ( (204 == _status) || (304 == _status) )
  1092. {
  1093. return true;
  1094. }
  1095. _headLength = p - sBuffer + 4;
  1096. sBuffer += _headLength;
  1097. //重定向就认为成功了
  1098. if ((_status == 301 || _status == 302) && hasHeader("Location"))
  1099. {
  1100. return true;
  1101. }
  1102. //是否是chunk编码
  1103. _bIsChunked = checkHeader("Transfer-Encoding", "chunked");
  1104. if(_bIsChunked) {
  1105. //删除头部里面
  1106. eraseHeader("Transfer-Encoding");
  1107. }
  1108. // _bIsChunked = (getHeader("Transfer-Encoding") == "chunked");
  1109. //删除头部里面
  1110. // eraseHeader("Transfer-Encoding");
  1111. if (_bIsChunked)
  1112. {
  1113. while (true)
  1114. {
  1115. p = TC_Port::strnstr(sBuffer, "\r\n", iLength - (sBuffer - pHeader));
  1116. if (p == NULL)
  1117. return false;
  1118. size_t pos = p - sBuffer;
  1119. //查找当前chunk的大小
  1120. string sChunkSize;
  1121. sChunkSize.insert(sChunkSize.end(), sBuffer, p);
  1122. int iChunkSize = strtol(sChunkSize.c_str(), NULL, 16);
  1123. if (iChunkSize <= 0) break; //所有chunk都接收完毕
  1124. if (strlen(sBuffer) < pos + 2 + (size_t)iChunkSize + 2)
  1125. {
  1126. //没有接收完整的chunk
  1127. return false;
  1128. }
  1129. //接收到一个完整的chunk了
  1130. addContent(p + 2, iChunkSize);
  1131. //删除一个chunk
  1132. sBuffer += pos + 2 + iChunkSize + 2;
  1133. }
  1134. //接收到buffer长度设置好
  1135. setContentLength(_iRecvContentLength);
  1136. return true;
  1137. }
  1138. else
  1139. {
  1140. if (_iTmpContentLength == 0)
  1141. {
  1142. //header长度为0, 但是有body数据
  1143. addContent(sBuffer);
  1144. setContentLength(_iRecvContentLength);
  1145. return true;
  1146. }
  1147. else if (_iTmpContentLength == (size_t) - 1)
  1148. {
  1149. //304的返回码中头没有Content-Length,不会有数据体
  1150. if (_status == 304 || _status == 302)
  1151. {
  1152. return true;
  1153. }
  1154. //header中没长度, 但是有body数据
  1155. addContent(sBuffer);
  1156. setContentLength(_iRecvContentLength);
  1157. }
  1158. else
  1159. {
  1160. //头部有长度, 接收到长度大于头部为止
  1161. addContent(sBuffer);
  1162. //头部的长度小于接收的内容, 还需要继续增加解析后续的buffer
  1163. if (_iTmpContentLength <= _iRecvContentLength)
  1164. return true;
  1165. }
  1166. }
  1167. //body内容长度为0或者没有content-length 且 非chunk模式, 则认为包收全了, 直接返回
  1168. if ((_iTmpContentLength == 0 || _iTmpContentLength == (size_t) - 1) && !_bIsChunked)
  1169. return true;
  1170. return (getContentLength() + getHeadLength() <= iLength);
  1171. }
  1172. string TC_HttpResponse::encode() const
  1173. {
  1174. string sRet;
  1175. sRet.reserve(128);
  1176. sRet += _version;
  1177. sRet += " ";
  1178. sRet += TC_Common::tostr(_status);
  1179. sRet += " ";
  1180. sRet += _about;
  1181. sRet += "\r\n";
  1182. genHeader(sRet);
  1183. sRet += "\r\n";
  1184. sRet += _content;
  1185. return sRet;
  1186. }
  1187. void TC_HttpResponse::encode(vector<char> &buffer) const
  1188. {
  1189. buffer.clear();
  1190. string s = encode();
  1191. buffer.resize(s.length());
  1192. memcpy(buffer.data(), s.c_str(), s.length());
  1193. }
  1194. void TC_HttpResponse::setResponse(int status, const string& about, const string& body)
  1195. {
  1196. _status = status;
  1197. _about = about;
  1198. _content = body;
  1199. /*stringstream os;
  1200. os << _version << " " << _status << " " << _about;
  1201. _headerLine = os.str();*/
  1202. _headerLine = "";
  1203. _headerLine += _version;
  1204. _headerLine += " ";
  1205. _headerLine += TC_Common::tostr(_status);
  1206. _headerLine += " ";
  1207. _headerLine += _about;
  1208. setHeader("Content-Length", TC_Common::tostr(_content.length()));
  1209. }
  1210. void TC_HttpResponse::setResponse(int status, const string& about, const char *sBuffer, size_t iLength)
  1211. {
  1212. _status = status;
  1213. _about = about;
  1214. /*stringstream os;
  1215. os << _version << " " << _status << " " << _about;
  1216. _headerLine = os.str();*/
  1217. _headerLine = "";
  1218. _headerLine += _version;
  1219. _headerLine += " ";
  1220. _headerLine += TC_Common::tostr(_status);
  1221. _headerLine += " ";
  1222. _headerLine += _about;
  1223. if (sBuffer != NULL && iLength > 0)
  1224. {
  1225. _content.assign(sBuffer, iLength);
  1226. }
  1227. else
  1228. {
  1229. _content.clear();
  1230. }
  1231. setHeader("Content-Length", TC_Common::tostr(_content.length()));
  1232. }
  1233. void TC_HttpResponse::setResponse(const char *sBuffer, size_t iLength)
  1234. {
  1235. setResponse(200, "OK", sBuffer, iLength);
  1236. }
  1237. /********************* TC_HttpRequest ***********************/
  1238. void TC_HttpRequest::reset()
  1239. {
  1240. TC_Http::reset();
  1241. _httpURL.clear();
  1242. }
  1243. vector<string> TC_HttpRequest::getCookie()
  1244. {
  1245. vector<string> v;
  1246. http_header_type::const_iterator itEnd = _headers.end();
  1247. for ( http_header_type::const_iterator it = _headers.begin(); it != itEnd; ++it)
  1248. {
  1249. if (it->first == "Cookie")
  1250. {
  1251. v.push_back(it->second);
  1252. }
  1253. }
  1254. return v;
  1255. }
  1256. void TC_HttpRequest::parseURL(const string& sUrl)
  1257. {
  1258. _httpURL.parseURL(sUrl);
  1259. //设置Host
  1260. if (!hasHeader("Host"))
  1261. {
  1262. string sPort = _httpURL.isDefaultPort() ? "" : ":" + _httpURL.getPort();
  1263. //缺省端口可以不用放进去
  1264. setHost(_httpURL.getDomain() + sPort);
  1265. }
  1266. }
  1267. void TC_HttpRequest::setRequest(const string& method, const string &sUrl, const std::string& body, bool bNewCreateHost)
  1268. {
  1269. if (TC_Port::strncasecmp(method.c_str(), "GET", 3) == 0)
  1270. setGetRequest(sUrl, bNewCreateHost);
  1271. else if (TC_Port::strncasecmp(method.c_str(), "HEAD", 4) == 0)
  1272. setHeadRequest(sUrl, bNewCreateHost);
  1273. else if (TC_Port::strncasecmp(method.c_str(), "POST", 4) == 0)
  1274. setPostRequest(sUrl, body, bNewCreateHost);
  1275. else if (TC_Port::strncasecmp(method.c_str(), "PUT", 3) == 0)
  1276. setPutRequest(sUrl, body, bNewCreateHost);
  1277. else if (TC_Port::strncasecmp(method.c_str(), "DELETE", 6) == 0)
  1278. setDeleteRequest(sUrl, body, bNewCreateHost);
  1279. else if (TC_Port::strncasecmp(method.c_str(), "PATH", 5) == 0)
  1280. setPatchRequest(sUrl, body, bNewCreateHost);
  1281. }
  1282. void TC_HttpRequest::setGetRequest(const string &sUrl, bool bNewCreateHost)
  1283. {
  1284. if (bNewCreateHost)
  1285. {
  1286. eraseHeader("Host");
  1287. }
  1288. parseURL(sUrl);
  1289. _requestType = REQUEST_GET;
  1290. _content = "";
  1291. eraseHeader("Content-Length");
  1292. }
  1293. void TC_HttpRequest::setHeadRequest(const string &sUrl, bool bNewCreateHost)
  1294. {
  1295. if (bNewCreateHost)
  1296. {
  1297. eraseHeader("Host");
  1298. }
  1299. parseURL(sUrl);
  1300. _requestType = REQUEST_HEAD;
  1301. _content = "";
  1302. eraseHeader("Content-Length");
  1303. }
  1304. void TC_HttpRequest::setPostRequest(const string &sUrl, const string &sPostBody, bool bNewCreateHost)
  1305. {
  1306. if (bNewCreateHost)
  1307. {
  1308. eraseHeader("Host");
  1309. }
  1310. parseURL(sUrl);
  1311. _requestType = REQUEST_POST;
  1312. _content = sPostBody;
  1313. setHeader("Content-Length", TC_Common::tostr(_content.length()));
  1314. }
  1315. void TC_HttpRequest::setOptionsRequest(const string &sUrl, bool bNewCreateHost)
  1316. {
  1317. if (bNewCreateHost)
  1318. {
  1319. eraseHeader("Host");
  1320. }
  1321. parseURL(sUrl);
  1322. _requestType = REQUEST_OPTIONS;
  1323. _content = "";
  1324. eraseHeader("Content-Length");
  1325. }
  1326. void TC_HttpRequest::setPostRequest(const string &sUrl, const char *sBuffer, size_t iLength, bool bNewCreateHost)
  1327. {
  1328. assert(sBuffer != NULL);
  1329. if (bNewCreateHost)
  1330. {
  1331. eraseHeader("Host");
  1332. }
  1333. parseURL(sUrl);
  1334. _requestType = REQUEST_POST;
  1335. if (iLength > 0)
  1336. {
  1337. _content.assign(sBuffer, iLength);
  1338. }
  1339. else
  1340. {
  1341. _content.clear();
  1342. }
  1343. setHeader("Content-Length", TC_Common::tostr(_content.length()));
  1344. }
  1345. void TC_HttpRequest::setPutRequest(const string &sUrl, const string &sPostBody, bool bNewCreateHost )
  1346. {
  1347. if(bNewCreateHost)
  1348. {
  1349. eraseHeader("Host");
  1350. }
  1351. parseURL(sUrl);
  1352. _requestType = REQUEST_PUT;
  1353. _content = sPostBody;
  1354. setHeader("Content-Length", TC_Common::tostr(_content.length()));
  1355. }
  1356. void TC_HttpRequest::setPatchRequest(const string &sUrl, const string &sPostBody, bool bNewCreateHost )
  1357. {
  1358. if(bNewCreateHost)
  1359. {
  1360. eraseHeader("Host");
  1361. }
  1362. parseURL(sUrl);
  1363. _requestType = REQUEST_PATCH;
  1364. _content = sPostBody;
  1365. setHeader("Content-Length", TC_Common::tostr(_content.length()));
  1366. }
  1367. void TC_HttpRequest::setDeleteRequest(const string &sUrl, const string &sPostBody, bool bNewCreateHost )
  1368. {
  1369. if(bNewCreateHost)
  1370. {
  1371. eraseHeader("Host");
  1372. }
  1373. parseURL(sUrl);
  1374. _requestType = REQUEST_DELETE;
  1375. _content = sPostBody;
  1376. setHeader("Content-Length", TC_Common::tostr(_content.length()));
  1377. }
  1378. string TC_HttpRequest::encode()
  1379. {
  1380. string sRet;
  1381. sRet.reserve(128);
  1382. if(_requestType == REQUEST_GET || _requestType == REQUEST_OPTIONS || _requestType == REQUEST_HEAD)
  1383. {
  1384. sRet += getMethod();//(_requestType);
  1385. sRet += " ";
  1386. sRet += _httpURL.getRequest();
  1387. sRet += " HTTP/1.1\r\n";
  1388. genHeader(sRet);
  1389. sRet += "\r\n";
  1390. }
  1391. else if(_requestType == REQUEST_POST || _requestType == REQUEST_PUT || _requestType == REQUEST_PATCH || _requestType == REQUEST_DELETE)
  1392. {
  1393. setContentLength(_content.length());
  1394. sRet += getMethod();//requestType2str(_requestType);
  1395. sRet += " ";
  1396. sRet += _httpURL.getRequest();
  1397. sRet += " HTTP/1.1\r\n";
  1398. genHeader(sRet);
  1399. sRet += "\r\n";
  1400. sRet += _content;
  1401. }
  1402. return sRet;
  1403. }
  1404. void TC_HttpRequest::encode(vector<char> &sRet)
  1405. {
  1406. string s = encode();
  1407. sRet.resize(s.length());
  1408. memcpy(sRet.data(), s.c_str(), s.length());
  1409. }
  1410. void TC_HttpRequest::encode(TC_NetWorkBuffer &buff)
  1411. {
  1412. buff.addBuffer(std::move(encode()));
  1413. }
  1414. void TC_HttpRequest::encode(shared_ptr<TC_NetWorkBuffer::Buffer>& buff)
  1415. {
  1416. buff->addBuffer(std::move(encode()));
  1417. }
  1418. bool TC_HttpRequest::decode(const string &sBuffer)
  1419. {
  1420. return decode(sBuffer.c_str(), sBuffer.length());
  1421. }
  1422. bool TC_HttpRequest::decode(const vector<char> &sBuffer)
  1423. {
  1424. return decode(sBuffer.data(), sBuffer.size());
  1425. }
  1426. bool TC_HttpRequest::decode(const char *sBuffer, size_t iLength)
  1427. {
  1428. assert(sBuffer != NULL);
  1429. const char *p = TC_Port::strnstr(sBuffer, " ", 10);
  1430. if(p == NULL)
  1431. {
  1432. throw runtime_error("[TC_HttpRequest::decode] http protocol parse error");
  1433. }
  1434. auto it = TC_Http::HEADER.find(string(sBuffer, p - sBuffer));
  1435. if(it == TC_Http::HEADER.end())
  1436. {
  1437. throw runtime_error("[TC_HttpRequest::decode] protocol not support ");
  1438. }
  1439. p = TC_Port::strnstr(sBuffer, "\r\n\r\n", iLength);
  1440. if (p == NULL)
  1441. {
  1442. return false;
  1443. }
  1444. _requestType = it->second;
  1445. parseRequestHeader(sBuffer, p);
  1446. _headLength = p - sBuffer + 4;
  1447. bool bChunk = checkHeader("Transfer-Encoding", "chunked"); //(getHeader("Transfer-Encoding") == "chunked");
  1448. int iChunkSuffixLen = 0;
  1449. if (bChunk)
  1450. {
  1451. p = sBuffer + _headLength;
  1452. while (true)
  1453. {
  1454. const char *pos = TC_Port::strnstr(p, "\r\n", iLength - (p - sBuffer));
  1455. // const char *pos = strstr(p, "\r\n");
  1456. if (pos == NULL)
  1457. return false;
  1458. //查找当前chunk的大小
  1459. string sChunkSize(p, pos - p);
  1460. int iChunkSize = strtol(sChunkSize.c_str(), NULL, 16);
  1461. iChunkSuffixLen = iChunkSuffixLen + sChunkSize.length();
  1462. if (iChunkSize <= 0)
  1463. {
  1464. iChunkSuffixLen = iChunkSuffixLen + 4;
  1465. break; //所有chunk都接收完毕
  1466. }
  1467. if ((sBuffer+iLength-p) >= (pos - p) + 2 + iChunkSize + 2) //接收到一个完整的chunk了
  1468. {
  1469. //获取一个chunk的内容
  1470. _content.append(pos + 2, iChunkSize);
  1471. //删除一个chunk
  1472. p = pos + 2 + iChunkSize + 2;
  1473. iChunkSuffixLen = iChunkSuffixLen + 4;
  1474. }
  1475. else
  1476. {
  1477. //没有接收完整的chunk
  1478. return false;
  1479. }
  1480. setContentLength(getContent().length());
  1481. }
  1482. }
  1483. else
  1484. {
  1485. _content.assign((sBuffer + _headLength), iLength - _headLength);
  1486. }
  1487. return (getContentLength() + getHeadLength() + iChunkSuffixLen == iLength);
  1488. }
  1489. bool TC_HttpRequest::checkRequest(TC_NetWorkBuffer &buff)
  1490. {
  1491. buff.mergeBuffers();
  1492. return checkRequest(buff.getBufferPointer().first, buff.getBufferLength());
  1493. }
  1494. bool TC_HttpRequest::checkRequest(const char* sBuffer, size_t iLen)
  1495. {
  1496. if(iLen < 10)
  1497. return false;
  1498. const char *p = TC_Port::strnstr(sBuffer, " ", 10);
  1499. if(p == NULL)
  1500. {
  1501. throw runtime_error("[TC_HttpRequest::checkRequest] http protocol parse error");
  1502. }
  1503. auto it = TC_Http::HEADER.find(string(sBuffer, p - sBuffer));
  1504. if(it == TC_Http::HEADER.end())
  1505. {
  1506. throw runtime_error("[TC_HttpRequest::checkRequest] protocol not support: " + string(sBuffer, 8));
  1507. }
  1508. const char *header = TC_Port::strnstr(sBuffer, "\r\n\r\n", iLen);
  1509. if ( header == NULL)
  1510. {
  1511. return false;
  1512. }
  1513. size_t pos = header - sBuffer;
  1514. size_t iHeadLen = pos + 4;
  1515. p = TC_Port::strnstr(sBuffer, "\r\n", iHeadLen);
  1516. if(p == NULL)
  1517. {
  1518. //first line
  1519. return false;
  1520. }
  1521. p += 2;
  1522. bool bChunk = false;
  1523. size_t len = 0;
  1524. //找到\r\n\r\n之前的长度表示
  1525. while (true)
  1526. {
  1527. size_t iMoveLen = p - sBuffer;
  1528. if ( iMoveLen >= iHeadLen )
  1529. {
  1530. break;
  1531. }
  1532. const char *line = p;
  1533. const char *lineEnd = strstr(line, "\r\n");
  1534. if (lineEnd != NULL)
  1535. {
  1536. p = lineEnd + 2;
  1537. if (TC_Port::strncasecmp(line, "Transfer-Encoding:", 18) == 0)
  1538. {
  1539. string chunked = TC_Common::trim(string(line + 18, lineEnd));
  1540. bChunk = (chunked == "chunked");
  1541. if (bChunk) break;
  1542. }
  1543. else if (TC_Port::strncasecmp(line, "Content-Length:", 15) != 0)
  1544. {
  1545. continue;
  1546. }
  1547. else
  1548. {
  1549. len = TC_Common::strto<size_t>(TC_Common::trim(string(line + 15, lineEnd), " "));
  1550. }
  1551. }
  1552. }
  1553. if (bChunk)
  1554. {
  1555. int remain_len = iLen - iHeadLen;
  1556. int move_len = 0;
  1557. const char * pCur = header + 4;
  1558. while (true)
  1559. {
  1560. p = TC_Port::strnstr(pCur, "\r\n", remain_len);
  1561. // p = strstr(pCur , "\r\n");
  1562. if ( p == NULL )
  1563. {
  1564. return false;
  1565. }
  1566. //查找当前chunk的大小
  1567. int iChunkSize = strtol(string(pCur, p - pCur).c_str(), NULL, 16);
  1568. if (iChunkSize <= 0)
  1569. {
  1570. return true; //所有chunk都接收完毕
  1571. }
  1572. move_len = (p - pCur) + 2 + iChunkSize + 2;
  1573. if ( remain_len >= move_len ) //接收到一个完整的chunk了
  1574. {
  1575. //移动到下一个chunk
  1576. remain_len -= move_len;
  1577. pCur = p + 2 + iChunkSize + 2;
  1578. }
  1579. else
  1580. {
  1581. return false;
  1582. }
  1583. }
  1584. }
  1585. else if (len + pos + 4 <= iLen)
  1586. {
  1587. return true;
  1588. }
  1589. return false;
  1590. }
  1591. size_t TC_Http::parseHeaderString(const char *beginIt, const char *headerIt, TC_Http::http_header_type &sHeader)
  1592. {
  1593. size_t contentLength = -1;
  1594. sHeader.clear();
  1595. bool first = true;
  1596. auto lineStartIt= beginIt;
  1597. bool isLastLine = false;
  1598. while (true)
  1599. {
  1600. auto it = TC_Port::strnstr(lineStartIt, "\r\n", headerIt - lineStartIt);
  1601. if(it == NULL)
  1602. {
  1603. it = headerIt;
  1604. isLastLine = true;
  1605. }
  1606. //first line ignore
  1607. if(!first)
  1608. {
  1609. auto itF = TC_Port::strnstr(lineStartIt, ":", it - lineStartIt);
  1610. if (itF != NULL)
  1611. {
  1612. while(*lineStartIt == ' ')
  1613. ++lineStartIt;
  1614. const char *s = itF;
  1615. while(*s == ' ')
  1616. --s;
  1617. string name(lineStartIt, s - lineStartIt);
  1618. ++itF;
  1619. while(*itF == ' ')
  1620. ++itF;
  1621. s = it;
  1622. while(*s == ' ')
  1623. --s;
  1624. string value(itF, s-itF);
  1625. if (TC_Port::strncasecmp(name.c_str(), "Content-Length", 14) == 0)
  1626. {
  1627. contentLength = TC_Common::strto<size_t>(value);
  1628. }
  1629. sHeader.insert(multimap<string, string>::value_type(std::move(name), std::move(value)));
  1630. }
  1631. }
  1632. else
  1633. {
  1634. first = false;
  1635. }
  1636. if (isLastLine)
  1637. {
  1638. break;
  1639. }
  1640. lineStartIt = it + 2;//sep.size();
  1641. }
  1642. return contentLength;
  1643. }
  1644. void TC_HttpRequest::parseRequestHeader(const char* szBuffer, const char *header)
  1645. {
  1646. const char *p = strstr(szBuffer, "\r\n");
  1647. assert(p != NULL);
  1648. auto f1 = TC_Port::strnstr(szBuffer, " ", p - szBuffer);
  1649. if (f1 == p)
  1650. {
  1651. throw TC_HttpRequest_Exception("[TC_HttpRequest::parseRequestHeader] http request format error: " + string(szBuffer, p - szBuffer));
  1652. }
  1653. auto f2 = TC_Port::strnstr(f1 + 1, " ", p - f1 + 1);//std::search(f1 + 1, p, sep.c_str(), sep.c_str() + sep.size());
  1654. if (f2 == p || f1 >= f2)
  1655. {
  1656. throw TC_HttpRequest_Exception("[TC_HttpRequest::parseRequestHeader] http request format error: " + string(szBuffer, p - szBuffer));
  1657. }
  1658. //URL地址
  1659. string sURL(f1 + 1, f2 - f1 - 1 );
  1660. //HTTP协议版本
  1661. _version.assign(f2 + 1, p - f2 - 1);
  1662. parseHeaderString(szBuffer, header, _headers);
  1663. _headComplete = true;
  1664. if (TC_Port::strncasecmp(f1 + 1, "https://", 8) != 0 )
  1665. {
  1666. if (TC_Port::strncasecmp(f1 + 1, "http://", 7) != 0 )
  1667. {
  1668. sURL = "http://" + getHost() + sURL;
  1669. }
  1670. }
  1671. parseURL(sURL);
  1672. }
  1673. void TC_HttpRequest::getHostPort(string &sDomain, uint32_t &iPort)
  1674. {
  1675. sDomain = _httpURL.getDomain();
  1676. iPort = TC_Common::strto<uint32_t>(_httpURL.getPort());
  1677. }
  1678. const string &TC_HttpRequest::getMethod() const
  1679. {
  1680. auto it = TC_Http::HEADER_REVERSE.find(_requestType);
  1681. if(it != TC_Http::HEADER_REVERSE.end())
  1682. {
  1683. return it->second;
  1684. }
  1685. else
  1686. {
  1687. throw TC_HttpRequest_Exception("[TC_HttpRequest::setMethod] http request command error: " + TC_Common::tostr(_requestType));
  1688. }
  1689. }
  1690. void TC_HttpRequest::setMethod(const char * sMethod)
  1691. {
  1692. auto it = TC_Http::HEADER.find(sMethod);
  1693. if(it != TC_Http::HEADER.end())
  1694. {
  1695. _requestType = it->second;
  1696. }
  1697. else
  1698. {
  1699. throw TC_HttpRequest_Exception("[TC_HttpRequest::setMethod] http request command error: " + string(sMethod));
  1700. }
  1701. }
  1702. void TC_HttpRequest::setPath(const char *path)
  1703. {
  1704. _httpURL._sPath = path;
  1705. }
  1706. void TC_HttpRequest::setDomain(const char * sDomain)
  1707. {
  1708. _httpURL._sDomain = sDomain;
  1709. }
  1710. void TC_HttpRequest::setScheme(const char * sScheme)
  1711. {
  1712. _httpURL._sScheme = sScheme;
  1713. }
  1714. int TC_HttpRequest::doRequest(TC_TCPClient& tcpClient, TC_HttpResponse& stHttpRsp)
  1715. {
  1716. //只支持短连接模式
  1717. setConnection("close");
  1718. string sSendBuffer = encode();
  1719. int iRet = tcpClient.send(sSendBuffer.c_str(), sSendBuffer.length());
  1720. if (iRet != TC_ClientSocket::EM_SUCCESS)
  1721. {
  1722. return iRet;
  1723. }
  1724. stHttpRsp.reset();
  1725. TC_NetWorkBuffer::Buffer recvBuffer;
  1726. while (true)
  1727. {
  1728. recvBuffer.expansion(recvBuffer.length() + 8*1024);
  1729. size_t iRecvLen = recvBuffer.left();
  1730. iRet = tcpClient.recv(recvBuffer.free(), iRecvLen);
  1731. if (iRet == TC_ClientSocket::EM_SUCCESS)
  1732. {
  1733. recvBuffer.addWriteIdx(iRecvLen);
  1734. }
  1735. switch (iRet)
  1736. {
  1737. case TC_ClientSocket::EM_SUCCESS:
  1738. if (stHttpRsp.incrementDecode(recvBuffer))
  1739. {
  1740. return TC_ClientSocket::EM_SUCCESS;
  1741. }
  1742. continue;
  1743. case TC_ClientSocket::EM_CLOSE:
  1744. stHttpRsp.incrementDecode(recvBuffer);
  1745. return TC_ClientSocket::EM_SUCCESS;
  1746. default:
  1747. return iRet;
  1748. }
  1749. }
  1750. assert(true);
  1751. return 0;
  1752. }
  1753. int TC_HttpRequest::doRequest(TC_HttpResponse &stHttpRsp, int iTimeout)
  1754. {
  1755. //只支持短连接模式
  1756. setConnection("close");
  1757. string sSendBuffer = encode();
  1758. string sHost;
  1759. uint32_t iPort;
  1760. getHostPort(sHost, iPort);
  1761. TC_TCPClient tcpClient;
  1762. tcpClient.init(sHost, iPort, iTimeout);
  1763. int iRet = tcpClient.send(sSendBuffer.c_str(), sSendBuffer.length());
  1764. if (iRet != TC_ClientSocket::EM_SUCCESS)
  1765. {
  1766. return iRet;
  1767. }
  1768. stHttpRsp.reset();
  1769. TC_NetWorkBuffer::Buffer recvBuffer;
  1770. while (true)
  1771. {
  1772. recvBuffer.expansion(recvBuffer.length() + 8*1024);
  1773. size_t iRecvLen = recvBuffer.left();
  1774. iRet = tcpClient.recv(recvBuffer.free(), iRecvLen);
  1775. if (iRet == TC_ClientSocket::EM_SUCCESS)
  1776. {
  1777. recvBuffer.addWriteIdx(iRecvLen);
  1778. }
  1779. switch (iRet)
  1780. {
  1781. case TC_ClientSocket::EM_SUCCESS:
  1782. if (stHttpRsp.incrementDecode(recvBuffer))
  1783. {
  1784. return TC_ClientSocket::EM_SUCCESS;
  1785. }
  1786. continue;
  1787. case TC_ClientSocket::EM_CLOSE:
  1788. stHttpRsp.incrementDecode(recvBuffer);
  1789. return TC_ClientSocket::EM_SUCCESS;
  1790. default:
  1791. return iRet;
  1792. }
  1793. }
  1794. assert(true);
  1795. return 0;
  1796. }
  1797. }