From d576e0ad6425496affc0abfeeb2506f4cd879fe5 Mon Sep 17 00:00:00 2001 From: Jan Kneschke Date: Sun, 24 Jul 2005 06:58:03 +0000 Subject: [PATCH] added functions file_isreg() and dir_files() and added last-modified handling git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.3.x@472 152afb58-edef-0310-8abb-c4023f1b3aa9 --- src/mod_cml_funcs.c | 79 ++++++++++++++++++++++++++++++++++++++++++--- src/mod_cml_funcs.h | 3 ++ src/mod_cml_lua.c | 14 +++++++- 3 files changed, 91 insertions(+), 5 deletions(-) diff --git a/src/mod_cml_funcs.c b/src/mod_cml_funcs.c index d5c7f320..9f5b4d9b 100644 --- a/src/mod_cml_funcs.c +++ b/src/mod_cml_funcs.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include "buffer.h" @@ -74,18 +75,18 @@ int f_file_mtime(lua_State *L) { int n = lua_gettop(L); if (n != 1) { - lua_pushstring(L, "expected one argument"); + lua_pushstring(L, "file_mtime: expected one argument"); lua_error(L); } if (!lua_isstring(L, 1)) { - lua_pushstring(L, "argument has to be a string"); + lua_pushstring(L, "file_mtime: argument has to be a string"); lua_error(L); } if (-1 == stat(lua_tostring(L, 1), &st)) { - lua_pushstring(L, "stat failed"); - lua_error(L); + lua_pushnil(L); + return 1; } lua_pushnumber(L, st.st_mtime); @@ -93,6 +94,76 @@ int f_file_mtime(lua_State *L) { return 1; } +int f_dir_files_iter(lua_State *L) { + DIR *d; + struct dirent *de; + int n = lua_gettop(L); + + d = lua_touserdata(L, lua_upvalueindex(1)); + + if (NULL == (de = readdir(d))) { + /* EOF */ + closedir(d); + + return 0; + } else { + lua_pushstring(L, de->d_name); + return 1; + } +} + +int f_dir_files(lua_State *L) { + DIR *d; + int n = lua_gettop(L); + + if (n != 1) { + lua_pushstring(L, "dir_files: expected one argument"); + lua_error(L); + } + + if (!lua_isstring(L, 1)) { + lua_pushstring(L, "dir_files: argument has to be a string"); + lua_error(L); + } + + /* check if there is a valid DIR handle on the stack */ + if (NULL == (d = opendir(lua_tostring(L, 1)))) { + lua_pushnil(L); + return 1; + } + + /* push d into registry */ + lua_pushlightuserdata(L, d); + lua_pushcclosure(L, f_dir_files_iter, 1); + + return 1; +} + +int f_file_isreg(lua_State *L) { + struct stat st; + int n = lua_gettop(L); + + if (n != 1) { + lua_pushstring(L, "file_isreg: expected one argument"); + lua_error(L); + } + + if (!lua_isstring(L, 1)) { + lua_pushstring(L, "file_isreg: argument has to be a string"); + lua_error(L); + } + + if (-1 == stat(lua_tostring(L, 1), &st)) { + lua_pushnil(L); + return 1; + } + + lua_pushnumber(L, S_ISREG(st.st_mode)); + + return 1; +} + + #ifdef HAVE_MEMCACHE_H int f_memcache_exists(lua_State *L) { char *r; diff --git a/src/mod_cml_funcs.h b/src/mod_cml_funcs.h index f318d40e..f53557c0 100644 --- a/src/mod_cml_funcs.h +++ b/src/mod_cml_funcs.h @@ -8,6 +8,9 @@ int f_crypto_md5(lua_State *L); int f_file_mtime(lua_State *L); +int f_file_isreg(lua_State *L); +int f_dir_files(lua_State *L); + int f_memcache_exists(lua_State *L); int f_memcache_get_string(lua_State *L); int f_memcache_get_long(lua_State *L); diff --git a/src/mod_cml_lua.c b/src/mod_cml_lua.c index 05659c94..1392d2b7 100644 --- a/src/mod_cml_lua.c +++ b/src/mod_cml_lua.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "mod_cml.h" #include "mod_cml_funcs.h" @@ -164,6 +165,8 @@ int cache_parse_lua(server *srv, connection *con, plugin_data *p, buffer *fn) { /* register functions */ lua_register(L, "md5", f_crypto_md5); lua_register(L, "file_mtime", f_file_mtime); + lua_register(L, "file_isreg", f_file_isreg); + lua_register(L, "dir_files", f_dir_files); #ifdef HAVE_MEMCACHE_H lua_pushliteral(L, "memcache_get_long"); @@ -312,7 +315,16 @@ int cache_parse_lua(server *srv, connection *con, plugin_data *p, buffer *fn) { if (ret == 0) { con->file_finished = 1; - + + /* no Last-Modified specified */ + if (mtime && NULL == array_get_element(con->response.headers, "Last-Modified")) { + char timebuf[sizeof("Sat, 23 Jul 2005 21:20:01 GMT")]; + + strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&mtime)); + + response_header_overwrite(srv, con, CONST_STR_LEN("Last-Modified"), timebuf, sizeof(timebuf) - 1); + } + if (http_response_handle_cachable(srv, con, mtime)) { /* ok, the client already has our content, * no need to send it again */