From cb00632e23a41d8d171631de9d85e168b251b80e Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Thu, 6 Jun 2019 19:13:29 +0200 Subject: [PATCH] HTTP API: Allow binary downloads and headers (#8573) Add minetest.features.httpfetch_binary_data --- builtin/game/features.lua | 1 + doc/lua_api.txt | 7 +++++-- src/script/common/c_converter.cpp | 4 ++-- src/script/common/c_converter.h | 2 +- src/script/common/helper.cpp | 5 +++-- src/script/lua_api/l_http.cpp | 13 +++++-------- 6 files changed, 17 insertions(+), 15 deletions(-) diff --git a/builtin/game/features.lua b/builtin/game/features.lua index 8e5104867..cf21303c7 100644 --- a/builtin/game/features.lua +++ b/builtin/game/features.lua @@ -12,6 +12,7 @@ core.features = { no_chat_message_prediction = true, object_use_texture_alpha = true, object_independent_selectionbox = true, + httpfetch_binary_data = true, } function core.has_feature(arg) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index f29b7d439..352b04cb0 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -3527,11 +3527,14 @@ Utilities -- Chat messages are no longer predicted (0.4.16) no_chat_message_prediction = true, -- The transparency channel of textures can optionally be used on - -- objects (ie: players and lua entities) (5.0) + -- objects (ie: players and lua entities) (5.0.0) object_use_texture_alpha = true, -- Object selectionbox is settable independently from collisionbox - -- (5.0) + -- (5.0.0) object_independent_selectionbox = true, + -- Specifies whether binary data can be uploaded or downloaded using + -- the HTTP API (5.1.0) + httpfetch_binary_data = true, } * `minetest.has_feature(arg)`: returns `boolean, missing_features` diff --git a/src/script/common/c_converter.cpp b/src/script/common/c_converter.cpp index dfd3f5cea..b9d6f0494 100644 --- a/src/script/common/c_converter.cpp +++ b/src/script/common/c_converter.cpp @@ -540,9 +540,9 @@ v3s16 getv3s16field_default(lua_State *L, int table, } void setstringfield(lua_State *L, int table, - const char *fieldname, const char *value) + const char *fieldname, const std::string &value) { - lua_pushstring(L, value); + lua_pushlstring(L, value.c_str(), value.length()); if(table < 0) table -= 1; lua_setfield(L, table, fieldname); diff --git a/src/script/common/c_converter.h b/src/script/common/c_converter.h index 87bc35ac6..f84494c8d 100644 --- a/src/script/common/c_converter.h +++ b/src/script/common/c_converter.h @@ -91,7 +91,7 @@ std::string checkstringfield(lua_State *L, int table, const char *fieldname); void setstringfield(lua_State *L, int table, - const char *fieldname, const char *value); + const char *fieldname, const std::string &value); void setintfield(lua_State *L, int table, const char *fieldname, int value); void setfloatfield(lua_State *L, int table, diff --git a/src/script/common/helper.cpp b/src/script/common/helper.cpp index 59bde57ab..f53a2b7e8 100644 --- a/src/script/common/helper.cpp +++ b/src/script/common/helper.cpp @@ -107,9 +107,10 @@ template <> v2f LuaHelper::readParam(lua_State *L, int index) template <> std::string LuaHelper::readParam(lua_State *L, int index) { + size_t length; std::string result; - const char *str = luaL_checkstring(L, index); - result.append(str); + const char *str = luaL_checklstring(L, index, &length); + result.assign(str, length); return result; } diff --git a/src/script/lua_api/l_http.cpp b/src/script/lua_api/l_http.cpp index f27f789ad..2ff651cb5 100644 --- a/src/script/lua_api/l_http.cpp +++ b/src/script/lua_api/l_http.cpp @@ -53,9 +53,8 @@ void ModApiHttp::read_http_fetch_request(lua_State *L, HTTPFetchRequest &req) lua_getfield(L, 1, "post_data"); if (lua_istable(L, 2)) { lua_pushnil(L); - while (lua_next(L, 2) != 0) - { - req.post_fields[luaL_checkstring(L, -2)] = luaL_checkstring(L, -1); + while (lua_next(L, 2) != 0) { + req.post_fields[readParam(L, -2)] = readParam(L, -1); lua_pop(L, 1); } } else if (lua_isstring(L, 2)) { @@ -66,10 +65,8 @@ void ModApiHttp::read_http_fetch_request(lua_State *L, HTTPFetchRequest &req) lua_getfield(L, 1, "extra_headers"); if (lua_istable(L, 2)) { lua_pushnil(L); - while (lua_next(L, 2) != 0) - { - const char *header = luaL_checkstring(L, -1); - req.extra_headers.emplace_back(header); + while (lua_next(L, 2) != 0) { + req.extra_headers.emplace_back(readParam(L, -1)); lua_pop(L, 1); } } @@ -83,7 +80,7 @@ void ModApiHttp::push_http_fetch_result(lua_State *L, HTTPFetchResult &res, bool setboolfield(L, -1, "timeout", res.timeout); setboolfield(L, -1, "completed", completed); setintfield(L, -1, "code", res.response_code); - setstringfield(L, -1, "data", res.data.c_str()); + setstringfield(L, -1, "data", res.data); } // http_api.fetch_async(HTTPRequest definition)