From f7468b66bf8df89f092ac27801219b8a27fcc118 Mon Sep 17 00:00:00 2001 From: Tom van Dijck Date: Tue, 30 Aug 2016 12:05:43 -0700 Subject: [PATCH] Clean up curl wrapper a bit... --- src/host/http.c | 86 +++++++++++++++++++++++++++++++++++++--------- src/host/premake.c | 3 +- src/host/premake.h | 1 + 3 files changed, 73 insertions(+), 17 deletions(-) diff --git a/src/host/http.c b/src/host/http.c index 54b9b787..16da3861 100644 --- a/src/host/http.c +++ b/src/host/http.c @@ -118,7 +118,7 @@ static void get_headers(lua_State* L, int headersIndex, struct curl_slist** head } } -static CURL* curl_request(lua_State* L, curl_state* state, const char* url, FILE* fp, int optionsIndex, int progressFnIndex, int headersIndex) +static CURL* curl_request(lua_State* L, curl_state* state, int optionsIndex, int progressFnIndex, int headersIndex) { CURL* curl; @@ -135,8 +135,7 @@ static CURL* curl_request(lua_State* L, curl_state* state, const char* url, FILE if (!curl) return NULL; - curl_easy_setopt(curl, CURLOPT_URL, url); - curl_easy_setopt(curl, CURLOPT_HTTPGET, 1); + curl_easy_setopt(curl, CURLOPT_URL, luaL_checkstring(L, 1)); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1); @@ -177,6 +176,18 @@ static CURL* curl_request(lua_State* L, curl_state* state, const char* url, FILE { curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long)luaL_checknumber(L, -1)); } + else if (!strcmp(key, "timeoutms") && lua_isnumber(L, -1)) + { + curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, (long)luaL_checknumber(L, -1)); + } + else if (!strcmp(key, "sslverifyhost") && lua_isnumber(L, -1)) + { + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, (long)luaL_checknumber(L, -1)); + } + else if (!strcmp(key, "sslverifypeer") && lua_isnumber(L, -1)) + { + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, (long)luaL_checknumber(L, -1)); + } // pop the value, leave the key for lua_next lua_pop(L, 1); @@ -201,12 +212,6 @@ static CURL* curl_request(lua_State* L, curl_state* state, const char* url, FILE curl_easy_setopt(curl, CURLOPT_WRITEDATA, state); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_cb); - if (fp) - { - curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_file_cb); - } - if (state->L != 0) { curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); @@ -241,19 +246,20 @@ int http_get(lua_State* L) if (lua_istable(L, 2)) { // http.get(source, { options }) - curl = curl_request(L, &state, luaL_checkstring(L, 1), /*fp=*/NULL, /*optionsIndex=*/2, /*progressFnIndex=*/0, /*headersIndex=*/0); + curl = curl_request(L, &state, /*optionsIndex=*/2, /*progressFnIndex=*/0, /*headersIndex=*/0); } else { // backward compatible function signature // http.get(source, progressFunction, { headers }) - curl = curl_request(L, &state, luaL_checkstring(L, 1), /*fp=*/NULL, /*optionsIndex=*/0, /*progressFnIndex=*/2, /*headersIndex=*/3); + curl = curl_request(L, &state, /*optionsIndex=*/0, /*progressFnIndex=*/2, /*headersIndex=*/3); } string_init(&state.S); - if (curl) { + curl_easy_setopt(curl, CURLOPT_HTTPGET, 1); + code = curl_easy_perform(curl); curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode); curl_cleanup(curl, &state); @@ -273,9 +279,54 @@ int http_get(lua_State* L) } string_free(&state.S); - lua_pushnumber(L, responseCode); + return 3; +} + +int http_post(lua_State* L) +{ + curl_state state; + CURL* curl; + CURLcode code = CURLE_FAILED_INIT; + long responseCode = 0; + + // http.post(source, postdata, { options }) + curl = curl_request(L, &state, /*optionsIndex=*/3, /*progressFnIndex=*/0, /*headersIndex=*/0); + + string_init(&state.S); + if (curl) + { + curl_easy_setopt(curl, CURLOPT_POST, 1); + + size_t dataSize; + const char* data = luaL_checklstring(L, 2, &dataSize); + if (data && dataSize > 0) + { + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)dataSize); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data); + } + + code = curl_easy_perform(curl); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode); + curl_cleanup(curl, &state); + } + + if (code != CURLE_OK) + { + lua_pushnil(L); + char errorBuf[1024]; + snprintf(errorBuf, sizeof(errorBuf) - 1, "%s\n%s\n", curl_easy_strerror(code), state.errorBuffer); + lua_pushstring(L, errorBuf); + } + else + { + lua_pushlstring(L, state.S.ptr, state.S.len); + lua_pushstring(L, "OK"); + } + + string_free(&state.S); + lua_pushnumber(L, responseCode); return 3; } @@ -301,17 +352,21 @@ int http_download(lua_State* L) if (lua_istable(L, 3)) { // http.download(source, destination, { options }) - curl = curl_request(L, &state, luaL_checkstring(L, 1), fp, /*optionsIndex=*/3, /*progressFnIndex=*/0, /*headersIndex=*/0); + curl = curl_request(L, &state, /*optionsIndex=*/3, /*progressFnIndex=*/0, /*headersIndex=*/0); } else { // backward compatible function signature // http.download(source, destination, progressFunction, { headers }) - curl = curl_request(L, &state, luaL_checkstring(L, 1), fp, /*optionsIndex=*/0, /*progressFnIndex=*/3, /*headersIndex=*/4); + curl = curl_request(L, &state, /*optionsIndex=*/0, /*progressFnIndex=*/3, /*headersIndex=*/4); } if (curl) { + curl_easy_setopt(curl, CURLOPT_HTTPGET, 1); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_file_cb); + code = curl_easy_perform(curl); curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode); curl_cleanup(curl, &state); @@ -331,7 +386,6 @@ int http_download(lua_State* L) } lua_pushnumber(L, responseCode); - return 2; } diff --git a/src/host/premake.c b/src/host/premake.c index 115a7a3e..8c26b306 100644 --- a/src/host/premake.c +++ b/src/host/premake.c @@ -97,7 +97,8 @@ static const luaL_Reg buffered_functions[] = { #ifdef PREMAKE_CURL static const luaL_Reg http_functions[] = { - { "get", http_get }, + { "get", http_get }, + { "post", http_post }, { "download", http_download }, { NULL, NULL } }; diff --git a/src/host/premake.h b/src/host/premake.h index c52e2693..a028ad88 100644 --- a/src/host/premake.h +++ b/src/host/premake.h @@ -135,6 +135,7 @@ int buffered_tostring(lua_State* L); #ifdef PREMAKE_CURL int http_get(lua_State* L); +int http_post(lua_State* L); int http_download(lua_State* L); #endif