目录
预备知识
URL编解码
- 常用于url链接和application/x-www-form-urlencoded格式的请求体中对参数进行编码
- 由于url的参数的样子是key1=value1&key2=value2,如果key或者value中包含= &等字符,就会导致解析时混乱了,因此需要一种编码来把这些可能引起歧义的符号替换掉
- 例如:http://localhost/src/components/global/Checkbox.vue?type=style&index=0
- 这个链接中 ? 的后面就是参数部分,即 type=style&index=0
- 这是两个键值对,type值为style,index值为0
- 假如现在 type 的值为 a=b,那么参数部分最后组装成 type=a=b&index=0 ,可见已经有点歧义了,但由于&分割,兴许还能解析
- 如果再假设type的值为 a&c=d,那组装后是 type=a&c=d&index=0,显然这个字符串给程序去解析的话,天王老子来了也会被解析为三个部分:type值为a,c值为d,index值为0
请求体编码格式
- Http协议中,请求体有多种格式,如:
- application/x-www-form-urlencoded,相当常用的格式,即和url中的参数一样,是key=value格式的字符串,且这个字符串是经过url编码的,在解析之前需要进行url解码。
- multipart/form-data,可以上传多个键值对/文件。具体格式下文将着重展开。
- application/json,顾名思义,就是json格式的
- application/xml,xml格式,即像HTML一般的标签
- text/plain,文本
- application/octet-stream,二进制数据,且仅能上传一个文件。如果传单个文件(图片、音视频)使用这个相当快乐,它并不需要解析,整个请求体就是文件,但需要使用其他方式上传文件的文件名等信息。
- 如果有请求体,则应该在请求头使用 Content-Type 说明使用的编码格式
form-data格式
- 如果请求体是form-data格式,则在请求头中,我们应该能找到 Content-Type 的值为 multipart/form-data 且它后面会带一个 boundary:
- Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
- 这里boundary是解析请求体用的
- 我们先来看看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--
- 这个请求体示例中有两个部分:
- 文件名为hello.gif的动态图
- 一个键值对,键为mytext,值为coolight
- 刚刚在请求头的 Content-Type 中的boundary的值在请求体中是用来分割数据的,在boundary前加两个-,即:--{boundary},并用它独占一行作为分隔标志。
- 注意最后一行分割标志的后面还有两个-,即 --{boundary}--
- 我们先看示例的第二部分,即键值对 mytext=coolight
- 其格式如下,其中把换行(\r\n)标出:
- 注意换行 \r\n 也是格式的一部分
--{boundary}(\r\n)
Content-Disposition: form-data; name="{key}"(\r\n)
(\r\n)
{value}(\r\n)
--{boundary}
- 然后是第一部分,上传文件时的格式:
- 其中与键值对格式不同的是,在name后面多了个filename,再后面还有一个可选的filename*。这是因为如果filename里面包含中文等非ASCII字符时,因客户端和服务端的编码不同而导致解析时filename乱码,因此可能会多传一个filename*,指定使用的编码格式,如UTF-8,且注意它的值是编码方式后紧接着两个单引号',然后直接是对应编码的filename,整个字符串两端没有双引号。
- 注意 行Content-Type 之后还有两行才是数据。
--{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的来历
- boundary是浏览器(或者说是客户端)随机生成的,可能你会想它会不会和我要传输的字符串刚好重复而导致解析出问题呢?其实还是有可能的,但概率相当小。
- 由于想找出和数据不重复的字串的成本很高,如果数据才几KB那当然可以写程序循环随机生成,然后匹配查找是否重复。但如果上传的文件几百MB甚至上GB呢,此时字符串匹配的速度足以让用户炸毛,因此浏览器一般都是尽力随机生成,但不保证一定不会和数据重复。
form-data和Birnary的选择
- 上传文件的话显然是能选Birnary就不用form-data,因为form-data需要解析。
- 如果只上传一个文件,就选Birnay,并使用url参数之类的各种手段带上文件名等信息。
cost clomid without rx: clomidonpharm – generic clomid without dr prescription
can i buy amoxicillin over the counter Amox Star amoxil generic
price of prednisone tablets: PredniBest – 25 mg prednisone
https://rxguides.net Discover the best game codes, in-depth guides, and updated tier lists for your favorite games! Unlock exclusive rewards, master gameplay strategies, and find the top characters or items to dominate the competition. Start your journey to success today!
https://prednibest.com/# prednisone 20mg
buy amoxil: amoxicillin without rx – generic amoxicillin cost
Torlab.net https://torlab.net новый торрент-трекер для поиска и обмена файлами! Здесь вы найдете фильмы, игры, музыку, софт и многое другое. Быстрая скорость загрузки, удобный интерфейс и активное сообщество. Подключайтесь, делитесь, скачивайте — ваш доступ к миру качественного контента!
Доставка дизельного топлива https://neftegazlogistic.ru в Москве – оперативно и качественно! Поставляем ДТ для автотранспорта, строительной и спецтехники. Гарантия чистоты топлива, выгодные цены и быстрая доставка прямо на объект.
http://clomidonpharm.com/# where buy clomid without insurance
where can i get clomid without rx buying cheap clomid online how can i get clomid without rx
prednisone 5084 PredniBest prednisone 20mg prescription cost
1 юань в тенге рубли в тенге .
Сайт предлагает удобный обменный калькулятор для конвертации тенге в рубли, юани или доллары США. Обновляемые курсы и мгновенные результаты делают процесс максимально простым.
order generic clomid without rx: where can i get generic clomid pills – cost generic clomid without dr prescription
https://cipharmdelivery.com/# cipro pharmacy
over the counter amoxicillin: 875 mg amoxicillin cost – order amoxicillin online
prednisone 2 mg daily: prednisone pills for sale – cost of prednisone 40 mg
buy cipro online usa: buy cipro online – ciprofloxacin mail online
Геосинтетические материалы https://geobentomat.ru надежное решение для строительства и укрепления грунтов. Геотекстиль, георешетки, геомембраны и другие материалы для дренажа, армирования и защиты конструкций.
Инженерные изыскания в Москве https://geology-kaluga.ru точные исследования для строительства и проектирования. Геологические, гидрологические, экологические и геодезические работы для строительства.
prednisone 20mg buy online prednisone medicine prednisone 10mg
Производство шпона в Москве https://shpon-massiv.ru качественный шпон из натурального дерева для мебели, дверей и отделки. Широкий выбор пород, гибкие размеры и выгодные цены.
Предлагаем стекла для спецтехники https://steklo-ufa.ru любых типов и размеров. Прочные, устойчивые к ударам и погодным условиям материалы.
amoxicillin discount coupon Amox Star over the counter amoxicillin canada
http://amoxstar.com/# amoxicillin buy canada
http://prednibest.com/# order prednisone 10mg
Ontdek promoties van CorgiSlot https://www.mijnstudentenleven.nl/news/corgislot-casino-review.html
http://cipharmdelivery.com/# buy cipro cheap
10 mg prednisone: prednisone 50 mg canada – prednisone cream rx
buy cipro ciprofloxacin order online buy cipro
ciprofloxacin order online: CiPharmDelivery – buy cipro
prednisone canada pharmacy PredniBest prednisone 12 mg
https://cipharmdelivery.com/# cipro online no prescription in the usa
wien sexkontakte sex in vienna
Оценка профессиональных рисков https://ocenka-riskov-msk.ru комплексная услуга для выявления, анализа и снижения угроз на рабочем месте.
Наши бюстгальтер набор предлагают идеальное сочетание стиля и комфорта. Выберите бюстгальтер без косточек для мягкой поддержки или кружевной бюстгальтер для романтичного образа. Для будущих мам подойдут бюстгальтеры для беременных и бюстгальтеры для кормления. Обратите внимание на бюстгальтер с пуш-ап для эффекта увеличения груди и комфортные бюстгальтеры для повседневного ношения.
Летайте выгодно с Pegasus Airlines предлагаем доступные билеты, удобные маршруты и современный сервис. Внутренние и международные рейсы для комфортных путешествий.
https://clomidonpharm.com/# order generic clomid pill
тинькофф платинум условия тинькофф платинум проценты
VIP сувениры https://podarki-suveniry-vip.ru
Mikrosluchatko – kompaktni mikro-sluchatka https://mikrosluchatko-cena.cz pro skrytou komunikaci. Nenapadnost, spolehlivost a pohodli v kazdem zarizeni. Idealni pro zkousky, jednani a dulezite ukoly.
Оценка профессиональных рисков https://ocenka-riskov-msk.ru комплексная услуга для выявления, анализа и снижения угроз на рабочем месте.
buy cipro without rx CiPharmDelivery buy cipro
amoxicillin 500 coupon Amox Star can i buy amoxicillin over the counter
Техосмотр категория C новый техосмотр
https://prednibest.com/# over the counter prednisone pills
Предлагаем услуги профессиональных инженеров офицальной мастерской.
Еслли вы искали ремонт телефонов sony цены, можете посмотреть на сайте: ремонт телефонов sony сервис
Наши мастера оперативно устранят неисправности вашего устройства в сервисе или с выездом на дом!
Предлагаем услуги профессиональных инженеров офицальной мастерской.
Еслли вы искали ремонт телефонов sony в москве, можете посмотреть на сайте: срочный ремонт телефонов sony
Наши мастера оперативно устранят неисправности вашего устройства в сервисе или с выездом на дом!
buy cipro without rx: buy cipro online without prescription – buy ciprofloxacin
amoxicillin 500mg: Amox Star – amoxicillin 500 mg tablet price
Предлагаем услуги профессиональных инженеров офицальной мастерской.
Еслли вы искали ремонт телефонов realme адреса, можете посмотреть на сайте: ремонт телефонов realme адреса
Наши мастера оперативно устранят неисправности вашего устройства в сервисе или с выездом на дом!