mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Support HEAD and PATCH methods in http api
This commit is contained in:
parent
d937cd9b90
commit
893a74f9d7
5 changed files with 37 additions and 22 deletions
|
@ -46,6 +46,7 @@ core.features = {
|
||||||
biome_weights = true,
|
biome_weights = true,
|
||||||
particle_blend_clip = true,
|
particle_blend_clip = true,
|
||||||
remove_item_match_meta = true,
|
remove_item_match_meta = true,
|
||||||
|
httpfetch_additional_methods = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
function core.has_feature(arg)
|
function core.has_feature(arg)
|
||||||
|
|
|
@ -5780,6 +5780,8 @@ Utilities
|
||||||
particle_blend_clip = true,
|
particle_blend_clip = true,
|
||||||
-- The `match_meta` optional parameter is available for `InvRef:remove_item()` (5.12.0)
|
-- The `match_meta` optional parameter is available for `InvRef:remove_item()` (5.12.0)
|
||||||
remove_item_match_meta = true,
|
remove_item_match_meta = true,
|
||||||
|
-- The HTTP API supports the HEAD and PATCH methods (5.12.0)
|
||||||
|
httpfetch_additional_methods = true,
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -11824,22 +11826,22 @@ Used by `HTTPApiTable.fetch` and `HTTPApiTable.fetch_async`.
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
{
|
{
|
||||||
url = "http://example.org",
|
url = "https://example.org",
|
||||||
|
|
||||||
timeout = 10,
|
timeout = 10,
|
||||||
-- Timeout for request to be completed in seconds. Default depends on engine settings.
|
-- Timeout for request to be completed in seconds. Default depends on engine settings.
|
||||||
|
|
||||||
method = "GET", "POST", "PUT" or "DELETE"
|
method = "GET", "HEAD", "POST", "PUT", "PATCH" or "DELETE"
|
||||||
-- The http method to use. Defaults to "GET".
|
-- The http method to use. Defaults to "GET".
|
||||||
|
|
||||||
data = "Raw request data string" OR {field1 = "data1", field2 = "data2"},
|
data = "Raw request data string" or {field1 = "data1", field2 = "data2"},
|
||||||
-- Data for the POST, PUT or DELETE request.
|
-- Data for the POST, PUT, PATCH or DELETE request.
|
||||||
-- Accepts both a string and a table. If a table is specified, encodes
|
-- Accepts both a string and a table. If a table is specified, encodes
|
||||||
-- table as x-www-form-urlencoded key-value pairs.
|
-- table as x-www-form-urlencoded key-value pairs.
|
||||||
|
|
||||||
user_agent = "ExampleUserAgent",
|
user_agent = "ExampleUserAgent",
|
||||||
-- Optional, if specified replaces the default Luanti user agent with
|
-- Optional, if specified replaces the default Luanti user agent with
|
||||||
-- given string
|
-- given string.
|
||||||
|
|
||||||
extra_headers = { "Accept-Language: en-us", "Accept-Charset: utf-8" },
|
extra_headers = { "Accept-Language: en-us", "Accept-Charset: utf-8" },
|
||||||
-- Optional, if specified adds additional headers to the HTTP request.
|
-- Optional, if specified adds additional headers to the HTTP request.
|
||||||
|
@ -11849,7 +11851,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.
|
||||||
-- Not allowed for GET method and `data` must be a table.
|
-- Not allowed for GET or HEAD 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"`.
|
||||||
|
@ -11877,7 +11879,8 @@ Passed to `HTTPApiTable.fetch` callback. Returned by
|
||||||
code = 200,
|
code = 200,
|
||||||
-- HTTP status code
|
-- HTTP status code
|
||||||
|
|
||||||
data = "response"
|
data = "",
|
||||||
|
-- Response body
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -282,20 +282,28 @@ HTTPFetchOngoing::HTTPFetchOngoing(const HTTPFetchRequest &request_,
|
||||||
case HTTP_GET:
|
case HTTP_GET:
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
|
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
|
||||||
break;
|
break;
|
||||||
|
case HTTP_HEAD:
|
||||||
|
// This is kinda pointless right now, since we don't return response headers (TODO?)
|
||||||
|
curl_easy_setopt(curl, CURLOPT_NOBODY, 1);
|
||||||
|
break;
|
||||||
case HTTP_POST:
|
case HTTP_POST:
|
||||||
curl_easy_setopt(curl, CURLOPT_POST, 1);
|
curl_easy_setopt(curl, CURLOPT_POST, 1);
|
||||||
break;
|
break;
|
||||||
case HTTP_PUT:
|
case HTTP_PUT:
|
||||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
|
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
|
||||||
break;
|
break;
|
||||||
|
case HTTP_PATCH:
|
||||||
|
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PATCH");
|
||||||
|
break;
|
||||||
case HTTP_DELETE:
|
case HTTP_DELETE:
|
||||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
|
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
const bool has_request_body = request.method != HTTP_GET && request.method != HTTP_HEAD;
|
||||||
|
|
||||||
// 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);
|
assert(has_request_body);
|
||||||
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);
|
||||||
|
@ -303,7 +311,7 @@ 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 if (request.method != HTTP_GET) {
|
} else if (has_request_body) {
|
||||||
if (request.fields.empty()) {
|
if (request.fields.empty()) {
|
||||||
// Note that we need to set this to an empty buffer (not NULL)
|
// Note that we need to set this to an empty buffer (not NULL)
|
||||||
// even if no data is to be sent.
|
// even if no data is to be sent.
|
||||||
|
|
|
@ -31,8 +31,10 @@ namespace {
|
||||||
enum HttpMethod : u8
|
enum HttpMethod : u8
|
||||||
{
|
{
|
||||||
HTTP_GET,
|
HTTP_GET,
|
||||||
|
HTTP_HEAD,
|
||||||
HTTP_POST,
|
HTTP_POST,
|
||||||
HTTP_PUT,
|
HTTP_PUT,
|
||||||
|
HTTP_PATCH,
|
||||||
HTTP_DELETE,
|
HTTP_DELETE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "common/c_content.h"
|
#include "common/c_content.h"
|
||||||
#include "lua_api/l_http.h"
|
#include "lua_api/l_http.h"
|
||||||
#include "cpp_api/s_security.h"
|
#include "cpp_api/s_security.h"
|
||||||
|
#include "util/enum_string.h"
|
||||||
#include "httpfetch.h"
|
#include "httpfetch.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
@ -19,6 +20,16 @@
|
||||||
lua_pushcfunction(L, l_http_##name); \
|
lua_pushcfunction(L, l_http_##name); \
|
||||||
lua_settable(L, -3);
|
lua_settable(L, -3);
|
||||||
|
|
||||||
|
const static EnumString es_HttpMethod[] = {
|
||||||
|
{HTTP_GET, "GET"},
|
||||||
|
{HTTP_HEAD, "HEAD"},
|
||||||
|
{HTTP_POST, "POST"},
|
||||||
|
{HTTP_PUT, "PUT"},
|
||||||
|
{HTTP_PATCH, "PATCH"},
|
||||||
|
{HTTP_DELETE, "DELETE"},
|
||||||
|
{0, nullptr}
|
||||||
|
};
|
||||||
|
|
||||||
#if USE_CURL
|
#if USE_CURL
|
||||||
void ModApiHttp::read_http_fetch_request(lua_State *L, HTTPFetchRequest &req)
|
void ModApiHttp::read_http_fetch_request(lua_State *L, HTTPFetchRequest &req)
|
||||||
{
|
{
|
||||||
|
@ -32,17 +43,8 @@ void ModApiHttp::read_http_fetch_request(lua_State *L, HTTPFetchRequest &req)
|
||||||
req.timeout *= 1000;
|
req.timeout *= 1000;
|
||||||
|
|
||||||
lua_getfield(L, 1, "method");
|
lua_getfield(L, 1, "method");
|
||||||
if (lua_isstring(L, -1)) {
|
if (lua_isstring(L, -1))
|
||||||
std::string mth = getstringfield_default(L, 1, "method", "");
|
string_to_enum(es_HttpMethod, req.method, lua_tostring(L, -1));
|
||||||
if (mth == "GET")
|
|
||||||
req.method = HTTP_GET;
|
|
||||||
else if (mth == "POST")
|
|
||||||
req.method = HTTP_POST;
|
|
||||||
else if (mth == "PUT")
|
|
||||||
req.method = HTTP_PUT;
|
|
||||||
else if (mth == "DELETE")
|
|
||||||
req.method = HTTP_DELETE;
|
|
||||||
}
|
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
||||||
// post_data: if table, post form data, otherwise raw data DEPRECATED use data and method instead
|
// post_data: if table, post form data, otherwise raw data DEPRECATED use data and method instead
|
||||||
|
@ -50,8 +52,7 @@ void ModApiHttp::read_http_fetch_request(lua_State *L, HTTPFetchRequest &req)
|
||||||
if (lua_isnil(L, 2)) {
|
if (lua_isnil(L, 2)) {
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
lua_getfield(L, 1, "data");
|
lua_getfield(L, 1, "data");
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
req.method = HTTP_POST;
|
req.method = HTTP_POST;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue