commit 9550772cec7a7230996ef20eeb3fb9b9fc314a05
parent 64cd1626c6c0086f981b21b871cc67c4cbf9881c
Author: Daniel Barlow <dan@telent.net>
Date: Thu, 8 Aug 2024 13:27:21 +0100
add lua binding to fetch-freebsd
Diffstat:
2 files changed, 76 insertions(+), 1 deletion(-)
diff --git a/pkgs/fetch-freebsd/default.nix b/pkgs/fetch-freebsd/default.nix
@@ -2,6 +2,7 @@
cmake,
stdenv,
openssl,
+ lua,
fetchFromGitHub
}: stdenv.mkDerivation {
pname = "fetch-freebsd";
@@ -17,9 +18,14 @@
"-DFETCH_LIBRARY=ON"
"-DUSE_SYSTEM_SSL=ON"
];
+ postBuild = ''
+ $CC -shared -o fetch-lua.so ${./lua-glue.c} -I$src -Llibrary -lssl -lfetch -llua
+ '';
nativeBuildInputs = [ cmake ];
- buildInputs = [ openssl ];
+ buildInputs = [ lua openssl ];
postInstall = ''
rm -r $out/lib/lib*.a
+ mkdir -p $out/lib/lua/${lua.luaversion}
+ install fetch-lua.so $out/lib/lua/${lua.luaversion}/fetch.so
'';
}
diff --git a/pkgs/fetch-freebsd/lua-glue.c b/pkgs/fetch-freebsd/lua-glue.c
@@ -0,0 +1,69 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+#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) {
+ void * content = malloc(stat->size);
+ size_t bytes_read;
+ es_read(fp, content, stat->size, &bytes_read);
+
+ if(bytes_read != stat->size) {
+ lp_error(L, -1, "bytes read does not match content-length");
+ }
+ lua_pushlstring(L, (const char *) content, stat->size);
+ lua_newtable(L);
+ lua_pushliteral(L, "last-modified");
+ lua_pushinteger(L, stat->mtime);
+ lua_settable(L, -3);
+
+ 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);
+}
+
+static const struct luaL_Reg funcs [] = {
+ {"fetch", lp_fetch},
+ {NULL, NULL} /* sentinel */
+};
+
+
+int luaopen_fetch (lua_State *L) {
+ luaL_newlib(L, funcs);
+ return 1;
+}