mirror of
https://github.com/The-Powder-Toy/The-Powder-Toy.git
synced 2025-08-01 06:00:15 +02:00
Return HTTP response headers to Lua
Also accept request headers in a string array format, beside the old string-string dictionary format.
This commit is contained in:
@@ -77,10 +77,10 @@ namespace http
|
||||
#endif
|
||||
}
|
||||
|
||||
void Request::AddHeader(ByteString name, ByteString value)
|
||||
void Request::AddHeader(ByteString header)
|
||||
{
|
||||
#ifndef NOHTTP
|
||||
headers = curl_slist_append(headers, (name + ": " + value).c_str());
|
||||
headers = curl_slist_append(headers, header.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -131,17 +131,32 @@ namespace http
|
||||
{
|
||||
if (session.size())
|
||||
{
|
||||
AddHeader("X-Auth-User-Id", ID);
|
||||
AddHeader("X-Auth-Session-Key", session);
|
||||
AddHeader("X-Auth-User-Id: " + ID);
|
||||
AddHeader("X-Auth-Session-Key: " + session);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddHeader("X-Auth-User", ID);
|
||||
AddHeader("X-Auth-User: " + ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NOHTTP
|
||||
size_t Request::HeaderDataHandler(char *ptr, size_t size, size_t count, void *userdata)
|
||||
{
|
||||
Request *req = (Request *)userdata;
|
||||
auto actual_size = size * count;
|
||||
if (actual_size >= 2 && ptr[actual_size - 2] == '\r' && ptr[actual_size - 1] == '\n')
|
||||
{
|
||||
if (actual_size > 2) // don't include header list terminator (but include the status line)
|
||||
{
|
||||
req->response_headers.push_back(ByteString(ptr, ptr + actual_size - 2));
|
||||
}
|
||||
return actual_size;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t Request::WriteDataHandler(char *ptr, size_t size, size_t count, void *userdata)
|
||||
{
|
||||
Request *req = (Request *)userdata;
|
||||
@@ -231,6 +246,9 @@ namespace http
|
||||
curl_easy_setopt(easy, CURLOPT_PRIVATE, (void *)this);
|
||||
curl_easy_setopt(easy, CURLOPT_USERAGENT, user_agent.c_str());
|
||||
|
||||
curl_easy_setopt(easy, CURLOPT_HEADERDATA, (void *)this);
|
||||
curl_easy_setopt(easy, CURLOPT_HEADERFUNCTION, Request::HeaderDataHandler);
|
||||
|
||||
curl_easy_setopt(easy, CURLOPT_WRITEDATA, (void *)this);
|
||||
curl_easy_setopt(easy, CURLOPT_WRITEFUNCTION, Request::WriteDataHandler);
|
||||
}
|
||||
@@ -245,7 +263,7 @@ namespace http
|
||||
|
||||
|
||||
// finish the request (if called before the request is done, this will block)
|
||||
ByteString Request::Finish(int *status_out)
|
||||
ByteString Request::Finish(int *status_out, std::vector<ByteString> *headers_out)
|
||||
{
|
||||
#ifndef NOHTTP
|
||||
if (CheckCanceled())
|
||||
@@ -263,6 +281,10 @@ namespace http
|
||||
{
|
||||
*status_out = status;
|
||||
}
|
||||
if (headers_out)
|
||||
{
|
||||
*headers_out = std::move(response_headers);
|
||||
}
|
||||
response_out = std::move(response_body);
|
||||
}
|
||||
|
||||
|
@@ -31,6 +31,7 @@ namespace http
|
||||
{
|
||||
#ifndef NOHTTP
|
||||
ByteString uri;
|
||||
std::vector<ByteString> response_headers;
|
||||
ByteString response_body;
|
||||
|
||||
CURL *easy;
|
||||
@@ -58,19 +59,20 @@ namespace http
|
||||
|
||||
std::condition_variable done_cv;
|
||||
|
||||
static size_t WriteDataHandler(char * ptr, size_t size, size_t count, void * userdata);
|
||||
static size_t HeaderDataHandler(char *ptr, size_t size, size_t count, void *userdata);
|
||||
static size_t WriteDataHandler(char *ptr, size_t size, size_t count, void *userdata);
|
||||
#endif
|
||||
|
||||
public:
|
||||
Request(ByteString uri);
|
||||
virtual ~Request();
|
||||
|
||||
void AddHeader(ByteString name, ByteString value);
|
||||
void AddHeader(ByteString header);
|
||||
void AddPostData(std::map<ByteString, ByteString> data);
|
||||
void AuthHeaders(ByteString ID, ByteString session);
|
||||
|
||||
void Start();
|
||||
ByteString Finish(int *status);
|
||||
ByteString Finish(int *status, std::vector<ByteString> *headers = nullptr);
|
||||
void Cancel();
|
||||
|
||||
void CheckProgress(int *total, int *done);
|
||||
|
@@ -4048,13 +4048,13 @@ class RequestHandle
|
||||
bool dead;
|
||||
|
||||
public:
|
||||
RequestHandle(ByteString &uri, bool isPost, std::map<ByteString, ByteString> &post_data, std::map<ByteString, ByteString> &headers)
|
||||
RequestHandle(ByteString &uri, bool isPost, std::map<ByteString, ByteString> &post_data, std::vector<ByteString> &headers)
|
||||
{
|
||||
dead = false;
|
||||
request = new http::Request(uri);
|
||||
for (auto &header : headers)
|
||||
{
|
||||
request->AddHeader(header.first, header.second);
|
||||
request->AddHeader(header);
|
||||
}
|
||||
if (isPost)
|
||||
request->AddPostData(post_data);
|
||||
@@ -4096,14 +4096,14 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
ByteString Finish(int *status_out)
|
||||
ByteString Finish(int &status_out, std::vector<ByteString> &headers)
|
||||
{
|
||||
ByteString data;
|
||||
if (!dead)
|
||||
{
|
||||
if (request->CheckDone())
|
||||
{
|
||||
data = request->Finish(status_out);
|
||||
data = request->Finish(&status_out, &headers);
|
||||
dead = true;
|
||||
}
|
||||
}
|
||||
@@ -4166,10 +4166,17 @@ static int http_request_finish(lua_State *l)
|
||||
if (!rh->Dead())
|
||||
{
|
||||
int status_out;
|
||||
ByteString data = rh->Finish(&status_out);
|
||||
std::vector<ByteString> headers;
|
||||
ByteString data = rh->Finish(status_out, headers);
|
||||
lua_pushlstring(l, data.c_str(), data.size());
|
||||
lua_pushinteger(l, status_out);
|
||||
return 2;
|
||||
lua_newtable(l);
|
||||
for (auto i = 0; i < int(headers.size()); ++i)
|
||||
{
|
||||
lua_pushlstring(l, headers[i].data(), headers[i].size());
|
||||
lua_rawseti(l, -2, i + 1);
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -4192,15 +4199,30 @@ static int http_request(lua_State *l, bool isPost)
|
||||
}
|
||||
}
|
||||
|
||||
std::map<ByteString, ByteString> headers;
|
||||
if (lua_istable(l, isPost ? 3 : 2))
|
||||
std::vector<ByteString> headers;
|
||||
auto headersIndex = isPost ? 3 : 2;
|
||||
if (lua_istable(l, headersIndex))
|
||||
{
|
||||
lua_pushnil(l);
|
||||
while (lua_next(l, isPost ? 3 : 2))
|
||||
auto size = lua_objlen(l, headersIndex);
|
||||
if (size)
|
||||
{
|
||||
lua_pushvalue(l, -2);
|
||||
headers.emplace(lua_tostring(l, -1), lua_tostring(l, -2));
|
||||
lua_pop(l, 2);
|
||||
for (auto i = 0U; i < size; ++i)
|
||||
{
|
||||
lua_rawgeti(l, headersIndex, i + 1);
|
||||
headers.push_back(lua_tostring(l, -1));
|
||||
lua_pop(l, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// old dictionary format
|
||||
lua_pushnil(l);
|
||||
while (lua_next(l, headersIndex))
|
||||
{
|
||||
lua_pushvalue(l, -2);
|
||||
headers.push_back(lua_tostring(l, -1) + ByteString(": ") + lua_tostring(l, -2));
|
||||
lua_pop(l, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
auto *rh = (RequestHandle *)lua_newuserdata(l, sizeof(RequestHandle));
|
||||
|
Reference in New Issue
Block a user