1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

Don't restrict multipart requests to POST

This commit is contained in:
sfan5 2025-04-25 15:19:28 +02:00
parent 4164cea58f
commit d937cd9b90
3 changed files with 45 additions and 42 deletions

View file

@ -11849,7 +11849,7 @@ Used by `HTTPApiTable.fetch` and `HTTPApiTable.fetch_async`.
multipart = boolean multipart = boolean
-- Optional, if true performs a multipart HTTP request. -- Optional, if true performs a multipart HTTP request.
-- Default is false. -- Default is false.
-- Post only, data must be array -- Not allowed for GET method and `data` must be a table.
post_data = "Raw POST request data string" OR {field1 = "data1", field2 = "data2"}, post_data = "Raw POST request data string" OR {field1 = "data1", field2 = "data2"},
-- Deprecated, use `data` instead. Forces `method = "POST"`. -- Deprecated, use `data` instead. Forces `method = "POST"`.

View file

@ -275,8 +275,27 @@ HTTPFetchOngoing::HTTPFetchOngoing(const HTTPFetchRequest &request_,
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &result.data); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &result.data);
} }
// Configure the method
switch (request.method) {
default:
assert(false);
case HTTP_GET:
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
break;
case HTTP_POST:
curl_easy_setopt(curl, CURLOPT_POST, 1);
break;
case HTTP_PUT:
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
break;
case HTTP_DELETE:
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
break;
}
// Set data from fields or raw_data // Set data from fields or raw_data
if (request.multipart) { if (request.multipart) {
assert(request.method != HTTP_GET);
multipart_mime = curl_mime_init(curl); multipart_mime = curl_mime_init(curl);
for (auto &it : request.fields) { for (auto &it : request.fields) {
curl_mimepart *part = curl_mime_addpart(multipart_mime); curl_mimepart *part = curl_mime_addpart(multipart_mime);
@ -284,46 +303,31 @@ HTTPFetchOngoing::HTTPFetchOngoing(const HTTPFetchRequest &request_,
curl_mime_data(part, it.second.c_str(), it.second.size()); curl_mime_data(part, it.second.c_str(), it.second.size());
} }
curl_easy_setopt(curl, CURLOPT_MIMEPOST, multipart_mime); curl_easy_setopt(curl, CURLOPT_MIMEPOST, multipart_mime);
} else { } else if (request.method != HTTP_GET) {
switch (request.method) { if (request.fields.empty()) {
case HTTP_GET: // Note that we need to set this to an empty buffer (not NULL)
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1); // even if no data is to be sent.
break; curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE,
case HTTP_POST: request.raw_data.size());
curl_easy_setopt(curl, CURLOPT_POST, 1); curl_easy_setopt(curl, CURLOPT_POSTFIELDS,
break; request.raw_data.c_str());
case HTTP_PUT: } else {
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT"); std::string str;
break; for (auto &field : request.fields) {
case HTTP_DELETE: if (!str.empty())
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE"); str += "&";
break; str += urlencode(field.first);
} str += "=";
if (request.method != HTTP_GET) { str += urlencode(field.second);
if (request.fields.empty()) {
// Note that we need to set this to an empty buffer (not NULL)
// even if no data is to be sent.
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE,
request.raw_data.size());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS,
request.raw_data.c_str());
} else {
std::string str;
for (auto &field : request.fields) {
if (!str.empty())
str += "&";
str += urlencode(field.first);
str += "=";
str += urlencode(field.second);
}
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, str.size());
curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, str.c_str());
} }
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, str.size());
curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, str.c_str());
} }
} }
// Set additional HTTP headers // Set additional HTTP headers
for (const std::string &extra_header : request.extra_headers) { for (const auto &s : request.extra_headers) {
http_header = curl_slist_append(http_header, extra_header.c_str()); http_header = curl_slist_append(http_header, s.c_str());
} }
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, http_header); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, http_header);

View file

@ -55,23 +55,22 @@ struct HTTPFetchRequest
long connect_timeout; long connect_timeout;
// Indicates if this is multipart/form-data or // Indicates if this is multipart/form-data or
// application/x-www-form-urlencoded. POST-only. // application/x-www-form-urlencoded. Not allowed for GET.
bool multipart = false; bool multipart = false;
// The Method to use default = GET // Method to use
// Avaible methods GET, POST, PUT, DELETE
HttpMethod method = HTTP_GET; HttpMethod method = HTTP_GET;
// Fields of the request // Fields of the request
StringMap fields; StringMap fields;
// Raw data of the request (instead of fields) // Raw data of the request (instead of fields, ignored if multipart)
std::string raw_data; std::string raw_data;
// If not empty, should contain entries such as "Accept: text/html" // If not empty, should contain entries such as "Accept: text/html"
std::vector<std::string> extra_headers; std::vector<std::string> extra_headers;
// useragent to use // User agent to send
std::string useragent; std::string useragent;
HTTPFetchRequest(); HTTPFetchRequest();