diff --git a/doc/lua_api.md b/doc/lua_api.md index ebc5826c2..f9b166bf6 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -11849,7 +11849,7 @@ Used by `HTTPApiTable.fetch` and `HTTPApiTable.fetch_async`. multipart = boolean -- Optional, if true performs a multipart HTTP request. -- 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"}, -- Deprecated, use `data` instead. Forces `method = "POST"`. diff --git a/src/httpfetch.cpp b/src/httpfetch.cpp index 18c0bc131..2f452ff57 100644 --- a/src/httpfetch.cpp +++ b/src/httpfetch.cpp @@ -275,8 +275,27 @@ HTTPFetchOngoing::HTTPFetchOngoing(const HTTPFetchRequest &request_, 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 if (request.multipart) { + assert(request.method != HTTP_GET); multipart_mime = curl_mime_init(curl); for (auto &it : request.fields) { 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_easy_setopt(curl, CURLOPT_MIMEPOST, multipart_mime); - } else { - switch (request.method) { - 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; - } - if (request.method != HTTP_GET) { - 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()); + } else if (request.method != HTTP_GET) { + 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()); } } + // Set additional HTTP headers - for (const std::string &extra_header : request.extra_headers) { - http_header = curl_slist_append(http_header, extra_header.c_str()); + for (const auto &s : request.extra_headers) { + http_header = curl_slist_append(http_header, s.c_str()); } curl_easy_setopt(curl, CURLOPT_HTTPHEADER, http_header); diff --git a/src/httpfetch.h b/src/httpfetch.h index f0c622775..286647e3f 100644 --- a/src/httpfetch.h +++ b/src/httpfetch.h @@ -55,23 +55,22 @@ struct HTTPFetchRequest long connect_timeout; // 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; - // The Method to use default = GET - // Avaible methods GET, POST, PUT, DELETE + // Method to use HttpMethod method = HTTP_GET; // Fields of the request 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; // If not empty, should contain entries such as "Accept: text/html" std::vector extra_headers; - // useragent to use + // User agent to send std::string useragent; HTTPFetchRequest();