http_parser.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. /*Software License
  2. Copyright(C) 2024[liuyingjie]
  3. License Terms
  4. Usage Rights
  5. Any individual or entity is free to use, copy, and distribute the binary form of this software without modification to the source code, without the need to disclose the source code.
  6. If the source code is modified, the modifications must be open - sourced under the same license.This means that the modifications must be disclosed and accompanied by a copy of this license.
  7. Future Versions Updates
  8. From this version onwards, all future releases will be governed by the terms of the latest version of the license.This license will automatically be nullified and replaced by the new version.
  9. Users must comply with the terms of the new license issued in future releases.
  10. Liability and Disclaimer
  11. This software is provided “as is”, without any express or implied warranties, including but not limited to the warranties of merchantability, fitness for a particular purpose, and non - infringement.In no event shall the author or copyright holder be liable for any claims, damages, or other liabilities, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software.
  12. Contact Information
  13. If you have any questions, please contact us: 1585346868@qq.com Or visit our website fwlua.com.
  14. */
  15. #include "net/http_parser.h"
  16. #if USE_NET_HTTP_WEBSITE
  17. #include "util/file.h"
  18. #include "util/strutils.h"
  19. network::http::parser::parser()
  20. {
  21. m_method = network::http::ALL;
  22. }
  23. network::http::parser::~parser()
  24. {
  25. }
  26. const ylib::json& ylib::network::http::parser::json()
  27. {
  28. return m_json_param;
  29. }
  30. std::string ylib::network::http::parser::text()
  31. {
  32. return m_data.to_string();
  33. }
  34. bool network::http::parser::init(const std::string &url,const network::http::method& method,const ylib::buffer &data, const std::string &content_type)
  35. {
  36. m_url = url;
  37. m_data = data;
  38. m_content_type = content_type;
  39. m_method = method;
  40. /*解析URL*/
  41. parse_url(m_url,m_url_param);
  42. switch (m_method) {
  43. case network::http::GET:
  44. break;
  45. case network::http::POST:
  46. {
  47. if(content_type.find("application/x-www-form-urlencoded") != -1)
  48. {
  49. parse_url(m_data.to_string(),m_body_param);
  50. }
  51. else if(content_type.find("application/json") != -1)
  52. {
  53. parse_json();
  54. }
  55. else if(content_type.find("multipart/form-data") !=-1)
  56. {
  57. parse_form();
  58. }
  59. }
  60. break;
  61. default:
  62. break;
  63. }
  64. return true;
  65. }
  66. bool network::http::parser::url_param(const std::string &name, std::string &value)
  67. {
  68. return read_url_param(m_url_param,name,value);
  69. }
  70. bool ylib::network::http::parser::url_param_exist(const std::string& name)
  71. {
  72. return m_url_param.find(name) != m_url_param.end();
  73. }
  74. std::vector<std::string> network::http::parser::url_param_names()
  75. {
  76. std::vector<std::string> names;
  77. for_iter(iter,m_url_param)
  78. names.push_back(iter->first);
  79. return names;
  80. }
  81. bool network::http::parser::body_param(const std::string &name, std::string &value)
  82. {
  83. if(m_method == POST)
  84. {
  85. if(m_content_type.find("application/x-www-form-urlencoded") != -1)
  86. {
  87. return read_url_param(m_body_param,name,value);
  88. }
  89. else if(m_content_type.find("application/json") != -1)
  90. {
  91. if(!m_json_param.exist(name))
  92. return false;
  93. if(m_json_param[name].is_number()){
  94. value = std::to_string(m_json_param[name].to<double>());
  95. }else{
  96. value = m_json_param[name].to<std::string>();
  97. }
  98. return true;
  99. }
  100. return false;
  101. }
  102. return false;
  103. }
  104. bool ylib::network::http::parser::body_param_exist(const std::string& name)
  105. {
  106. if (m_method == POST)
  107. {
  108. if (m_content_type.find("application/x-www-form-urlencoded") != -1)
  109. {
  110. return m_body_param.find(name) != m_body_param.end();
  111. }
  112. else if (m_content_type.find("application/json") != -1)
  113. {
  114. return m_json_param.exist(name);
  115. }
  116. }
  117. return false;
  118. }
  119. std::vector<std::string> network::http::parser::body_param_names()
  120. {
  121. std::vector<std::string> names;
  122. if(m_method == POST)
  123. {
  124. if (m_content_type.find("application/x-www-form-urlencoded") != -1)
  125. {
  126. for_iter(iter,m_body_param)
  127. names.push_back(iter->first);
  128. }
  129. else if (m_content_type.find("application/json") != -1)
  130. {
  131. return m_json_param.keys();
  132. }
  133. }
  134. return names;
  135. }
  136. network::http::form_parser *network::http::parser::form()
  137. {
  138. return &m_form;
  139. }
  140. void network::http::parser::parse_url(const std::string &url, std::map<std::string,std::string> &map)
  141. {
  142. map.clear();
  143. auto ps = strutils::split(url,'&');
  144. for(size_t i=0;i<ps.size();i++)
  145. {
  146. auto pi = strutils::split(ps[i],'=');
  147. if(pi.size() == 2)
  148. map.insert(std::pair<std::string,std::string>(pi[0],pi[1]));
  149. }
  150. }
  151. void network::http::parser::parse_json()
  152. {
  153. m_json_param.parse(m_data.to_string());
  154. }
  155. void network::http::parser::parse_form()
  156. {
  157. m_form.parse(&m_data);
  158. }
  159. bool network::http::parser::read_url_param(const std::map<std::string,std::string> &map, const std::string &name, std::string &value)
  160. {
  161. auto iter = map.find(name);
  162. if(iter == map.end())
  163. return false;
  164. value = iter->second;
  165. return true;
  166. }
  167. network::http::form_parser::form_parser()
  168. {
  169. }
  170. network::http::form_parser::~form_parser()
  171. {
  172. }
  173. std::vector<std::string> network::http::form_parser::names()
  174. {
  175. std::vector<std::string> result;
  176. for_iter(iter,m_infos)
  177. result.push_back(iter->first);
  178. return result;
  179. }
  180. bool network::http::form_parser::get(const std::string &name, form_info &info)
  181. {
  182. auto iter = m_infos.find(name);
  183. if(iter == m_infos.end())
  184. return false;
  185. info = iter->second;
  186. return true;
  187. }
  188. bool network::http::form_parser::write_file(const std::string &name, const std::string &filepath)
  189. {
  190. auto iter = m_infos.find(name);
  191. if(iter == m_infos.end())
  192. return false;
  193. return ylib::file::write(filepath,(const char*)m_data->data()+iter->second.start,iter->second.length);
  194. }
  195. bool network::http::form_parser::parse(buffer *data)
  196. {
  197. this->m_data = data;
  198. std::vector<uint32> starts;
  199. std::vector<uint32> lengths;
  200. parse_count(starts,lengths);
  201. for(size_t i=0;i<starts.size();i++)
  202. parse_form(starts[i],lengths[i]);
  203. return true;
  204. }
  205. void network::http::form_parser::parse_count(std::vector<uint32> &starts, std::vector<uint32> &lengths)
  206. {
  207. ylib::buffer cut_flag;
  208. {
  209. int32 curr_idx = 0;
  210. while (char c = getchar(curr_idx++))
  211. {
  212. if (c == '\r' && getchar(curr_idx) == '\n')
  213. {
  214. curr_idx++;
  215. break;
  216. }
  217. else
  218. cut_flag.append<char>(c);
  219. }
  220. }
  221. auto idxVct = m_data->find_list(cut_flag);
  222. for (size_t i = 0; i < idxVct.size(); i++)
  223. {
  224. size_t startIdx = idxVct[i] + cut_flag.length() + 2;
  225. if (i + 1 != idxVct.size())
  226. {
  227. starts.push_back((uint32)startIdx);
  228. lengths.push_back((uint32)(idxVct[i + 1] - idxVct[i] - cut_flag.length() - 2));
  229. }
  230. }
  231. }
  232. void network::http::form_parser::parse_form(uint32 start,uint32 length)
  233. {
  234. auto parse_paraminfo_secondkv=[](const ylib::buffer& buf)->ylib::KeyValue<std::string,std::string>
  235. {
  236. ylib::KeyValue<std::string,std::string> kv;
  237. buffer cutV;
  238. cutV.resize(1);
  239. cutV[0] = '=';
  240. auto cdIdx = buf.find(cutV, 0);
  241. if (cdIdx == -1)
  242. return kv;
  243. kv.name = buf.sub(0, cdIdx).to_string();
  244. kv.value = buf.sub(cdIdx + 2, buf.length() - 3 - cdIdx).to_string();
  245. return kv;
  246. };
  247. ylib::buffer form_data(m_data->data()+start,length);
  248. ylib::buffer fh;
  249. ylib::buffer fh2;
  250. ylib::buffer cs_ln;
  251. fh.resize(2);
  252. fh2.resize(2);
  253. cs_ln.resize(2);
  254. fh[0] = ';';
  255. fh[1] = ' ';
  256. fh2[0] = ':';
  257. fh2[1] = ' ';
  258. cs_ln[0] = '\r';
  259. cs_ln[1] = '\n';
  260. auto div = form_data.find_list(cs_ln);
  261. if (div.size() == -1)
  262. return;
  263. form_info forminfo;
  264. //数据
  265. if (div.size() == 3)
  266. {
  267. forminfo.start = div[1] + 2+start;
  268. forminfo.length = div[div.size() - 1] - 2 - div[1];
  269. }
  270. else if (div.size() > 3)
  271. {
  272. forminfo.start = div[2] + 2+start;
  273. forminfo.length = div[div.size() - 1] - 2 - div[2];
  274. auto ContentType = form_data.sub(div[0] + 2, div[1] - 2 - div[0]);
  275. // Content-Type
  276. auto cdIdx = ContentType.find(fh2);
  277. if (cdIdx == -1)
  278. return;
  279. forminfo.content_type = ContentType.sub(cdIdx + 2, ContentType.length() - 2 - cdIdx);
  280. }
  281. else
  282. return;
  283. //配置项
  284. auto info = form_data.sub(div[0]);
  285. std::string t = info;
  286. auto info_vct = info.find_list(fh);
  287. if (info_vct.size() == 0)
  288. return;
  289. // Content-Disposition
  290. auto contentDisposition = info.sub(info_vct[0]);
  291. auto cdIdx = contentDisposition.find(fh2);
  292. if (cdIdx == -1)
  293. return;
  294. forminfo.disposition = contentDisposition.sub(cdIdx + 2, contentDisposition.length() - 2 - cdIdx);
  295. if (info_vct.size() == 1)
  296. {
  297. auto kv = parse_paraminfo_secondkv(info.sub(info_vct[0] + 2, info.length() - info_vct[0] - 2));
  298. if (kv.name == "name")
  299. forminfo.name = kv.value;
  300. else if (kv.name == "filename")
  301. forminfo.filename = kv.value;
  302. }
  303. else
  304. {
  305. for (size_t i = 0; i < info_vct.size(); i++)
  306. {
  307. ylib::buffer info_sub;
  308. if (info_vct.size() == i + 1)
  309. info_sub = info.sub(info_vct[i] + 2, info.length() - info_vct[i] - 2);
  310. else
  311. info_sub = info.sub(info_vct[i] + 2, info_vct[i + 1] - info_vct[i] - 2);
  312. auto kv = parse_paraminfo_secondkv(info_sub);
  313. if (kv.name == "name")
  314. forminfo.name = kv.value;
  315. else if (kv.name == "filename")
  316. forminfo.filename = kv.value;
  317. }
  318. }
  319. m_infos.insert(std::pair<std::string,form_info>(forminfo.name,forminfo));
  320. }
  321. char network::http::form_parser::getchar(size_t index)
  322. {
  323. if (index + 1 > m_data->length())
  324. throw 0;
  325. return *(m_data->data() + index);
  326. }
  327. #endif