fix(MutliPart): Does not respect quotes in Content-Disposition header (#1031)

* fix(MutliPart): Does not respect quotes in Content-Disposition header

Currently, Drogon MultiPart parser expects quotes for name and filename in the Content-Disposition header.

The builtin HTTP library for .NET Core (System.Net.Http.HttpClient) leaves the quotes in this header, which means that by default, .NET Core applications cannot upload files to drogon.

The related RFC https://datatracker.ietf.org/doc/html/rfc6266 allows for both usages.

This contribution aims to fix this and handle both cases (with or without quotes)
This commit is contained in:
Bertrand Darbon 2021-09-26 02:51:13 +02:00 committed by GitHub
parent 8460249ab3
commit c5effe9c51
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 33 additions and 11 deletions

View File

@ -76,20 +76,28 @@ int MultiPartParser::parse(const HttpRequestPtr &req)
int MultiPartParser::parseEntity(const char *begin, const char *end)
{
static const char entityName[] = "name=\"";
static const char quotationMark[] = "\"";
static const char fileName[] = "filename=\"";
static const char entityName[] = "name=";
static const char semiColon[] = ";";
static const char fileName[] = "filename=";
static const char CRLF[] = "\r\n\r\n";
auto pos = std::search(begin, end, entityName, entityName + 6);
auto pos = std::search(begin, end, entityName, entityName + 5);
if (pos == end)
return -1;
pos += 6;
auto pos1 = std::search(pos, end, quotationMark, quotationMark + 1);
pos += 5;
auto pos1 = std::search(pos, end, semiColon, semiColon + 1);
if (pos1 == end)
return -1;
{
pos1 = std::search(pos, end, CRLF, CRLF + 2);
if (pos1 == end)
return -1;
}
if (*pos == '"')
pos++;
if (*(pos1 - 1) == '"')
pos1--;
std::string name(pos, pos1);
pos = std::search(pos1, end, fileName, fileName + 10);
pos = std::search(pos1, end, fileName, fileName + 9);
if (pos == end)
{
pos1 = std::search(pos1, end, CRLF, CRLF + 4);
@ -100,10 +108,24 @@ int MultiPartParser::parseEntity(const char *begin, const char *end)
}
else
{
pos += 10;
auto pos1 = std::search(pos, end, quotationMark, quotationMark + 1);
pos += 9;
pos1 = std::search(pos, end, semiColon, semiColon + 1);
if (pos1 == end)
return -1;
{
pos1 = std::search(pos, end, CRLF, CRLF + 2);
if (pos1 == end)
return -1;
}
else
{
auto pos2 = std::search(pos, pos1, CRLF, CRLF + 2);
if (pos2 != end)
pos1 = pos2;
}
if (*pos == '"')
pos++;
if (*(pos1 - 1) == '"')
pos1--;
auto filePtr = std::make_shared<HttpFileImpl>();
filePtr->setRequest(requestPtr_);
filePtr->setItemName(name);