From 772c9629ebbffc2751c9048f0708bd009a8bd3ca Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sat, 22 Aug 2020 19:38:36 +0200 Subject: [PATCH] Unrestricted HTTP API for Client, Server and Main Menu --- builtin/init.lua | 1 - clientmods/mods.conf | 2 +- clientmods/test/init.lua | 3 + doc/client_lua_api.txt | 68 +++++++++++++++++ doc/lua_api.txt | 126 +++++++++++++++----------------- src/script/lua_api/l_http.cpp | 13 +--- src/script/scripting_client.cpp | 2 + 7 files changed, 133 insertions(+), 82 deletions(-) create mode 100644 clientmods/test/init.lua diff --git a/builtin/init.lua b/builtin/init.lua index 75bb3db85..f76174be7 100644 --- a/builtin/init.lua +++ b/builtin/init.lua @@ -36,7 +36,6 @@ dofile(commonpath .. "misc_helpers.lua") if INIT == "game" then dofile(gamepath .. "init.lua") - assert(not core.get_http_api) elseif INIT == "mainmenu" then local mm_script = core.settings:get("main_menu_script") if mm_script and mm_script ~= "" then diff --git a/clientmods/mods.conf b/clientmods/mods.conf index a2a29c06f..3fcd30dfd 100644 --- a/clientmods/mods.conf +++ b/clientmods/mods.conf @@ -4,4 +4,4 @@ load_mod_respawn = true load_mod_inventory = true load_mod_commands = true load_mod_chat = true -load_mod_invertory = false +load_mod_test = true diff --git a/clientmods/test/init.lua b/clientmods/test/init.lua new file mode 100644 index 000000000..3020f9a62 --- /dev/null +++ b/clientmods/test/init.lua @@ -0,0 +1,3 @@ +local HTTPApiTable = minetest.get_http_api() + +print(dump(HTTPApiTable.fetch_sync({url = "https://example.org"}))) diff --git a/doc/client_lua_api.txt b/doc/client_lua_api.txt index e2cebcb10..0b63838b7 100644 --- a/doc/client_lua_api.txt +++ b/doc/client_lua_api.txt @@ -878,6 +878,73 @@ Call these functions only at load time! * `minetest.send_respawn()` * Sends a respawn request to the server. +### HTTP Requests + +* `minetest.get_http_api()` + * returns `HTTPApiTable` containing http functions. + * The returned table contains the functions `fetch_sync`, `fetch_async` and + `fetch_async_get` described below. + * Function only exists if minetest server was built with cURL support. +* `HTTPApiTable.fetch_sync(HTTPRequest req)`: returns HTTPRequestResult + * Performs given request synchronously +* `HTTPApiTable.fetch_async(HTTPRequest req)`: returns handle + * Performs given request asynchronously and returns handle for + `HTTPApiTable.fetch_async_get` +* `HTTPApiTable.fetch_async_get(handle)`: returns HTTPRequestResult + * Return response data for given asynchronous HTTP request + +### `HTTPRequest` definition + +Used by `HTTPApiTable.fetch` and `HTTPApiTable.fetch_async`. + + { + url = "http://example.org", + + timeout = 10, + -- Timeout for connection in seconds. Default is 3 seconds. + + post_data = "Raw POST request data string" OR {field1 = "data1", field2 = "data2"}, + -- Optional, if specified a POST request with post_data is performed. + -- Accepts both a string and a table. If a table is specified, encodes + -- table as x-www-form-urlencoded key-value pairs. + -- If post_data is not specified, a GET request is performed instead. + + user_agent = "ExampleUserAgent", + -- Optional, if specified replaces the default minetest user agent with + -- given string + + extra_headers = { "Accept-Language: en-us", "Accept-Charset: utf-8" }, + -- Optional, if specified adds additional headers to the HTTP request. + -- You must make sure that the header strings follow HTTP specification + -- ("Key: Value"). + + multipart = boolean + -- Optional, if true performs a multipart HTTP request. + -- Default is false. + } + +### `HTTPRequestResult` definition + +Passed to `HTTPApiTable.fetch` callback. Returned by +`HTTPApiTable.fetch_async_get`. + + { + completed = true, + -- If true, the request has finished (either succeeded, failed or timed + -- out) + + succeeded = true, + -- If true, the request was successful + + timeout = false, + -- If true, the request timed out + + code = 200, + -- HTTP status code + + data = "response" + } + ### Storage API * `minetest.get_mod_storage()`: * returns reference to mod private `StorageRef` @@ -1566,3 +1633,4 @@ Same as `image`, but does not accept a `position`; the position is instead deter texture = "image.png", -- ^ Uses texture (string) } + diff --git a/doc/lua_api.txt b/doc/lua_api.txt index e0c895c97..353ccc924 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -5425,28 +5425,72 @@ Schematics HTTP Requests ------------- - -* `minetest.request_http_api()`: - * returns `HTTPApiTable` containing http functions if the calling mod has - been granted access by being listed in the `secure.http_mods` or - `secure.trusted_mods` setting, otherwise returns `nil`. - * The returned table contains the functions `fetch`, `fetch_async` and +* `minetest.get_http_api()` + * returns `HTTPApiTable` containing http functions. + * The returned table contains the functions `fetch_sync`, `fetch_async` and `fetch_async_get` described below. - * Only works at init time and must be called from the mod's main scope - (not from a function). * Function only exists if minetest server was built with cURL support. - * **DO NOT ALLOW ANY OTHER MODS TO ACCESS THE RETURNED TABLE, STORE IT IN - A LOCAL VARIABLE!** -* `HTTPApiTable.fetch(HTTPRequest req, callback)` - * Performs given request asynchronously and calls callback upon completion - * callback: `function(HTTPRequestResult res)` - * Use this HTTP function if you are unsure, the others are for advanced use +* `HTTPApiTable.fetch_sync(HTTPRequest req)`: returns HTTPRequestResult + * Performs given request synchronously * `HTTPApiTable.fetch_async(HTTPRequest req)`: returns handle * Performs given request asynchronously and returns handle for `HTTPApiTable.fetch_async_get` * `HTTPApiTable.fetch_async_get(handle)`: returns HTTPRequestResult * Return response data for given asynchronous HTTP request +### `HTTPRequest` definition + +Used by `HTTPApiTable.fetch` and `HTTPApiTable.fetch_async`. + + { + url = "http://example.org", + + timeout = 10, + -- Timeout for connection in seconds. Default is 3 seconds. + + post_data = "Raw POST request data string" OR {field1 = "data1", field2 = "data2"}, + -- Optional, if specified a POST request with post_data is performed. + -- Accepts both a string and a table. If a table is specified, encodes + -- table as x-www-form-urlencoded key-value pairs. + -- If post_data is not specified, a GET request is performed instead. + + user_agent = "ExampleUserAgent", + -- Optional, if specified replaces the default minetest user agent with + -- given string + + extra_headers = { "Accept-Language: en-us", "Accept-Charset: utf-8" }, + -- Optional, if specified adds additional headers to the HTTP request. + -- You must make sure that the header strings follow HTTP specification + -- ("Key: Value"). + + multipart = boolean + -- Optional, if true performs a multipart HTTP request. + -- Default is false. + } + +### `HTTPRequestResult` definition + +Passed to `HTTPApiTable.fetch` callback. Returned by +`HTTPApiTable.fetch_async_get`. + + { + completed = true, + -- If true, the request has finished (either succeeded, failed or timed + -- out) + + succeeded = true, + -- If true, the request was successful + + timeout = false, + -- If true, the request timed out + + code = 200, + -- HTTP status code + + data = "response" + } + + Storage API ----------- @@ -8057,60 +8101,6 @@ Used by `minetest.add_particlespawner`. -- Otherwise, the default behavior is used. (currently: any random tile) } -`HTTPRequest` definition ------------------------- - -Used by `HTTPApiTable.fetch` and `HTTPApiTable.fetch_async`. - - { - url = "http://example.org", - - timeout = 10, - -- Timeout for connection in seconds. Default is 3 seconds. - - post_data = "Raw POST request data string" OR {field1 = "data1", field2 = "data2"}, - -- Optional, if specified a POST request with post_data is performed. - -- Accepts both a string and a table. If a table is specified, encodes - -- table as x-www-form-urlencoded key-value pairs. - -- If post_data is not specified, a GET request is performed instead. - - user_agent = "ExampleUserAgent", - -- Optional, if specified replaces the default minetest user agent with - -- given string - - extra_headers = { "Accept-Language: en-us", "Accept-Charset: utf-8" }, - -- Optional, if specified adds additional headers to the HTTP request. - -- You must make sure that the header strings follow HTTP specification - -- ("Key: Value"). - - multipart = boolean - -- Optional, if true performs a multipart HTTP request. - -- Default is false. - } - -`HTTPRequestResult` definition ------------------------------- - -Passed to `HTTPApiTable.fetch` callback. Returned by -`HTTPApiTable.fetch_async_get`. - - { - completed = true, - -- If true, the request has finished (either succeeded, failed or timed - -- out) - - succeeded = true, - -- If true, the request was successful - - timeout = false, - -- If true, the request timed out - - code = 200, - -- HTTP status code - - data = "response" - } - Authentication handler definition --------------------------------- diff --git a/src/script/lua_api/l_http.cpp b/src/script/lua_api/l_http.cpp index ec43bf174..84837e71b 100644 --- a/src/script/lua_api/l_http.cpp +++ b/src/script/lua_api/l_http.cpp @@ -216,18 +216,7 @@ int ModApiHttp::l_get_http_api(lua_State *L) void ModApiHttp::Initialize(lua_State *L, int top) { #if USE_CURL - - bool isMainmenu = false; -#ifndef SERVER - isMainmenu = ModApiBase::getGuiEngine(L) != nullptr; -#endif - - if (isMainmenu) { - API_FCT(get_http_api); - } else { - API_FCT(request_http_api); - } - + API_FCT(get_http_api); #endif } diff --git a/src/script/scripting_client.cpp b/src/script/scripting_client.cpp index d71c79f0d..83ec3e777 100644 --- a/src/script/scripting_client.cpp +++ b/src/script/scripting_client.cpp @@ -37,6 +37,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "lua_api/l_localplayer.h" #include "lua_api/l_camera.h" #include "lua_api/l_settings.h" +#include "lua_api/l_http.h" ClientScripting::ClientScripting(Client *client): ScriptApiBase(ScriptingType::Client) @@ -80,6 +81,7 @@ void ClientScripting::InitializeModApi(lua_State *L, int top) ModApiItemMod::Initialize(L, top); ModApiUtil::InitializeClient(L, top); + ModApiHttp::Initialize(L, top); ModApiClient::Initialize(L, top); ModApiStorage::Initialize(L, top); ModApiEnvMod::InitializeClient(L, top);