[HTTP/C++]请求体form-data解析

/ 4,106评论 / 17462阅读 / 11点赞

预备知识

URL编解码

请求体编码格式


form-data格式

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="myfile"; filename="hello.gif" filename*=UTF-8''hello.gif
Content-Type: image/gif


{二进制数据}
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="mytext"

coolight
------WebKitFormBoundary7MA4YWxkTrZu0gW--
--{boundary}(\r\n)
Content-Disposition: form-data; name="{key}"(\r\n)
(\r\n)
{value}(\r\n)
--{boundary}
--{boundary}(\r\n)
Content-Disposition: form-data; name="{key}"; filename="{filename}"(\r\n)[; filename*={编码方式}''{对应编码的filename}]
Content-Type: {文件格式}(\r\n)
(\r\n)
(\r\n)
{二进制数据}(\r\n)
--{boundary}

c++解析

这里使用正则表达式标准库匹配,并使用string_view减小开销。

#include <regex>
#include <string_view>
#include <map>

using std::string;
using std::multimap;
using std::string_view;

namespace mimicry {
	struct Http_form_data_s {
		bool isFile = false;	//是否为文件,否的话fileName和fileType是无效的
		//注意:fileName可能会包含./ ../等路径信息,此时可能会有一些危险的操作,建议截取最后一个/之后的文件名或自行命名
		std::string fileName;
		std::string fileName_CharEncoding;
		//有时可能文件名会乱码,因此请求中会有指定编码的文件名,对应字段 fileName*
		std::string fileName_;
		std::string fileType;
		std::string value;
	};

std::multimap<std::string, mimicry::Http_form_data_s>
read_form_data(const std::string& in_bound, const std::string& in_data) {
	std::multimap<std::string, mimicry::Http_form_data_s> remap;
	string_view view{ in_data };
	std::regex reg_name{"\\r\\nContent-Disposition:\\s*form-data;\\s*name=\"(.*)\"(?:\\s*;\\s*filename=\"(.*)\"(?:\\s*;\\s*filename\\*=(.*)''(.*))?\\r\\nContent-Type:\\s*(.*))?\\r\\n\\r\\n"};
	string find_bound = "--" + in_bound;
	mimicry::Http_form_data_s data;
	size_t pos = 0, pos_2 = 0;
	if ((pos = view.find(find_bound)) != string::npos) {
		pos += find_bound.size();
		for (;(pos_2 = view.find(find_bound, pos)) != string::npos;) {
			string_view block = view.substr(pos, pos_2 - pos);	//截取两个bound之间的内容
			std::match_results<string_view::const_iterator> block_match_view;
			if (std::regex_search(block.begin(), block.end(), block_match_view, reg_name)) {	//匹配 name 和可能存在的 filename
				data.fileName = block_match_view.str(2);
				data.fileName_CharEncoding = block_match_view.str(3);
				data.fileName_ = block_match_view.str(4);
				data.fileType = block_match_view.str(5);
				data.isFile = data.fileName.size() > 0;
				const char* str_p = &(* (block_match_view[0].second));
				size_t len = block.end() - 2 - block_match_view[0].second;
				//const string_view var_view = string_view{ block_match_view[0].second, block.end() - 2 };
				data.value = string(str_p, len);
				remap.insert({ block_match_view.str(1), data });
			}
			pos = pos_2 + find_bound.size();
		}
	}
	return remap;
}
};

其他

boundary的来历

