tc_cgi.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895
  1. /**
  2. * Tencent is pleased to support the open source community by making Tars available.
  3. *
  4. * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
  5. *
  6. * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
  7. * in compliance with the License. You may obtain a copy of the License at
  8. *
  9. * https://opensource.org/licenses/BSD-3-Clause
  10. *
  11. * Unless required by applicable law or agreed to in writing, software distributed
  12. * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  13. * CONDITIONS OF ANY KIND, either express or implied. See the License for the
  14. * specific language governing permissions and limitations under the License.
  15. */
  16. #include "util/tc_platform.h"
  17. #include "util/tc_cgi.h"
  18. #include "util/tc_common.h"
  19. #include "util/tc_http.h"
  20. #include <string.h>
  21. #if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
  22. extern char **environ;
  23. #endif
  24. namespace tars
  25. {
  26. ostream &operator<<(ostream &os, const TC_Cgi_Upload &tcCgiUpload)
  27. {
  28. os << tcCgiUpload.tostr();
  29. return os;
  30. }
  31. TC_Cgi_Upload::TC_Cgi_Upload(const TC_Cgi_Upload &tcCgiUpload)
  32. {
  33. _sFileName = tcCgiUpload._sFileName;
  34. _sRealFileName = tcCgiUpload._sRealFileName;
  35. _sServerFileName= tcCgiUpload._sServerFileName;
  36. _iSize = tcCgiUpload._iSize;
  37. _bOverSize = tcCgiUpload._bOverSize;
  38. }
  39. TC_Cgi_Upload & TC_Cgi_Upload::operator=(const TC_Cgi_Upload &tcCgiUpload)
  40. {
  41. if(this != &tcCgiUpload)
  42. {
  43. _sFileName = tcCgiUpload._sFileName;
  44. _sRealFileName = tcCgiUpload._sRealFileName;
  45. _sServerFileName= tcCgiUpload._sServerFileName;
  46. _iSize = tcCgiUpload._iSize;
  47. _bOverSize = tcCgiUpload._bOverSize;
  48. }
  49. return *this;
  50. }
  51. string TC_Cgi_Upload::tostr() const
  52. {
  53. string sBuffer;
  54. sBuffer = "[file控件名称:" + _sFileName + "] ";
  55. sBuffer += " [真实文件名称:" + _sRealFileName + "] ";
  56. sBuffer += " [服务器端文件名称:" + _sServerFileName + "] ";
  57. sBuffer += " [大小(字节):" + TC_Common::tostr(_iSize) + "] ";
  58. sBuffer += " [超过大小限制:" + TC_Common::tostr(_bOverSize) + "] ";
  59. return sBuffer;
  60. }
  61. TC_Cgi::TC_Cgi()
  62. : _is(NULL)
  63. , _iMaxUploadFiles(1)
  64. , _iUploadMaxSize(20971520)
  65. , _bOverUploadFiles(false)
  66. , _iMaxContentLength(20971520)
  67. , _bUploadFileOverSize(false)
  68. {
  69. }
  70. TC_Cgi::~TC_Cgi()
  71. {
  72. }
  73. void TC_Cgi::setUpload(const string &sUploadFilePrefix, int iMaxUploadFiles, size_t iUploadMaxSize, size_t iMaxContentLength)
  74. {
  75. _sUploadFilePrefix = sUploadFilePrefix;
  76. _iMaxUploadFiles = iMaxUploadFiles;
  77. _iUploadMaxSize = iUploadMaxSize;
  78. _iMaxContentLength = iMaxContentLength;
  79. }
  80. void TC_Cgi::parseCgi()
  81. {
  82. #if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
  83. char **env = environ;
  84. while(*env != NULL)
  85. {
  86. string s(*env);
  87. string::size_type pos = s.find('=');
  88. if(pos != string::npos)
  89. {
  90. _env[s.substr(0, pos)] = s.substr(pos + 1);
  91. }
  92. ++env;
  93. }
  94. #else
  95. LPCSTR env;
  96. LPVOID lpvEnv;
  97. // Get a pointer to the environment block.
  98. lpvEnv = GetEnvironmentStrings();
  99. // Variable strings are separated by NULL byte, and the block is
  100. // terminated by a NULL byte.
  101. for (env = (LPCSTR) lpvEnv; *env; env++)
  102. {
  103. string s(env);
  104. string::size_type pos = s.find('=');
  105. if(pos != string::npos)
  106. {
  107. _env[s.substr(0, pos)] = s.substr(pos + 1);
  108. }
  109. // ++env;
  110. }
  111. #endif
  112. _is = &cin;
  113. readCgiInput(_mmpParams, _mpCookies);
  114. }
  115. void TC_Cgi::parseCgi(const TC_HttpRequest &request)
  116. {
  117. setCgiEnv("QUERY_STRING", request.getRequestParam());
  118. setCgiEnv("CONTENT_LENGTH", TC_Common::tostr(request.getContentLength()));
  119. setCgiEnv("HTTP_COOKIE", request.getHeader("Cookie"));
  120. setCgiEnv("CONTENT_TYPE", request.getHeader("Content-Type"));
  121. setCgiEnv("REQUEST_METHOD", request.isGET() ? "GET" : "POST");
  122. _buffer = request.getContent();
  123. _iss.str(_buffer);
  124. _is = &_iss;
  125. readCgiInput(_mmpParams, _mpCookies);
  126. }
  127. void TC_Cgi::getPOST(string &sBuffer)
  128. {
  129. string::size_type iSize = atoi(getCgiEnv(TC_Cgi::ENM_CONTENT_LENGTH).c_str());
  130. if( iSize > _iMaxContentLength)
  131. {
  132. throw TC_Cgi_Exception("[TC_Cgi::getPOST] : CONTENT_LENGTH is too large!");
  133. }
  134. if(iSize <= 0)
  135. {
  136. return;
  137. }
  138. sBuffer = _buffer;
  139. if(sBuffer.length() < iSize)
  140. {
  141. throw TC_Cgi_Exception("[TC_Cgi::getPOST] : Read CONTENT error: content size " + TC_Common::tostr(sBuffer.length()) + "<" + TC_Common::tostr(iSize));
  142. }
  143. }
  144. void TC_Cgi::getGET(string &sBuffer)
  145. {
  146. sBuffer = getCgiEnv(TC_Cgi::ENM_QUERY_STRING);
  147. }
  148. void TC_Cgi::readCgiInput(multimap<string, string> &mmpParams, map<string, string> &mpCooies)
  149. {
  150. string sBuffer = TC_Cgi::getCgiEnv(TC_Cgi::ENM_HTTP_COOKIE);
  151. parseCookies(mpCooies, sBuffer);
  152. if (getCgiEnv(ENM_REQUEST_METHOD).find("POST") != string::npos)
  153. {
  154. //文件上传模式
  155. if (getCgiEnv(ENM_CONTENT_TYPE).find("multipart/form-data") != string::npos)
  156. {
  157. parseUpload(mmpParams);
  158. }
  159. else if (getCgiEnv(ENM_CONTENT_TYPE).find("application/x-www-form-urlencoded") != string::npos)
  160. {
  161. getPOST(sBuffer);
  162. parseNormal(mmpParams, sBuffer);
  163. }
  164. getGET(sBuffer);
  165. }
  166. else if (getCgiEnv(ENM_REQUEST_METHOD).find("GET") != string::npos)
  167. {
  168. getGET(sBuffer);
  169. }
  170. else
  171. {
  172. //default is GET
  173. getGET(sBuffer);
  174. }
  175. if (sBuffer.length() == 0)
  176. {
  177. return ;
  178. }
  179. parseNormal(mmpParams, sBuffer);
  180. }
  181. void TC_Cgi::parseNormal(multimap<string, string> &mmpParams, const string& sBuffer)
  182. {
  183. int iFlag = 0;
  184. string sName;
  185. string sValue;
  186. string sTmp;
  187. string::size_type len = sBuffer.length();
  188. string::size_type pos = 0;
  189. while (pos < len)
  190. {
  191. sTmp = "";
  192. if(iFlag == 0)
  193. {
  194. while ( (sBuffer[pos] != '=') && (pos < len) )
  195. {
  196. sTmp += (sBuffer[pos] == '+') ? ' ' : sBuffer[pos];
  197. ++pos;
  198. }
  199. }
  200. else
  201. {
  202. while ( (sBuffer[pos] != '&') && (pos < len) )
  203. {
  204. sTmp += (sBuffer[pos] == '+') ? ' ' : sBuffer[pos];
  205. ++pos;
  206. }
  207. }
  208. if (iFlag == 0) //param name
  209. {
  210. sName = TC_Cgi::decodeURL(sTmp);
  211. if ( (sBuffer[pos] != '=') || (pos == len - 1) )
  212. {
  213. sValue = "";
  214. mmpParams.insert(multimap<string, string>::value_type(sName, sValue));
  215. }
  216. else
  217. {
  218. iFlag = 1;
  219. }
  220. }
  221. else
  222. {
  223. sValue = TC_Cgi::decodeURL(sTmp);
  224. mmpParams.insert(multimap<string, string>::value_type(sName, sValue));
  225. iFlag = 0;
  226. }
  227. ++pos;
  228. }
  229. }
  230. void TC_Cgi::parseCookies(map<string, string> &mpCookies, const string& sBuffer)
  231. {
  232. string::size_type len = sBuffer.length();
  233. string::size_type pos = 0;
  234. if(len == 0)
  235. {
  236. return;
  237. }
  238. string sName;
  239. string sValue;
  240. int iFlag = 1;
  241. while(pos < len)
  242. {
  243. if(sBuffer[pos] == '=')
  244. {
  245. if( pos == len - 1) //最后一个参数
  246. {
  247. sName = decodeURL(TC_Common::trimleft(sName, " "));
  248. sValue = decodeURL(sValue);
  249. mpCookies[sName] = sValue;
  250. sName = "";
  251. sValue= "";
  252. }
  253. iFlag = 0; //取值
  254. }
  255. else if ( (sBuffer[pos] == ';') || (pos == len - 1) )
  256. {
  257. if(iFlag == 0)
  258. {
  259. if(pos == len - 1)
  260. {
  261. sValue += sBuffer[pos];
  262. }
  263. sName = decodeURL(TC_Common::trimleft(sName, " "));
  264. sValue = decodeURL(sValue);
  265. mpCookies[sName] = sValue;
  266. sName = "";
  267. sValue= "";
  268. iFlag = 1; //取名称
  269. }
  270. }
  271. else if (iFlag)
  272. {
  273. sName += sBuffer[pos];
  274. }
  275. else
  276. {
  277. sValue += sBuffer[pos];
  278. }
  279. ++pos;
  280. }
  281. }
  282. void TC_Cgi::ignoreLine()
  283. {
  284. string sBuffer;
  285. //读取直到有一个空行
  286. while(true)
  287. {
  288. if(!getline(*_is, sBuffer))
  289. {
  290. throw TC_Cgi_Exception("[TC_Cgi::parseFormData] 'multipart/form-data' Format is error");
  291. }
  292. sBuffer = TC_Common::trim(sBuffer, "\r\n");
  293. if(sBuffer.empty())
  294. {
  295. break;
  296. }
  297. }
  298. }
  299. bool TC_Cgi::writeFile(FILE*fp, const string &sFileName, const string &sBuffer, size_t &iTotalWrite)
  300. {
  301. if(!fp)
  302. {
  303. return false;
  304. }
  305. if(_mpUpload[sFileName]._bOverSize
  306. || iTotalWrite > _iUploadMaxSize
  307. || (iTotalWrite + sBuffer.length()) > _iUploadMaxSize)
  308. {
  309. _mpUpload[sFileName]._bOverSize = true;
  310. _bUploadFileOverSize = true;
  311. return false;
  312. }
  313. //内容写入文件
  314. int ret = fwrite(sBuffer.c_str(), 1, sBuffer.length(), fp);
  315. if(ret != (int)sBuffer.length())
  316. {
  317. fclose(fp);
  318. throw TC_Cgi_Exception("[TC_Cgi::parseFormData] upload file '" + _mpUpload[sFileName]._sServerFileName + "' error", TC_Exception::getSystemCode());
  319. }
  320. iTotalWrite += sBuffer.length();
  321. _mpUpload[sFileName]._iSize = iTotalWrite;
  322. return true;
  323. }
  324. void TC_Cgi::parseFormData(multimap<string, string> &mmpParams, const string &sBoundary)
  325. {
  326. string sBuffer;
  327. if(!getline(*_is, sBuffer))
  328. {
  329. throw TC_Cgi_Exception("[TC_Cgi::parseFormData] 'multipart/form-data' Format is error");
  330. }
  331. string sName;
  332. string sValue;
  333. string::size_type pos1 = string("Content-Disposition: form-data; name=\"").length();
  334. string::size_type pos2 = sBuffer.find('"', pos1);
  335. if(pos2 == string::npos)
  336. {
  337. throw TC_Cgi_Exception("[TC_Cgi::parseFormData] 'multipart/form-data' Format is error");
  338. }
  339. //控件名称
  340. sName = sBuffer.substr(pos1, pos2 - pos1);
  341. pos1 = sBuffer.find("filename=\"");
  342. if(pos1 != string::npos)
  343. {
  344. FILE *fp = NULL;
  345. string sTheFile;
  346. //上传文件的form data
  347. pos1 += 10; //filename=
  348. pos2 = sBuffer.find('"', pos1);
  349. if(pos2 == string::npos)
  350. {
  351. throw TC_Cgi_Exception("[TC_Cgi::parseFormData] 'multipart/form-data' Format is error");
  352. }
  353. //获取文件名
  354. sValue = sBuffer.substr(pos1, pos2 - pos1);
  355. if( sValue.length() > 0)
  356. {
  357. if(_iMaxUploadFiles < 0 || _mpUpload.size() < (size_t)_iMaxUploadFiles)
  358. {
  359. mmpParams.insert(multimap<string, string>::value_type(sName, sValue));
  360. //组成文件名称
  361. string sUploadFileName = _sUploadFilePrefix + "_" + TC_Common::tostr(_mpUpload.size());
  362. //记录上传文件路径
  363. _mpUpload[sName]._sFileName = sName;
  364. _mpUpload[sName]._sRealFileName = sValue;
  365. _mpUpload[sName]._sServerFileName = sUploadFileName;
  366. sTheFile = sName;
  367. //打开文件
  368. if ( (fp = fopen(sUploadFileName.c_str(),"w")) == NULL)
  369. {
  370. mmpParams.clear(); //clear , exception safe
  371. THROW_EXCEPTION_SYSCODE(TC_Cgi_Exception, "[TC_Cgi::parseFormData] Upload File '" + sValue + "' to '" + sUploadFileName +"' error");
  372. // throw TC_Cgi_Exception("[TC_Cgi::parseFormData] Upload File '" + sValue + "' to '" + sUploadFileName +"' error! " + string(strerror(errno)));
  373. }
  374. }
  375. else
  376. {
  377. _bOverUploadFiles = true;
  378. }
  379. }
  380. ignoreLine();
  381. string sLastBuffer;
  382. size_t iTotalWrite = 0;
  383. //读取内容到文件
  384. while(getline(*_is, sBuffer))
  385. {
  386. string sTmp = TC_Common::trimright(sBuffer);
  387. if(sTmp.find(sBoundary) != string::npos)
  388. {
  389. if(sLastBuffer.length() < 2)
  390. {
  391. if(fp)
  392. {
  393. fclose(fp);
  394. }
  395. throw TC_Cgi_Exception("[TC_Cgi::parseFormData] 'multipart/form-data' Format is error");
  396. }
  397. sLastBuffer = sLastBuffer.substr(0, sLastBuffer.length() - 2);
  398. writeFile(fp, sTheFile, sLastBuffer, iTotalWrite);
  399. if(fp)
  400. {
  401. fclose(fp);
  402. fp = NULL;
  403. }
  404. //新的一个form data
  405. if(sTmp == sBoundary)
  406. {
  407. parseFormData(mmpParams, sBoundary);
  408. return;
  409. }
  410. else if(sTmp == sBoundary + "--")
  411. {
  412. return;
  413. }
  414. {
  415. throw TC_Cgi_Exception("[TC_Cgi::parseFormData] 'multipart/form-data' Format is error");
  416. }
  417. }
  418. if(!sLastBuffer.empty())
  419. {
  420. writeFile(fp, sTheFile, sLastBuffer, iTotalWrite);
  421. }
  422. sLastBuffer = sBuffer + "\n";
  423. }
  424. if(fp)
  425. {
  426. fclose(fp);
  427. fp = NULL;
  428. }
  429. }
  430. else
  431. {
  432. ignoreLine();
  433. string sLastBuffer;
  434. while(getline(*_is, sBuffer))
  435. {
  436. string sTmp = TC_Common::trimright(sBuffer);
  437. if(sTmp.find(sBoundary) != string::npos)
  438. {
  439. if(sLastBuffer.length() < 2)
  440. {
  441. throw TC_Cgi_Exception("[TC_Cgi::parseFormData] 'multipart/form-data' Format is error");
  442. }
  443. sLastBuffer = sLastBuffer.substr(0, sLastBuffer.length() - 2);
  444. mmpParams.insert(multimap<string, string>::value_type(sName, sLastBuffer));
  445. //新的一个form data
  446. if(sTmp == sBoundary)
  447. {
  448. parseFormData(mmpParams, sBoundary);
  449. return;
  450. }
  451. else if(sTmp == sBoundary + "--")
  452. {
  453. return;
  454. }
  455. throw TC_Cgi_Exception("[TC_Cgi::parseFormData] 'multipart/form-data' Format is error");
  456. }
  457. sLastBuffer += sBuffer + "\n";
  458. }
  459. }
  460. }
  461. void TC_Cgi::parseUpload(multimap<string, string> &mmpParams)
  462. {
  463. string::size_type iSize = atoi(getCgiEnv(TC_Cgi::ENM_CONTENT_LENGTH).c_str());
  464. if( iSize > _iMaxContentLength)
  465. {
  466. throw TC_Cgi_Exception("[TC_Cgi::parseUpload] : CONTENT_LENGTH is too large!");
  467. }
  468. //get content type
  469. string sContentType = getCgiEnv(TC_Cgi::ENM_CONTENT_TYPE);
  470. string::size_type bPos = sContentType.find("boundary=");
  471. if(bPos == string::npos)
  472. {
  473. return;
  474. }
  475. //get boundary, boundary separete params
  476. string sBoundary(sContentType.substr(bPos + 9));
  477. sBoundary = "--" + sBoundary;
  478. string sBuffer;
  479. if(!getline(*_is, sBuffer))
  480. {
  481. throw TC_Cgi_Exception("[TC_Cgi::parseFormData] 'multipart/form-data' Format is error");
  482. }
  483. sBuffer = TC_Common::trim(sBuffer);
  484. if(sBuffer == sBoundary)
  485. {
  486. parseFormData(mmpParams, sBoundary);
  487. }
  488. else
  489. {
  490. throw TC_Cgi_Exception("[TC_Cgi::parseUpload] 'multipart/form-data' Format is error");
  491. }
  492. }
  493. string &TC_Cgi::operator[](const string &sName)
  494. {
  495. multimap<string, string>::iterator it;
  496. if((it = _mmpParams.find(sName)) != _mmpParams.end())
  497. {
  498. return it->second;
  499. }
  500. return _mmpParams.insert(multimap<string, string>::value_type(sName, ""))->second;
  501. }
  502. string TC_Cgi::getValue(const string& sName) const
  503. {
  504. multimap<string, string>::const_iterator it;
  505. if((it = _mmpParams.find(sName)) != _mmpParams.end())
  506. {
  507. return it->second;
  508. }
  509. return "";
  510. }
  511. const vector<string>& TC_Cgi::getMultiValue(const string& sName, vector<string> &vtValue) const
  512. {
  513. vtValue.clear();
  514. multimap<string, string>::const_iterator itEnd = _mmpParams.end();
  515. for( multimap<string, string>::const_iterator it = _mmpParams.begin(); it != itEnd; ++it)
  516. {
  517. if(it->first == sName)
  518. {
  519. vtValue.push_back(it->second);
  520. }
  521. }
  522. return vtValue;
  523. }
  524. const multimap<string, string> &TC_Cgi::getParamMap() const
  525. {
  526. return _mmpParams;
  527. }
  528. map<string, string> TC_Cgi::getParamMapEx() const
  529. {
  530. map<string, string> mpCgiParam;
  531. multimap<string, string>::const_iterator it = _mmpParams.begin();
  532. multimap<string, string>::const_iterator itEnd = _mmpParams.end();
  533. while(it != itEnd)
  534. {
  535. mpCgiParam[it->first] = it->second;
  536. ++it;
  537. }
  538. return mpCgiParam;
  539. }
  540. const map<string, string> &TC_Cgi::getCookiesMap() const
  541. {
  542. return _mpCookies;
  543. }
  544. bool TC_Cgi::isUploadOverSize() const
  545. {
  546. return _bUploadFileOverSize;
  547. }
  548. bool TC_Cgi::isUploadOverSize(vector<TC_Cgi_Upload> &vtUploads) const
  549. {
  550. vtUploads.clear();
  551. map<string, TC_Cgi_Upload>::const_iterator itEnd = _mpUpload.end();
  552. for( map<string, TC_Cgi_Upload>::const_iterator it = _mpUpload.begin(); it != itEnd; ++it)
  553. {
  554. if(it->second._bOverSize)
  555. {
  556. vtUploads.push_back(it->second);
  557. }
  558. }
  559. return vtUploads.size() > 0;
  560. }
  561. const map<string, TC_Cgi_Upload> &TC_Cgi::getUploadFilesMap() const
  562. {
  563. return _mpUpload;
  564. }
  565. size_t TC_Cgi::getUploadFilesCount() const
  566. {
  567. return _mpUpload.size();
  568. }
  569. string TC_Cgi::getCookie(const string &sName) const
  570. {
  571. map<string, string>::const_iterator it = _mpCookies.find(sName);
  572. if(it != _mpCookies.end())
  573. {
  574. return it->second;
  575. }
  576. return "";
  577. }
  578. string TC_Cgi::setCookie(const string &sName, const string &sValue, const string &sExpires, const string &sPath, const string &sDomain, bool bSecure)
  579. {
  580. if(sName.length() == 0)
  581. {
  582. return "";
  583. }
  584. ostringstream os;
  585. os << "Set-Cookie: %s=%s;",sName.c_str(),sValue.c_str();
  586. if (sExpires.length() > 0)
  587. {
  588. os << "EXPIRES=%s;",sExpires.c_str();
  589. }
  590. if (sPath.length() > 0)
  591. {
  592. os << "PATH=%s;", sPath.c_str();
  593. }
  594. if (sDomain.length() > 0)
  595. {
  596. os << "DOMAIN=%s;", sDomain.c_str();
  597. }
  598. if (bSecure)
  599. {
  600. os << "SECURE";
  601. }
  602. os << endl;
  603. _mpCookies[sName] = sValue;
  604. return os.str();
  605. }
  606. bool TC_Cgi::isParamEmpty() const
  607. {
  608. return _mmpParams.empty();
  609. }
  610. bool TC_Cgi::isParamExist(const string& sName) const
  611. {
  612. return _mmpParams.find(sName) != _mmpParams.end();
  613. }
  614. string TC_Cgi::getCgiEnv(int iEnv)
  615. {
  616. switch(iEnv)
  617. {
  618. case ENM_SERVER_SOFTWARE:
  619. return getCgiEnv("SERVER_SOFTWARE");
  620. case ENM_SERVER_NAME:
  621. return getCgiEnv("SERVER_NAME");
  622. case ENM_GATEWAY_INTERFACE:
  623. return getCgiEnv("GATEWAY_INTERFACE");
  624. case ENM_SERVER_PROTOCOL:
  625. return getCgiEnv("SERVER_PROTOCOL");
  626. case ENM_SERVER_PORT:
  627. return getCgiEnv("SERVER_PORT");
  628. case ENM_REQUEST_METHOD:
  629. return getCgiEnv("REQUEST_METHOD");
  630. case ENM_PATH_INFO:
  631. return getCgiEnv("PATH_INFO");
  632. case ENM_PATH_TRANSLATED:
  633. return getCgiEnv("PATH_TRANSLATED");
  634. case ENM_SCRIPT_NAME:
  635. return getCgiEnv("SCRIPT_NAME");
  636. case ENM_HTTP_COOKIE:
  637. return getCgiEnv("HTTP_COOKIE");;
  638. case ENM_QUERY_STRING:
  639. return getCgiEnv("QUERY_STRING");
  640. case ENM_REMOTE_HOST:
  641. return getCgiEnv("REMOTE_HOST");
  642. case ENM_REMOTE_ADDR:
  643. return getCgiEnv("REMOTE_ADDR");
  644. case ENM_AUTH_TYPE:
  645. return getCgiEnv("AUTH_TYPE");
  646. case ENM_REMOTE_USER:
  647. return getCgiEnv("REMOTE_USER");
  648. case ENM_REMOTE_IDENT:
  649. return getCgiEnv("REMOTE_IDENT");
  650. case ENM_CONTENT_TYPE:
  651. return getCgiEnv("CONTENT_TYPE");
  652. case ENM_CONTENT_LENGTH:
  653. return getCgiEnv("CONTENT_LENGTH");
  654. case ENM_HTTP_USER_AGENT:
  655. return getCgiEnv("HTTP_USER_AGENT");
  656. default:
  657. return "";
  658. }
  659. }
  660. string TC_Cgi::getCgiEnv(const string &sEnv)
  661. {
  662. if(_env.find(sEnv) != _env.end())
  663. {
  664. return _env[sEnv];
  665. }
  666. return "";
  667. }
  668. void TC_Cgi::setCgiEnv(const string &sName, const string &sValue)
  669. {
  670. _env[sName] = sValue;
  671. }
  672. string TC_Cgi::htmlHeader(const string &sHeader)
  673. {
  674. return "Content-type: " + sHeader + "\n\n";
  675. }
  676. string TC_Cgi::decodeURL(const string &sUrl)
  677. {
  678. string sDecodeUrl;
  679. register string::size_type pos = 0;
  680. string::size_type len = sUrl.length();
  681. sDecodeUrl = "";
  682. while (pos < len)
  683. {
  684. if(sUrl[pos] == '+')
  685. {
  686. sDecodeUrl += ' ';
  687. ++pos;
  688. }
  689. else if(sUrl[pos] == '%')
  690. {
  691. sDecodeUrl += TC_Common::x2c(sUrl.substr(pos + 1));
  692. pos += 3;
  693. }
  694. else
  695. {
  696. sDecodeUrl += sUrl[pos];
  697. ++pos;
  698. }
  699. }
  700. return sDecodeUrl;
  701. }
  702. string TC_Cgi::encodeURL(const string &sUrl)
  703. {
  704. static char HEX_TABLE[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
  705. string result;
  706. for (size_t i = 0; i < sUrl.length(); i++)
  707. {
  708. char c = sUrl[i];
  709. if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
  710. result.append(1, c);
  711. else
  712. {
  713. result.append(1, '%');
  714. result.append(1, HEX_TABLE[(c >> 4) & 0x0f]);
  715. result.append(1, HEX_TABLE[c & 0x0f]);
  716. }
  717. }
  718. return result;
  719. }
  720. string TC_Cgi::encodeHTML(const string &src, bool blankEncode)
  721. {
  722. if (src == "")
  723. return "";
  724. string result = src;
  725. result = TC_Common::replace(result, "&", "&amp;");
  726. result = TC_Common::replace(result, "<", "&lt;");
  727. result = TC_Common::replace(result, ">", "&gt;");
  728. result = TC_Common::replace(result, "\"", "&quot;");
  729. if (blankEncode)
  730. {
  731. result = TC_Common::replace(result, "\t", " ");
  732. result = TC_Common::replace(result, " ", "&nbsp; ");
  733. result = TC_Common::replace(result, "\r\n", "<br>");
  734. result = TC_Common::replace(result, "\n", "<br>");
  735. }
  736. return result;
  737. }
  738. string TC_Cgi::encodeXML(const string &src)
  739. {
  740. if (src == "")
  741. return "";
  742. string result = src;
  743. result = TC_Common::replace(result, "&", "&amp;");
  744. result = TC_Common::replace(result, "<", "&lt;");
  745. result = TC_Common::replace(result, ">", "&gt;");
  746. result = TC_Common::replace(result, "\"", "&quot;");
  747. result = TC_Common::replace(result, "'", "&apos;");
  748. return result;
  749. }
  750. }