Merge pull request #499 from mversluys/master
Improvements to http.get and http.download
This commit is contained in:
commit
5b5ef74331
@ -45,11 +45,12 @@ typedef struct
|
|||||||
int RefIndex;
|
int RefIndex;
|
||||||
string S;
|
string S;
|
||||||
char errorBuffer[CURL_ERROR_SIZE];
|
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)
|
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;
|
lua_State* L = state->L;
|
||||||
|
|
||||||
(void)ultotal;
|
(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)
|
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;
|
string* s = &state->S;
|
||||||
|
|
||||||
size_t new_len = s->len + size * nmemb;
|
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;
|
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_init();
|
||||||
curl = curl_easy_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))
|
if (!strcmp(key, "headers") && lua_istable(L, -1))
|
||||||
{
|
{
|
||||||
get_headers(L, lua_gettop(L), &headers);
|
get_headers(L, lua_gettop(L), &state->headers);
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, state->headers);
|
||||||
}
|
}
|
||||||
else if (!strcmp(key, "progress") && lua_isfunction(L, -1))
|
else if (!strcmp(key, "progress") && lua_isfunction(L, -1))
|
||||||
{
|
{
|
||||||
@ -166,6 +173,10 @@ static CURL* curl_request(lua_State* L, CurlCallbackState* state, const char* ur
|
|||||||
{
|
{
|
||||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, luaL_checkstring(L, -1));
|
curl_easy_setopt(curl, CURLOPT_PASSWORD, luaL_checkstring(L, -1));
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(key, "timeout") && lua_isnumber(L, -1))
|
||||||
|
{
|
||||||
|
curl_easy_setopt(curl, CURLOPT_TIMEOUT, luaL_checknumber(L, -1));
|
||||||
|
}
|
||||||
|
|
||||||
// pop the value, leave the key for lua_next
|
// pop the value, leave the key for lua_next
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
@ -182,8 +193,8 @@ static CURL* curl_request(lua_State* L, CurlCallbackState* state, const char* ur
|
|||||||
|
|
||||||
if (headersIndex && lua_istable(L, headersIndex))
|
if (headersIndex && lua_istable(L, headersIndex))
|
||||||
{
|
{
|
||||||
get_headers(L, headersIndex, &headers);
|
get_headers(L, headersIndex, &state->headers);
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, state->headers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,13 +220,24 @@ static CURL* curl_request(lua_State* L, CurlCallbackState* state, const char* ur
|
|||||||
return curl;
|
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)
|
int http_get(lua_State* L)
|
||||||
{
|
{
|
||||||
CurlCallbackState state = { 0, 0, {NULL, 0}, {0} };
|
curl_state state;
|
||||||
CURL* curl;
|
CURL* curl;
|
||||||
CURLcode code;
|
CURLcode code = CURLE_FAILED_INIT;
|
||||||
|
long responseCode = 0;
|
||||||
|
|
||||||
if (lua_istable(L, 2))
|
if (lua_istable(L, 2))
|
||||||
{
|
{
|
||||||
// http.get(source, { options })
|
// http.get(source, { options })
|
||||||
@ -228,41 +250,42 @@ int http_get(lua_State* L)
|
|||||||
curl = curl_request(L, &state, luaL_checkstring(L, 1), /*fp=*/NULL, /*optionsIndex=*/0, /*progressFnIndex=*/2, /*headersIndex=*/3);
|
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);
|
string_init(&state.S);
|
||||||
|
|
||||||
code = curl_easy_perform(curl);
|
if (curl)
|
||||||
if (code != CURLE_OK)
|
|
||||||
{
|
{
|
||||||
char errorBuf[1024];
|
code = curl_easy_perform(curl);
|
||||||
snprintf(errorBuf, sizeof(errorBuf) - 1, "%s\n%s\n", curl_easy_strerror(code), state.errorBuffer);
|
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode);
|
||||||
|
curl_cleanup(curl, &state);
|
||||||
lua_pushnil(L);
|
|
||||||
lua_pushfstring(L, errorBuf);
|
|
||||||
string_free(&state.S);
|
|
||||||
return 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
string_free(&state.S);
|
||||||
|
|
||||||
return 1;
|
lua_pushnumber(L, responseCode);
|
||||||
|
|
||||||
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int http_download(lua_State* L)
|
int http_download(lua_State* L)
|
||||||
{
|
{
|
||||||
CurlCallbackState state = { 0, 0, {NULL, 0}, {0} };
|
curl_state state;
|
||||||
|
|
||||||
CURL* curl;
|
CURL* curl;
|
||||||
CURLcode code = CURLE_FAILED_INIT;
|
CURLcode code = CURLE_FAILED_INIT;
|
||||||
|
long responseCode = 0;
|
||||||
|
|
||||||
FILE* fp;
|
FILE* fp;
|
||||||
const char* file = luaL_checkstring(L, 2);
|
const char* file = luaL_checkstring(L, 2);
|
||||||
@ -290,7 +313,8 @@ int http_download(lua_State* L)
|
|||||||
if (curl)
|
if (curl)
|
||||||
{
|
{
|
||||||
code = curl_easy_perform(curl);
|
code = curl_easy_perform(curl);
|
||||||
curl_easy_cleanup(curl);
|
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode);
|
||||||
|
curl_cleanup(curl, &state);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
@ -306,7 +330,8 @@ int http_download(lua_State* L)
|
|||||||
lua_pushstring(L, "OK");
|
lua_pushstring(L, "OK");
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_pushnumber(L, code);
|
lua_pushnumber(L, responseCode);
|
||||||
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user