lua-glue.c (3133B)
1 #include <stdlib.h> 2 #include <string.h> 3 4 #include <lua.h> 5 #include <lualib.h> 6 #include <lauxlib.h> 7 #include "fetch.h" 8 9 /* 10 FIXME: "By default libfetch allows TLSv1 and newer when negotiating 11 the connecting with the remote peer. You can change this behavior 12 by setting the SSL_NO_TLS1, SSL_NO_TLS1_1 and SSL_NO_TLS1_2 13 environment variables to disable TLS 1.0, 1.1 and 1.2 respectively." 14 */ 15 16 int lp_error(lua_State *L, int code, char *message) { 17 lua_pushnil(L); 18 lua_pushinteger(L, code); 19 lua_pushlstring(L, message, strlen(message)); 20 return 3; 21 } 22 23 int lp_fetched(lua_State *L, FXRETTYPE fp, struct url_stat *stat) { 24 size_t bytes_read = 0; 25 char * content = 0; 26 if(stat->size > 0) { 27 content = (char *) malloc(stat->size); 28 es_read(fp, content, stat->size, &bytes_read); 29 30 if(bytes_read != stat->size) { 31 lp_error(L, -1, "bytes read does not match content-length"); 32 } 33 } else { 34 /* no content-length header */ 35 int block_size = 128; 36 int buf_size = block_size; 37 size_t bytes_read_block; 38 do { 39 content = (char *) realloc(content, buf_size); 40 es_read(fp, content + bytes_read, block_size, &bytes_read_block); 41 bytes_read += bytes_read_block; 42 buf_size += block_size; 43 } while(bytes_read_block > 0); 44 } 45 46 lua_pushlstring(L, (const char *) content, bytes_read); 47 lua_newtable(L); 48 lua_pushliteral(L, "last-modified"); 49 lua_pushinteger(L, stat->mtime); 50 lua_settable(L, -3); 51 /* free(content) ? */ 52 return 2; 53 } 54 55 int lp_fetch(lua_State *L) { 56 const char * url_string = luaL_checkstring(L, 1); 57 const char * flags = luaL_optstring(L, 2, ""); 58 time_t if_modified_since = luaL_optinteger(L, 3, 0); 59 60 struct url *url = fetchParseURL(url_string); 61 if(url == NULL) { 62 return lp_error(L, -1, "url not parseable"); 63 } 64 url->ims_time = if_modified_since; 65 struct url_stat stat; 66 67 FXRETTYPE fp = fetchXGet(url, &stat, flags); 68 fetchFreeURL(url); 69 if(fp == NULL) { 70 return lp_error(L, fetchLastErrCode, fetchLastErrString); 71 } 72 return lp_fetched(L, fp, &stat); 73 } 74 75 int lp_request(lua_State *L) { 76 const char * request_method = luaL_checkstring(L, 1); 77 const char * url_string = luaL_checkstring(L, 2); 78 const char * flags = luaL_optstring(L, 3, ""); 79 time_t if_modified_since = luaL_optinteger(L, 4, 0); 80 const char * content_type = lua_tostring(L, 5); 81 const char * body = lua_tostring(L, 6); 82 83 struct url *url = fetchParseURL(url_string); 84 if(url == NULL) { 85 return lp_error(L, -1, "url not parseable"); 86 } 87 url->ims_time = if_modified_since; 88 struct url_stat stat; 89 90 FXRETTYPE fp = http_request_body(url, 91 request_method, 92 &stat, 93 NULL, /* no proxy */ 94 flags, 95 content_type, 96 body); 97 fetchFreeURL(url); 98 if(fp == NULL) { 99 return lp_error(L, fetchLastErrCode, fetchLastErrString); 100 } 101 return lp_fetched(L, fp, &stat); 102 } 103 104 static const struct luaL_Reg funcs [] = { 105 {"fetch", lp_fetch}, 106 {"request", lp_request}, 107 {NULL, NULL} /* sentinel */ 108 }; 109 110 111 int luaopen_fetch (lua_State *L) { 112 luaL_newlib(L, funcs); 113 return 1; 114 }