liminix

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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 }