Skip to content

Commit

Permalink
Update lua-https to latest commit (love2d/lua-https@6dbce69)
Browse files Browse the repository at this point in the history
  • Loading branch information
slime73 committed Aug 31, 2023
1 parent b0e3246 commit ddf88c6
Show file tree
Hide file tree
Showing 11 changed files with 405 additions and 53 deletions.
11 changes: 10 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1619,6 +1619,8 @@ set(LOVE_SRC_3P_LUAHTTPS_LUA
set(LOVE_SRC_3P_LUAHTTPS_WINDOWS
src/libraries/luahttps/src/windows/SChannelConnection.cpp
src/libraries/luahttps/src/windows/SChannelConnection.h
src/libraries/luahttps/src/windows/WinINetClient.cpp
src/libraries/luahttps/src/windows/WinINetClient.h
)

# These are platform-dependent but have ifdef guards to make sure they only
Expand All @@ -1638,10 +1640,17 @@ endif()
set(LOVE_LINK_L3P_LUAHTTPS)
if(MSVC)
set(LOVE_LINK_L3P_LUAHTTPS
${LOVE_LINK_L3P_LUASOCKET_LIBLUASOCKET}
${LOVE_LINK_L3P_LUAHTTPS}
ws2_32
secur32
)

if(NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
set(LOVE_LINK_L3P_LUAHTTPS
${LOVE_LINK_L3P_LUAHTTPS}
wininet
)
endif()
endif()

add_library(love_3p_luahttps ${LOVE_SRC_3P_LUAHTTPS})
Expand Down
3 changes: 0 additions & 3 deletions src/libraries/luahttps/src/common/HTTPRequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,6 @@ HTTPSClient::Reply HTTPRequest::request(const HTTPSClient::Request &req)

request << "Host: " << info.hostname << "\r\n";

if (hasData && req.headers.count("Content-Type") == 0)
request << "Content-Type: application/x-www-form-urlencoded\r\n";

if (hasData)
request << "Content-Length: " << req.postdata.size() << "\r\n";

Expand Down
18 changes: 9 additions & 9 deletions src/libraries/luahttps/src/common/HTTPRequest.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,6 @@
class HTTPRequest
{
public:
typedef std::function<Connection *()> ConnectionFactory;
HTTPRequest(ConnectionFactory factory);

HTTPSClient::Reply request(const HTTPSClient::Request &req);

private:
ConnectionFactory factory;

struct DissectedURL
{
bool valid;
Expand All @@ -25,6 +17,14 @@ class HTTPRequest
std::string query;
// TODO: Auth?
};
typedef std::function<Connection *()> ConnectionFactory;

HTTPRequest(ConnectionFactory factory);

HTTPSClient::Reply request(const HTTPSClient::Request &req);

static DissectedURL parseUrl(const std::string &url);

DissectedURL parseUrl(const std::string &url);
private:
ConnectionFactory factory;
};
10 changes: 10 additions & 0 deletions src/libraries/luahttps/src/common/HTTPS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
#ifdef HTTPS_BACKEND_ANDROID
# include "../android/AndroidClient.h"
#endif
#ifdef HTTPS_BACKEND_WININET
# include "../windows/WinINetClient.h"
#endif

#ifdef HTTPS_BACKEND_CURL
static CurlClient curlclient;
Expand All @@ -35,13 +38,20 @@
#ifdef HTTPS_BACKEND_ANDROID
static AndroidClient androidclient;
#endif
#ifdef HTTPS_BACKEND_WININET
static WinINetClient wininetclient;
#endif

static HTTPSClient *clients[] = {
#ifdef HTTPS_BACKEND_CURL
&curlclient,
#endif
#ifdef HTTPS_BACKEND_OPENSSL
&opensslclient,
#endif
// WinINet must be above SChannel
#ifdef HTTPS_BACKEND_WININET
&wininetclient,
#endif
#ifdef HTTPS_BACKEND_SCHANNEL
&schannelclient,
Expand Down
4 changes: 2 additions & 2 deletions src/libraries/luahttps/src/common/HTTPSClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ bool HTTPSClient::ci_string_less::operator()(const std::string &lhs, const std::
}

HTTPSClient::Request::Request(const std::string &url)
: url(url)
, method("")
: url(url)
, method("GET")
{
}

5 changes: 5 additions & 0 deletions src/libraries/luahttps/src/common/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
#elif defined(WIN32) || defined(_WIN32)
#define HTTPS_BACKEND_SCHANNEL
#define HTTPS_USE_WINSOCK
#include <winapifamily.h>
#if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)
// WinINet is only supported on desktop.
#define HTTPS_BACKEND_WININET
#endif
#elif defined(__ANDROID__)
#define HTTPS_BACKEND_ANDROID
#elif defined(__APPLE__)
Expand Down
148 changes: 117 additions & 31 deletions src/libraries/luahttps/src/generic/CurlClient.cpp
Original file line number Diff line number Diff line change
@@ -1,49 +1,129 @@
#ifdef _WIN32
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#endif

#include "CurlClient.h"

#ifdef HTTPS_BACKEND_CURL

#include <dlfcn.h>
#include <algorithm>
#include <stdexcept>
#include <sstream>
#include <vector>

// Dynamic library loader
#ifdef _WIN32
#include <windows.h>
#else
#include <dlfcn.h>
#endif

typedef struct StringReader
{
const std::string *str;
size_t pos;
} StringReader;

template <class T>
static inline bool loadSymbol(T &var, void *handle, const char *name)
{
#ifdef _WIN32
var = (T) GetProcAddress((HMODULE) handle, name);
#else
var = (T) dlsym(handle, name);
#endif
return var != nullptr;
}

CurlClient::Curl::Curl()
: handle(nullptr)
, loaded(false)
, global_cleanup(nullptr)
, easy_init(nullptr)
, easy_cleanup(nullptr)
, easy_setopt(nullptr)
, easy_perform(nullptr)
, easy_getinfo(nullptr)
, slist_append(nullptr)
, slist_free_all(nullptr)
{
void *handle = dlopen("libcurl.so", RTLD_LAZY);
#ifdef _WIN32
handle = (void *) LoadLibraryA("libcurl.dll");
#else
handle = dlopen("libcurl.so.4", RTLD_LAZY);
#endif
if (!handle)
{
loaded = false;
return;
}

void (*global_init)() = (void(*)()) dlsym(handle, "curl_global_init");
easy_init = (CURL*(*)()) dlsym(handle, "curl_easy_init");
easy_cleanup = (void(*)(CURL*)) dlsym(handle, "curl_easy_cleanup");
easy_setopt = (CURLcode(*)(CURL*,CURLoption,...)) dlsym(handle, "curl_easy_setopt");
easy_perform = (CURLcode(*)(CURL*)) dlsym(handle, "curl_easy_perform");
easy_getinfo = (CURLcode(*)(CURL*,CURLINFO,...)) dlsym(handle, "curl_easy_getinfo");
slist_append = (curl_slist*(*)(curl_slist*,const char*)) dlsym(handle, "curl_slist_append");
slist_free_all = (void(*)(curl_slist*)) dlsym(handle, "curl_slist_free_all");
// Load symbols
decltype(&curl_global_init) global_init = nullptr;
if (!loadSymbol(global_init, handle, "curl_global_init"))
return;
if (!loadSymbol(global_cleanup, handle, "curl_global_cleanup"))
return;
if (!loadSymbol(easy_init, handle, "curl_easy_init"))
return;
if (!loadSymbol(easy_cleanup, handle, "curl_easy_cleanup"))
return;
if (!loadSymbol(easy_setopt, handle, "curl_easy_setopt"))
return;
if (!loadSymbol(easy_perform, handle, "curl_easy_perform"))
return;
if (!loadSymbol(easy_getinfo, handle, "curl_easy_getinfo"))
return;
if (!loadSymbol(slist_append, handle, "curl_slist_append"))
return;
if (!loadSymbol(slist_free_all, handle, "curl_slist_free_all"))
return;

global_init(CURL_GLOBAL_DEFAULT);
loaded = true;
}

CurlClient::Curl::~Curl()
{
if (loaded)
global_cleanup();

if (handle)
#ifdef _WIN32
FreeLibrary((HMODULE) handle);
#else
dlclose(handle);
#endif
}

static char toUppercase(char c)
{
int ch = (unsigned char) c;
return toupper(ch);
}

loaded = (global_init && easy_init && easy_cleanup && easy_setopt && easy_perform && easy_getinfo && slist_append && slist_free_all);
static size_t stringReader(char *ptr, size_t size, size_t nmemb, StringReader *reader)
{
const char *data = reader->str->data();
size_t len = reader->str->length();
size_t maxCount = (len - reader->pos) / size;
size_t desiredCount = std::min(maxCount, nmemb);
size_t desiredBytes = desiredCount * size;

if (!loaded)
return;
std::copy(data + reader->pos, data + desiredBytes, ptr);
reader->pos += desiredBytes;

global_init();
return desiredCount;
}

static size_t stringstreamWriter(char *ptr, size_t size, size_t nmemb, void *userdata)
static size_t stringstreamWriter(char *ptr, size_t size, size_t nmemb, std::stringstream *ss)
{
std::stringstream *ss = (std::stringstream*) userdata;
size_t count = size*nmemb;
ss->write(ptr, count);
return count;
}

static size_t headerWriter(char *ptr, size_t size, size_t nmemb, void *userdata)
static size_t headerWriter(char *ptr, size_t size, size_t nmemb, std::map<std::string,std::string> *userdata)
{
std::map<std::string, std::string> &headers = *((std::map<std::string,std::string>*) userdata);
std::map<std::string, std::string> &headers = *userdata;
size_t count = size*nmemb;
std::string line(ptr, count);
size_t split = line.find(':');
Expand All @@ -64,31 +144,37 @@ bool CurlClient::valid() const
HTTPSClient::Reply CurlClient::request(const HTTPSClient::Request &req)
{
Reply reply;
reply.responseCode = 400;
reply.responseCode = 0;

// Use sensible default header for later
HTTPSClient::header_map newHeaders = req.headers;

CURL *handle = curl.easy_init();
if (!handle)
throw std::runtime_error("Could not create curl request");

curl.easy_setopt(handle, CURLOPT_URL, req.url.c_str());
curl.easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1L);
curl.easy_setopt(handle, CURLOPT_CUSTOMREQUEST, req.method.c_str());

if (req.method == "PUT")
curl.easy_setopt(handle, CURLOPT_PUT, 1L);
else if (req.method == "POST")
curl.easy_setopt(handle, CURLOPT_POST, 1L);
else
curl.easy_setopt(handle, CURLOPT_CUSTOMREQUEST, req.method.c_str());
StringReader reader {};

if (req.postdata.size() > 0 && (req.method != "GET" && req.method != "HEAD"))
{
curl.easy_setopt(handle, CURLOPT_POSTFIELDS, req.postdata.c_str());
curl.easy_setopt(handle, CURLOPT_POSTFIELDSIZE, req.postdata.size());
reader.str = &req.postdata;
reader.pos = 0;
curl.easy_setopt(handle, CURLOPT_UPLOAD, 1L);
curl.easy_setopt(handle, CURLOPT_READFUNCTION, stringReader);
curl.easy_setopt(handle, CURLOPT_READDATA, &reader);
curl.easy_setopt(handle, CURLOPT_INFILESIZE_LARGE, (curl_off_t) req.postdata.length());
}

if (req.method == "HEAD")
curl.easy_setopt(handle, CURLOPT_NOBODY, 1L);

// Curl doesn't copy memory, keep the strings around
std::vector<std::string> lines;
for (auto &header : req.headers)
for (auto &header : newHeaders)
{
std::stringstream line;
line << header.first << ": " << header.second;
Expand Down
18 changes: 11 additions & 7 deletions src/libraries/luahttps/src/generic/CurlClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,20 @@ class CurlClient : public HTTPSClient
static struct Curl
{
Curl();
~Curl();
void *handle;
bool loaded;

CURL *(*easy_init)();
void (*easy_cleanup)(CURL *handle);
CURLcode (*easy_setopt)(CURL *handle, CURLoption option, ...);
CURLcode (*easy_perform)(CURL *easy_handle);
CURLcode (*easy_getinfo)(CURL *curl, CURLINFO info, ...);
decltype(&curl_global_cleanup) global_cleanup;

curl_slist *(*slist_append)(curl_slist *list, const char *string);
void (*slist_free_all)(curl_slist *list);
decltype(&curl_easy_init) easy_init;
decltype(&curl_easy_cleanup) easy_cleanup;
decltype(&curl_easy_setopt) easy_setopt;
decltype(&curl_easy_perform) easy_perform;
decltype(&curl_easy_getinfo) easy_getinfo;

decltype(&curl_slist_append) slist_append;
decltype(&curl_slist_free_all) slist_free_all;
} curl;
};

Expand Down
1 change: 1 addition & 0 deletions src/libraries/luahttps/src/lua/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ static int w_request(lua_State *L)
if (!lua_isnoneornil(L, -1))
{
req.postdata = w_checkstring(L, -1);
req.headers["Content-Type"] = "application/x-www-form-urlencoded";
defaultMethod = "POST";
}
lua_pop(L, 1);
Expand Down
Loading

0 comments on commit ddf88c6

Please sign in to comment.