form-data和Birnary的选择

  1. Тут можно преобрести сейф для пистолета и ружья сейфы для оружия

  2. LarryBow说道:

    ultrabet bonus ultrabet giris ultrabet giris

  3. ClydeTal说道:

    slot tr online: slot oyunlar? puf noktalar? – slot oyunlar? puf noktalar?

  4. CarrollWip说道:

    deneme bonusu veren siteler yerliarama.org http://ultrabet-tr.online/# ultrabet tr online

  5. Dereknef说道:

    matadorbet.bid: matadorbet giris – matadorbet

  6. LarryBow说道:

    deneme bonusu veren siteler mycbet.com deneme bonusu veren siteler yerliarama.org denemebonusuverensiteler.top

  7. Dereknef说道:

    matadorbet bid: matadorbet bid – matadorbet giris

  8. ClydeTal说道:

    slot oyunlar? puf noktalar?: slot tr online – slot oyunlar? puf noktalar?

  9. RobertSmemi说道:

    сколько стоит прокат лыж красная поляна прокат горнолыжных лыж Адлер

  10. CarrollWip说道:

    deneme bonusu veren siteler yeni http://casinositeleri.win/# Casino Siteleri

  11. Dereknef说道:

    slot oyunlar?: az parayla cok kazandiran slot oyunlar? – az parayla cok kazandiran slot oyunlar?

  12. LarryBow说道:

    Canl? Casino Siteleri Deneme Bonusu Veren Siteler casino siteleri win

  13. ClydeTal说道:

    slot tr online: slot oyunlar? puf noktalar? – slot siteleri

  14. Тут можно преобрести оружейный сейф на заказ москва купить оружейный шкаф

  15. Dereknef说道:

    deneme bonusu veren siteler yeni: deneme bonusu veren yeni siteler – deneme bonusu veren siteler betturkey betturkey.com

  16. Тут можно преобрести купить оружейный шкаф пистолетные сейфы москва

  17. CarrollWip说道:

    deneme bonusu veren siteler 2024 https://slot-tr.online/# az parayla cok kazandiran slot oyunlar?

  18. LarryBow说道:

    deneme bonusu veren siteler deneme bonusu veren siteler mycbet.com deneme bonusu veren siteler denemebonusu2026.com

  19. ClydeTal说道:

    casino siteleri win: guvenilir casino siteleri – Deneme Bonusu Veren Siteler

  20. Dereknef说道:

    deneme bonusu veren siteler denemebonusu2026.com: deneme bonusu veren siteler 2024 – deneme bonusu veren siteler mycbet.com

  21. LarryBow说道:

    deneme bonusu veren siteler denemebonusu2026.com deneme bonusu veren siteler yerliarama.org denemebonusuverensiteler.top

  22. Тут можно преобрести сейф для пистолета и ружья пистолетные сейфы москва

  23. Dereknef说道:

    az parayla cok kazandiran slot oyunlar?: slot oyunlar? puf noktalar? – en kazancl? slot oyunlar?

  24. luckyjetraketa说道:

    Получите дополнительные средства на игру с промокод лаки джет и играйте уверенно.

  25. CarrollWip说道:

    deneme bonusu veren siteler https://matadorbet.bid/# matadorbet

  26. ClydeTal说道:

    Canl? Casino Siteleri: guvenilir casino siteleri – casino siteleri win

  27. Тут можно преобрести сейф охотничий сейф для ружья цена

  28. LarryBow说道:

    ultrabet bonus ultrabet guncel ultrabet giris

  29. Dereknef说道:

    az parayla cok kazandiran slot oyunlar?: slot tr online – slot oyunlar? puf noktalar?

  30. CarrollWip说道:

    deneme bonusu veren siteler mycbet.com https://denemebonusuverensiteler.top/# deneme bonusu veren siteler yerliarama.org

  31. Dereknef说道:

    deneme bonusu veren siteler yeni: deneme bonusu veren siteler mycbet.com – denemebonusuverensiteler.top

  32. HassanMesty说道:

    http://slot-tr.online/# slot siteleri
    deneme bonusu veren siteler yerliarama.org

  33. ClydeTal说道:

    en kazancl? slot oyunlar?: en kazancl? slot oyunlar? – az parayla cok kazandiran slot oyunlar?

  34. LarryBow说道:

    slot oyunlar? slot siteleri en kazancl? slot oyunlar?

  35. HassanMesty说道:

    https://slot-tr.online/# en cok kazand?ran slot oyunlar?
    deneme bonusu veren siteler

  36. Тут можно преобрести сейф огнестойкий сейфы от пожара

  37. LarryBow说道:

    matadorbet giris matadorbet bid matadorbet giris

  38. Тут можно преобрести сейфы оружейные купить купить оружейный сейф

  39. Dereknef说道:

    slot tr online: en kazancl? slot oyunlar? – slot oyunlar? puf noktalar?

  40. ClydeTal说道:

    Casino Siteleri: casino siteleri win – Deneme Bonusu Veren Siteler

  41. Тут можно преобрести купить сейф оружейный оружейный сейф в москве

  42. Dereknef说道:

    ultrabet bonus: ultrabet tr online – ultrabet tr online

  43. LarryBow说道:

    Casino Siteleri Canl? Casino Siteleri casino siteleri win

  44. Тут можно преобрести оружейный шкаф купить москва цена сейфа для оружия

  45. ClydeTal说道:

    Canl? Casino Siteleri: Canl? Casino Siteleri – Canl? Casino Siteleri

  46. CarrollWip说道:

    deneme bonusu veren siteler betturkey http://slot-tr.online/# slot tr online

  47. LarryBow说道:

    Casino Siteleri Casino Siteleri Casino Siteleri

  48. Dereknef说道:

    guvenilir casino siteleri: guvenilir casino siteleri – Casino Siteleri

  49. Dereknef说道:

    guvenilir casino siteleri: casino siteleri win – Casino Siteleri

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注