diff options
| author | mrg <mrg@NetBSD.org> | 2010-05-10 03:30:04 +0000 |
|---|---|---|
| committer | mrg <mrg@NetBSD.org> | 2010-05-10 03:30:04 +0000 |
| commit | 390458fa546a7c8cf4c2ef38e584c9bbbc2cd638 (patch) | |
| tree | 3938648e1845c1cba939af177317c91561ef9ee4 /libexec/httpd/lua | |
| parent | 10e151e52e2a8ed4f8f81ec5c34250e73569797b (diff) | |
import bozohttpd 20100509. it has these changes:
o major rework and clean up of internal interfaces. move the main
program into main.c, the remaining parts are useable as library.
add bindings for lua. by Alistair G. Crooks <agc@netbsd.org>
o fix http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=566325
special thanks to al for the majority of these changes.
Diffstat (limited to 'libexec/httpd/lua')
| -rw-r--r-- | libexec/httpd/lua/Makefile | 39 | ||||
| -rwxr-xr-x | libexec/httpd/lua/bozo.lua | 162 | ||||
| -rw-r--r-- | libexec/httpd/lua/glue.c | 276 | ||||
| -rw-r--r-- | libexec/httpd/lua/optparse.lua | 123 | ||||
| -rw-r--r-- | libexec/httpd/lua/shlib_version | 2 |
5 files changed, 602 insertions, 0 deletions
diff --git a/libexec/httpd/lua/Makefile b/libexec/httpd/lua/Makefile new file mode 100644 index 00000000000..448fa71946c --- /dev/null +++ b/libexec/httpd/lua/Makefile @@ -0,0 +1,39 @@ +#PREFIX=/Users/agcrooks +PREFIX=/usr + +#LIBDIR=/usr/lib + +LIB=luabozohttpd +SRCS=glue.c +MKMAN=no +CPPFLAGS+=-g -I${PREFIX}/pkg/include +LDADD+= -lbozohttpd +WARNS=4 +CLEANFILES+= a a.sig + +.include <bsd.lib.mk> +.include <bsd.own.mk> + +LUABOZOOBJDIR != cd ${.CURDIR} && ${PRINTOBJDIR} + +OPSYS!= uname -s + +.if ${OPSYS} == "Darwin" +.sinclude <bsd.warns.mk> + +lib${LIB}.dylib: + libtool -dynamic -o ${.TARGET} ${OBJS} ${PREFIX}/pkg/lib/liblua.dylib /usr/lib/libc.dylib ${PREFIX}/pkg/lib/libbozohttpd.dylib + +t: lib${LIB}.dylib + cp Makefile a + ./bozo.lua --sign --detached a + ./bozo.lua --verify a.sig + +.else +t: + cp Makefile a + env LD_LIBRARY_PATH=${LUABOZOOBJDIR}:/lib:/usr/lib:${PREFIX}/lib \ + ./bozo.lua --sign --detached a + env LD_LIBRARY_PATH=${LUABOZOOBJDIR}:/lib:/usr/lib:${PREFIX}/lib \ + ./bozo.lua --verify a.sig +.endif diff --git a/libexec/httpd/lua/bozo.lua b/libexec/httpd/lua/bozo.lua new file mode 100755 index 00000000000..9a30c9f1fc6 --- /dev/null +++ b/libexec/httpd/lua/bozo.lua @@ -0,0 +1,162 @@ +#! /usr/bin/env lua + +-- +-- Copyright (c) 2009 The NetBSD Foundation, Inc. +-- All rights reserved. +-- +-- This code is derived from software contributed to The NetBSD Foundation +-- by Alistair Crooks (agc@netbsd.org) +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: +-- 1. Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +-- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +-- BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- + +-- command line args +dofile "optparse.lua" + +opt = OptionParser{usage="%prog [options] root [vhost]", version="20091105"} + +opt.add_option{"-C", "--cgimap", action="store", dest="cgimap", help="--cgimap 's t'"} +opt.add_option{"-H", "--hide-dots", action="store_true", dest="hidedots", help="--hide-dots"} +opt.add_option{"-I", "--portnum", action="store", dest="portnum", help="--portnum number"} +opt.add_option{"-M", "--dynamicmime", action="store", dest="dynmime", help="--dynamicmime 'suffix type a b'"} +opt.add_option{"-S", "--server-software", action="store", dest="serversw", help="--server-software name"} +opt.add_option{"-U", "--username", action="store", dest="username", help="--username name"} +opt.add_option{"-V", "--unknown-slash", action="store_true", dest="unknown", help="--unknown-slash"} +opt.add_option{"-X", "--dir-index", action="store_true", dest="dirindex", help="--dir-index"} +opt.add_option{"-Z", "--ssl", action="store", dest="ssl", help="--ssl 'cert priv'"} +opt.add_option{"-b", "--background", action="store", dest="background", help="--background count"} +opt.add_option{"-c", "--cgibin", action="store", dest="cgibin", help="--cgibin bin"} +opt.add_option{"-e", "--dirtyenv", action="store_true", dest="dirtyenv", help="--dirtyenv"} +opt.add_option{"-f", "--foreground", action="store_true", dest="foreground", help="--foreground"} +opt.add_option{"-i", "--bindaddr", action="store", dest="bindaddress", help="--bindaddr address"} +opt.add_option{"-n", "--numeric", action="store_true", dest="numeric", help="--numeric"} +opt.add_option{"-p", "--public-html", action="store", dest="public_html", help="--public-html dir"} +opt.add_option{"-r", "--trusted-referal", action="store_true", dest="trustedref", help="trusted referal"} +opt.add_option{"-s", "--logtostderr", action="store_true", dest="logstderr", help="log to stderr"} +opt.add_option{"-t", "--chroot", action="store", dest="chroot", help="--chroot dir"} +opt.add_option{"-u", "--enable-users", action="store_true", dest="enableusers", help="--enable-users"} +opt.add_option{"-v", "--virtbase", action="store", dest="virtbase", help="virtual base location"} +opt.add_option{"-x", "--index-html", action="store", dest="indexhtml", help="index.html name"} + +-- caller lua script +local extension = ".so" +f = io.open("libluabozohttpd.dylib", "r") +if f then + extension = ".dylib" + io.close(f) +end +glupkg = package.loadlib("./" .. "libluabozohttpd" .. extension, "luaopen_bozohttpd") +bozohttpd = glupkg() + +-- initialise +httpd = bozohttpd.new() +bozohttpd.init_httpd(httpd) +prefs = bozohttpd.init_prefs() + +-- parse command line args +options,args = opt.parse_args() +if options.portnum then + bozohttpd.set_pref(prefs, "port number", options.portnum) +end +if options.background then + bozohttpd.set_pref(prefs, "background", options.background) +end +if options.numeric then + bozohttpd.set_pref(prefs, "numeric", "true") +end +if options.logstderr then + bozohttpd.set_pref(prefs, "log to stderr", "true") +end +if options.foreground then + bozohttpd.set_pref(prefs, "foreground", "true") +end +if options.trustedref then + bozohttpd.set_pref(prefs, "trusted referal", "true") +end +if options.dynmime then + suffix, type, s1, s2 = string.find(options.dynmime, + "(%S+)%s+(%S+)%s+(%S+)%s+(%S+)") + bozohttpd.dynamic_mime(httpd, suffix, type, s1, s2) +end +if options.serversw then + bozohttpd.set_pref(prefs, "server software", options.serversw) +end +if options.ssl then + cert, priv = string.find(options.ssl, "(%S+)%s+(%S+)") + bozohttpd.dynamic_mime(httpd, cert, priv) +end +if options.username then + bozohttpd.set_pref(prefs, "username", options.username) +end +if options.unknownslash then + bozohttpd.set_pref(prefs, "unknown slash", "true") +end +if options.virtbase then + bozohttpd.set_pref(prefs, "virtual base", options.virtbase) +end +if options.indexhtml then + bozohttpd.set_pref(prefs, "index.html", options.indexhtml) +end +if options.dirtyenv then + bozohttpd.set_pref(prefs, "dirty environment", "true") +end +if options.bindaddr then + bozohttpd.set_pref(prefs, "bind address", options.bindaddr) +end +if options.cgibin then + bozohttpd.cgi_setbin(httpd, options.cgibin) +end +if options.cgimap then + name, handler = string.find(options.cgimap, "(%S+)%s+(%S+)") + bozohttpd.cgi_map(httpd, name, handler) +end +if options.public_html then + bozohttpd.set_pref(prefs, "public_html", options.public_html) +end +if options.chroot then + bozohttpd.set_pref(prefs, "chroot dir", options.chroot) +end +if options.enableusers then + bozohttpd.set_pref(prefs, "enable users", "true") +end +if options.hidedots then + bozohttpd.set_pref(prefs, "hide dots", "true") +end +if options.dirindex then + bozohttpd.set_pref(prefs, "directory indexing", "true") +end + +if #args < 1 then + print("At least one arg needed for root directory") +else + -- set up connections + local vhost = args[2] or "" + bozohttpd.setup(httpd, prefs, vhost, args[1]) + + -- loop, serving requests + local numreps = options.background or 0 + repeat + req = bozohttpd.read_request(httpd) + bozohttpd.process_request(httpd, req) + bozohttpd.clean_request(req) + until numreps == 0 +end diff --git a/libexec/httpd/lua/glue.c b/libexec/httpd/lua/glue.c new file mode 100644 index 00000000000..cad53b8e32c --- /dev/null +++ b/libexec/httpd/lua/glue.c @@ -0,0 +1,276 @@ +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Alistair Crooks (agc@netbsd.org) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/types.h> +#include <sys/param.h> +#include <sys/stat.h> + +#include <bozohttpd.h> +#include <inttypes.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#define LUA_LIB +#include <lua.h> +#include <lauxlib.h> +#include <lualib.h> + +#ifndef __UNCONST +#define __UNCONST(a) ((void *)(unsigned long)(const void *)(a)) +#endif /* !__UNCONST */ + +int luaopen_bozohttpd(lua_State *); + +#if 0 +typedef struct strarg_t { + const char *s; /* string */ + const int n; /* corresponding int value */ +} strarg_t; + +/* map a string onto an int */ +static int +findtype(strarg_t *strs, const char *s) +{ + strarg_t *sp; + + for (sp = strs ; sp->s && strcasecmp(sp->s, s) != 0 ; sp++) { + } + return sp->n; +} +#endif + +/* init() */ +static int +l_new(lua_State *L) +{ + bozohttpd_t *httpd; + + httpd = lua_newuserdata(L, sizeof(*httpd)); + (void) memset(httpd, 0x0, sizeof(*httpd)); + return 1; +} + +/* initialise(httpd) */ +static int +l_init_httpd(lua_State *L) +{ + bozohttpd_t *httpd; + + httpd = lua_touserdata(L, 1); + lua_pushnumber(L, bozo_init_httpd(httpd)); + return 1; +} + +/* initialise(prefs) */ +static int +l_init_prefs(lua_State *L) +{ + bozoprefs_t *prefs; + + prefs = lua_newuserdata(L, sizeof(*prefs)); + (void) memset(prefs, 0x0, sizeof(*prefs)); + (void) bozo_init_prefs(prefs); + return 1; +} + +/* bozo_set_pref(prefs, name, value) */ +static int +l_bozo_set_pref(lua_State *L) +{ + bozoprefs_t *prefs; + const char *name; + const char *value; + + prefs = lua_touserdata(L, 1); + name = luaL_checkstring(L, 2); + value = luaL_checkstring(L, 3); + lua_pushnumber(L, bozo_set_pref(prefs, name, value)); + return 1; +} + +/* bozo_get_pref(prefs, name) */ +static int +l_bozo_get_pref(lua_State *L) +{ + bozoprefs_t *prefs; + const char *name; + + prefs = lua_touserdata(L, 1); + name = luaL_checkstring(L, 2); + lua_pushstring(L, bozo_get_pref(prefs, name)); + return 1; +} + +/* bozo_setup(httpd, prefs, host, root) */ +static int +l_bozo_setup(lua_State *L) +{ + bozohttpd_t *httpd; + bozoprefs_t *prefs; + const char *vhost; + const char *root; + + httpd = lua_touserdata(L, 1); + prefs = lua_touserdata(L, 2); + vhost = luaL_checkstring(L, 3); + if (vhost && *vhost == 0x0) { + vhost = NULL; + } + root = luaL_checkstring(L, 4); + lua_pushnumber(L, bozo_setup(httpd, prefs, vhost, root)); + return 1; +} + +/* bozo_read_request(httpd) */ +static int +l_bozo_read_request(lua_State *L) +{ + bozo_httpreq_t *req; + bozohttpd_t *httpd; + + httpd = lua_touserdata(L, 1); + req = bozo_read_request(httpd); + lua_pushlightuserdata(L, req); + return 1; +} + +/* bozo_process_request(httpd, req) */ +static int +l_bozo_process_request(lua_State *L) +{ + bozo_httpreq_t *req; + bozohttpd_t *httpd; + + httpd = lua_touserdata(L, 1); + req = lua_touserdata(L, 2); + bozo_process_request(httpd, req); + lua_pushnumber(L, 1); + return 1; +} + +/* bozo_clean_request(req) */ +static int +l_bozo_clean_request(lua_State *L) +{ + bozo_httpreq_t *req; + + req = lua_touserdata(L, 1); + bozo_clean_request(req); + lua_pushnumber(L, 1); + return 1; +} + +/* dynamic_mime(httpd, one, two, three, four) */ +static int +l_bozo_dynamic_mime(lua_State *L) +{ + bozohttpd_t *httpd; + const char *s[4]; + + httpd = lua_touserdata(L, 1); + s[0] = luaL_checkstring(L, 2); + s[1] = luaL_checkstring(L, 3); + s[2] = luaL_checkstring(L, 4); + s[3] = luaL_checkstring(L, 5); + bozo_add_content_map_mime(httpd, s[0], s[1], s[2], s[3]); + lua_pushnumber(L, 1); + return 1; +} + +/* ssl_set_opts(httpd, one, two) */ +static int +l_bozo_ssl_set_opts(lua_State *L) +{ + bozohttpd_t *httpd; + const char *s[2]; + + httpd = lua_touserdata(L, 1); + s[0] = luaL_checkstring(L, 2); + s[1] = luaL_checkstring(L, 3); + bozo_ssl_set_opts(httpd, s[0], s[1]); + lua_pushnumber(L, 1); + return 1; +} + +/* cgi_setbin(httpd, bin) */ +static int +l_bozo_cgi_setbin(lua_State *L) +{ + bozohttpd_t *httpd; + const char *bin; + + httpd = lua_touserdata(L, 1); + bin = luaL_checkstring(L, 2); + bozo_cgi_setbin(httpd, bin); + lua_pushnumber(L, 1); + return 1; +} + +/* cgi_map(httpd, 1, 2) */ +static int +l_bozo_cgi_map(lua_State *L) +{ + bozohttpd_t *httpd; + const char *s[2]; + + httpd = lua_touserdata(L, 1); + s[0] = luaL_checkstring(L, 2); + s[1] = luaL_checkstring(L, 3); + bozo_add_content_map_cgi(httpd, s[0], s[1]); + lua_pushnumber(L, 1); + return 1; +} + +const struct luaL_reg libluabozohttpd[] = { + { "new", l_new }, + { "init_httpd", l_init_httpd }, + { "init_prefs", l_init_prefs }, + + { "set_pref", l_bozo_set_pref }, + { "get_pref", l_bozo_get_pref }, + { "setup", l_bozo_setup }, + { "dynamic_mime", l_bozo_dynamic_mime }, + { "ssl_set_opts", l_bozo_ssl_set_opts }, + { "cgi_setbin", l_bozo_cgi_setbin }, + { "cgi_map", l_bozo_cgi_map }, + + { "read_request", l_bozo_read_request }, + { "process_request", l_bozo_process_request }, + { "clean_request", l_bozo_clean_request }, + + { NULL, NULL } +}; + +int +luaopen_bozohttpd(lua_State *L) +{ + luaL_openlib(L, "bozohttpd", libluabozohttpd, 0); + return 1; +} diff --git a/libexec/httpd/lua/optparse.lua b/libexec/httpd/lua/optparse.lua new file mode 100644 index 00000000000..da9b62a16cf --- /dev/null +++ b/libexec/httpd/lua/optparse.lua @@ -0,0 +1,123 @@ +-- Lua command line option parser. +-- Interface based on Pythons optparse. +-- http://docs.python.org/lib/module-optparse.html +-- (c) 2008 David Manura, Licensed under the same terms as Lua (MIT license) +-- +-- To be used like this: +-- t={usage="<some usage message>", version="<version string>"} +-- op=OptionParser(t) +-- op=add_option{"<opt>", action=<action>, dest=<dest>, help="<help message for this option>"} +-- +-- with : +-- <opt> the option string to be used (can be anything, if one letter opt, then should be -x val, more letters: -xy=val ) +-- <action> one of +-- - store: store in options as key, val +-- - store_true: stores key, true +-- - store_false: stores key, false +-- <dest> is the key under which the option is saved +-- +-- options,args = op.parse_args() +-- +-- now options is the table of options (key, val) and args is the table with non-option arguments. +-- You can use op.fail(message) for failing and op.print_help() for printing the usage as you like. + +function OptionParser(t) + local usage = t.usage + local version = t.version + + local o = {} + local option_descriptions = {} + local option_of = {} + + function o.fail(s) -- extension + io.stderr:write(s .. '\n') + os.exit(1) + end + + function o.add_option(optdesc) + option_descriptions[#option_descriptions+1] = optdesc + for _,v in ipairs(optdesc) do + option_of[v] = optdesc + end + end + function o.parse_args() + -- expand options (e.g. "--input=file" -> "--input", "file") + local arg = {unpack(arg)} + for i=#arg,1,-1 do local v = arg[i] + local flag, val = v:match('^(%-%-%w+)=(.*)') + if flag then + arg[i] = flag + table.insert(arg, i+1, val) + end + end + + local options = {} + local args = {} + local i = 1 + while i <= #arg do local v = arg[i] + local optdesc = option_of[v] + if optdesc then + local action = optdesc.action + local val + if action == 'store' or action == nil then + i = i + 1 + val = arg[i] + if not val then o.fail('option requires an argument ' .. v) end + elseif action == 'store_true' then + val = true + elseif action == 'store_false' then + val = false + end + options[optdesc.dest] = val + else + if v:match('^%-') then o.fail('invalid option ' .. v) end + args[#args+1] = v + end + i = i + 1 + end + if options.help then + o.print_help() + os.exit() + end + if options.version then + io.stdout:write(t.version .. "\n") + os.exit() + end + return options, args + end + + local function flags_str(optdesc) + local sflags = {} + local action = optdesc.action + for _,flag in ipairs(optdesc) do + local sflagend + if action == nil or action == 'store' then + local metavar = optdesc.metavar or optdesc.dest:upper() + sflagend = #flag == 2 and ' ' .. metavar + or '=' .. metavar + else + sflagend = '' + end + sflags[#sflags+1] = flag .. sflagend + end + return table.concat(sflags, ', ') + end + + function o.print_help() + io.stdout:write("Usage: " .. usage:gsub('%%prog', arg[0]) .. "\n") + io.stdout:write("\n") + io.stdout:write("Options:\n") + for _,optdesc in ipairs(option_descriptions) do + io.stdout:write(" " .. flags_str(optdesc) .. + " " .. optdesc.help .. "\n") + end + end + o.add_option{"--help", action="store_true", dest="help", + help="show this help message and exit"} + if t.version then + o.add_option{"--version", action="store_true", dest="version", + help="output version info."} + end + return o +end + diff --git a/libexec/httpd/lua/shlib_version b/libexec/httpd/lua/shlib_version new file mode 100644 index 00000000000..97c9f92d6b8 --- /dev/null +++ b/libexec/httpd/lua/shlib_version @@ -0,0 +1,2 @@ +major=0 +minor=0 |
