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

/ 1,617评论 / 9019阅读 / 10点赞

预备知识

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. Jamesjer说道:

    average price of doxycycline: where can you buy doxycycline online – cost of doxycycline online canada

  2. Лучшие автомобили из Кореи | Секреты выбора авто из Кореи | Корейские авто: плюсы и минусы | Пятерка лучших корейских автомобилей | Преимущества авто из Кореи | Популярные модели корейских авто | Корейские автомобили с выгодным расходом топлива | Ценовая политика корейских автомобилей | Подбор авто из Кореи по вашим требованиям | Лучшие внедорожники из Кореи | Выбор современного кроссовера Кореи | Корейские авто для долгих поездок: комфорт и безопасность | Что нужно знать о корейских электромобилях | Секреты осмотра авто из Кореи | Тюнинг авто из Кореи: особенности и возможности
    авто из кореи купить авто из кореи купить .

  3. Michaelphime说道:

    AC Milan https://italy.milan-ar.com is one of the most successful and decorated football clubs in the world.

  4. Charlesimify说道:

    Ремонт плоской кровли https://remontiruem-krovly.ru в Москве, цена работы за 1 м?. Прайс лист на работы под ключ, отзывы и фото.

  5. StevenSof说道:

    Thai Company Directory https://thaicorporates.com List of companies and business information.

  6. ThomasInace说道:

    http://amoxildelivery.pro/# over the counter amoxicillin

  7. TimothySkymn说道:

    Real Madrid’s https://spain.real-madrid-ar.com history goes back more than a century. The club was founded in 1902 by a group of football enthusiasts led by Juan Padilla

  8. RandallWhirm说道:

    Arsenal https://england.arsenal-ar.com is one of the most famous and successful football clubs in the history of English football.

  9. MichaelLix说道:

    FC Bayern Munich (Munich) https://germany.bayern-munchen-ar.com is one of the most famous and recognized football clubs in Germany and Europe

  10. ThomasInace说道:

    http://doxycyclinedelivery.pro/# buy doxycycline online

  11. Jamesjer说道:

    paxlovid pill: paxlovid india – paxlovid generic

  12. Provadent说道:

    I really enjoy looking through on this web site, it contains good posts. “Beware lest in your anxiety to avoid war you obtain a master.” by Demosthenes.

  13. ThomasInace说道:

    https://doxycyclinedelivery.pro/# no prescription doxycycline

  14. Prodentim Review说道:

    I enjoy the efforts you have put in this, thankyou for all the great content.

发表回复

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