Improvements to http.get and http.download
There was an undocumented return code from http.download which was the numerical CURL error code. This has been replaced with the HTTP response code. The return for http.download is now error message, HTTP response code. This could break code that was relying on the CURL error but my light research is that users of this call were checking for the error message being “OK” and that functionality is preserved. http.get has been updated to have a consistent return signature to http.download and now returns the result, error message, HTTP response code. The error message is now set to “OK” to match http.download. These changes abstract this api from curl and make the focus http. Cleaned up the code to make it easier to follow and removed some memory leaks. http.get and http.download would leak if headers were supplied. http.get would leak the string buffer if curl_init failed.
This commit is contained in:
parent
780cd5f717
commit
31b22502b3
@ -45,11 +45,12 @@ typedef struct
|
||||
int RefIndex;
|
||||
string S;
|
||||
char errorBuffer[CURL_ERROR_SIZE];
|
||||
} CurlCallbackState;
|
||||
struct curl_slist* headers;
|
||||
} curl_state;
|
||||
|
||||
static int curl_progress_cb(void* userdata, double dltotal, double dlnow, double ultotal, double ulnow)
|
||||
{
|
||||
CurlCallbackState* state = (CurlCallbackState*) userdata;
|
||||
curl_state* state = (curl_state*) userdata;
|
||||
lua_State* L = state->L;
|
||||
|
||||
(void)ultotal;
|
||||
@ -68,7 +69,7 @@ static int curl_progress_cb(void* userdata, double dltotal, double dlnow, double
|
||||
|
||||
static size_t curl_write_cb(char *ptr, size_t size, size_t nmemb, void *userdata)
|
||||
{
|
||||
CurlCallbackState* state = (CurlCallbackState*) userdata;
|
||||
curl_state* state = (curl_state*) userdata;
|
||||
string* s = &state->S;
|
||||
|
||||
size_t new_len = s->len + size * nmemb;
|
||||
@ -117,10 +118,16 @@ static void get_headers(lua_State* L, int headersIndex, struct curl_slist** head
|
||||
}
|
||||
}
|
||||
|
||||
static CURL* curl_request(lua_State* L, CurlCallbackState* state, const char* url, FILE* fp, int optionsIndex, int progressFnIndex, int headersIndex)
|
||||
static CURL* curl_request(lua_State* L, curl_state* state, const char* url, FILE* fp, int optionsIndex, int progressFnIndex, int headersIndex)
|
||||
{
|
||||
CURL* curl;
|
||||
struct curl_slist* headers = NULL;
|
||||
|
||||
state->L = 0;
|
||||
state->RefIndex = 0;
|
||||
state->S.ptr = NULL;
|
||||
state->S.len = 0;
|
||||
state->errorBuffer[0] = '\0';
|
||||
state->headers = NULL;
|
||||
|
||||
curl_init();
|
||||
curl = curl_easy_init();
|
||||
@ -145,8 +152,8 @@ static CURL* curl_request(lua_State* L, CurlCallbackState* state, const char* ur
|
||||
|
||||
if (!strcmp(key, "headers") && lua_istable(L, -1))
|
||||
{
|
||||
get_headers(L, lua_gettop(L), &headers);
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
||||
get_headers(L, lua_gettop(L), &state->headers);
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, state->headers);
|
||||
}
|
||||
else if (!strcmp(key, "progress") && lua_isfunction(L, -1))
|
||||
{
|
||||
@ -182,8 +189,8 @@ static CURL* curl_request(lua_State* L, CurlCallbackState* state, const char* ur
|
||||
|
||||
if (headersIndex && lua_istable(L, headersIndex))
|
||||
{
|
||||
get_headers(L, headersIndex, &headers);
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
||||
get_headers(L, headersIndex, &state->headers);
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, state->headers);
|
||||
}
|
||||
}
|
||||
|
||||
@ -209,13 +216,24 @@ static CURL* curl_request(lua_State* L, CurlCallbackState* state, const char* ur
|
||||
return curl;
|
||||
}
|
||||
|
||||
static void curl_cleanup(CURL* curl, curl_state* state)
|
||||
{
|
||||
if (state->headers)
|
||||
{
|
||||
curl_slist_free_all(state->headers);
|
||||
state->headers = 0;
|
||||
}
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
|
||||
int http_get(lua_State* L)
|
||||
{
|
||||
CurlCallbackState state = { 0, 0, {NULL, 0}, {0} };
|
||||
curl_state state;
|
||||
CURL* curl;
|
||||
CURLcode code;
|
||||
|
||||
CURLcode code = CURLE_FAILED_INIT;
|
||||
long responseCode = 0;
|
||||
|
||||
if (lua_istable(L, 2))
|
||||
{
|
||||
// http.get(source, { options })
|
||||
@ -228,41 +246,42 @@ int http_get(lua_State* L)
|
||||
curl = curl_request(L, &state, luaL_checkstring(L, 1), /*fp=*/NULL, /*optionsIndex=*/0, /*progressFnIndex=*/2, /*headersIndex=*/3);
|
||||
}
|
||||
|
||||
if (!curl)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
string_init(&state.S);
|
||||
|
||||
code = curl_easy_perform(curl);
|
||||
if (code != CURLE_OK)
|
||||
if (curl)
|
||||
{
|
||||
char errorBuf[1024];
|
||||
snprintf(errorBuf, sizeof(errorBuf) - 1, "%s\n%s\n", curl_easy_strerror(code), state.errorBuffer);
|
||||
|
||||
lua_pushnil(L);
|
||||
lua_pushfstring(L, errorBuf);
|
||||
string_free(&state.S);
|
||||
return 2;
|
||||
code = curl_easy_perform(curl);
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode);
|
||||
curl_cleanup(curl, &state);
|
||||
}
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
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");
|
||||
}
|
||||
|
||||
lua_pushlstring(L, state.S.ptr, state.S.len);
|
||||
string_free(&state.S);
|
||||
|
||||
return 1;
|
||||
lua_pushnumber(L, responseCode);
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
||||
int http_download(lua_State* L)
|
||||
{
|
||||
CurlCallbackState state = { 0, 0, {NULL, 0}, {0} };
|
||||
|
||||
curl_state state;
|
||||
CURL* curl;
|
||||
CURLcode code = CURLE_FAILED_INIT;
|
||||
long responseCode = 0;
|
||||
|
||||
FILE* fp;
|
||||
const char* file = luaL_checkstring(L, 2);
|
||||
@ -290,7 +309,8 @@ int http_download(lua_State* L)
|
||||
if (curl)
|
||||
{
|
||||
code = curl_easy_perform(curl);
|
||||
curl_easy_cleanup(curl);
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode);
|
||||
curl_cleanup(curl, &state);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
@ -306,7 +326,8 @@ int http_download(lua_State* L)
|
||||
lua_pushstring(L, "OK");
|
||||
}
|
||||
|
||||
lua_pushnumber(L, code);
|
||||
lua_pushnumber(L, responseCode);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user