#include #include #include #include #include #include "fetch.h" /* FIXME: "By default libfetch allows TLSv1 and newer when negotiating the connecting with the remote peer. You can change this behavior by setting the SSL_NO_TLS1, SSL_NO_TLS1_1 and SSL_NO_TLS1_2 environment variables to disable TLS 1.0, 1.1 and 1.2 respectively." */ int lp_error(lua_State *L, int code, char *message) { lua_pushnil(L); lua_pushinteger(L, code); lua_pushlstring(L, message, strlen(message)); return 3; } int lp_fetched(lua_State *L, FXRETTYPE fp, struct url_stat *stat) { size_t bytes_read = 0; char * content = 0; if(stat->size > 0) { content = (char *) malloc(stat->size); es_read(fp, content, stat->size, &bytes_read); if(bytes_read != stat->size) { lp_error(L, -1, "bytes read does not match content-length"); } } else { /* no content-length header */ int block_size = 128; int buf_size = block_size; size_t bytes_read_block; do { content = (char *) realloc(content, buf_size); es_read(fp, content + bytes_read, block_size, &bytes_read_block); bytes_read += bytes_read_block; buf_size += block_size; } while(bytes_read_block > 0); } lua_pushlstring(L, (const char *) content, bytes_read); lua_newtable(L); lua_pushliteral(L, "last-modified"); lua_pushinteger(L, stat->mtime); lua_settable(L, -3); /* free(content) ? */ return 2; } int lp_fetch(lua_State *L) { const char * url_string = luaL_checkstring(L, 1); const char * flags = luaL_optstring(L, 2, ""); time_t if_modified_since = luaL_optinteger(L, 3, 0); struct url *url = fetchParseURL(url_string); if(url == NULL) { return lp_error(L, -1, "url not parseable"); } url->ims_time = if_modified_since; struct url_stat stat; FXRETTYPE fp = fetchXGet(url, &stat, flags); fetchFreeURL(url); if(fp == NULL) { return lp_error(L, fetchLastErrCode, fetchLastErrString); } return lp_fetched(L, fp, &stat); } int lp_request(lua_State *L) { const char * request_method = luaL_checkstring(L, 1); const char * url_string = luaL_checkstring(L, 2); const char * flags = luaL_optstring(L, 3, ""); time_t if_modified_since = luaL_optinteger(L, 4, 0); const char * content_type = lua_tostring(L, 5); const char * body = lua_tostring(L, 6); struct url *url = fetchParseURL(url_string); if(url == NULL) { return lp_error(L, -1, "url not parseable"); } url->ims_time = if_modified_since; struct url_stat stat; FXRETTYPE fp = http_request_body(url, request_method, &stat, NULL, /* no proxy */ flags, content_type, body); fetchFreeURL(url); if(fp == NULL) { return lp_error(L, fetchLastErrCode, fetchLastErrString); } return lp_fetched(L, fp, &stat); } static const struct luaL_Reg funcs [] = { {"fetch", lp_fetch}, {"request", lp_request}, {NULL, NULL} /* sentinel */ }; int luaopen_fetch (lua_State *L) { luaL_newlib(L, funcs); return 1; }