Import NetBSD httpd(8)
Also known as bozohttpd(8). Change-Id: I40e955b5654674f2c708b10e5e403ca9cbc92534
This commit is contained in:
parent
8f957290eb
commit
340f5e5660
|
|
@ -1058,9 +1058,11 @@
|
|||
./usr/libexec minix-base
|
||||
./usr/libexec/atf-check minix-base atf
|
||||
./usr/libexec/blacklistd-helper minix-base
|
||||
./usr/libexec/bozohttpd minix-base
|
||||
./usr/libexec/fingerd minix-base
|
||||
./usr/libexec/ftpd minix-base
|
||||
./usr/libexec/getty minix-base
|
||||
./usr/libexec/httpd minix-base
|
||||
./usr/libexec/kyua-atf-tester minix-base kyua
|
||||
./usr/libexec/kyua-plain-tester minix-base kyua
|
||||
./usr/libexec/ld.elf_so minix-base
|
||||
|
|
@ -3965,3 +3967,4 @@
|
|||
./var/spool/ftp/etc minix-base
|
||||
./var/spool/ftp/hidden minix-base
|
||||
./var/tmp minix-base
|
||||
./var/www minix-base
|
||||
|
|
|
|||
|
|
@ -600,12 +600,14 @@
|
|||
./usr/libdata/debug/usr/lib/libz.so.1.0.debug minix-debug debug
|
||||
./usr/libdata/debug/usr/libexec minix-debug
|
||||
./usr/libdata/debug/usr/libexec/atf-check.debug minix-debug debug
|
||||
./usr/libdata/debug/usr/libexec/bozohttpd.debug minix-debug debug
|
||||
./usr/libdata/debug/usr/libexec/cc1.debug minix-debug gcc=5,gcccmds,debug
|
||||
./usr/libdata/debug/usr/libexec/cc1obj.debug minix-debug gcc=5,gcccmds,debug
|
||||
./usr/libdata/debug/usr/libexec/cc1plus.debug minix-debug gcc=5,gcccmds,debug
|
||||
./usr/libdata/debug/usr/libexec/fingerd.debug minix-debug debug
|
||||
./usr/libdata/debug/usr/libexec/ftpd.debug minix-debug debug
|
||||
./usr/libdata/debug/usr/libexec/getty.debug minix-debug debug
|
||||
./usr/libdata/debug/usr/libexec/httpd.debug minix-debug debug
|
||||
./usr/libdata/debug/usr/libexec/kyua-atf-tester.debug minix-debug debug
|
||||
./usr/libdata/debug/usr/libexec/kyua-plain-tester.debug minix-debug debug
|
||||
./usr/libdata/debug/usr/libexec/ld.elf_so.debug minix-debug debug
|
||||
|
|
|
|||
|
|
@ -3462,6 +3462,7 @@
|
|||
./usr/man/man8/blacklistctl.8 minix-man
|
||||
./usr/man/man8/blacklistd.8 minix-man
|
||||
./usr/man/man8/boot.8 minix-man
|
||||
./usr/man/man8/bozohttpd.8 minix-man
|
||||
./usr/man/man8/btrace.8 minix-man
|
||||
./usr/man/man8/cdprobe.8 minix-man
|
||||
./usr/man/man8/chown.8 minix-man
|
||||
|
|
@ -3501,7 +3502,7 @@
|
|||
./usr/man/man8/groupinfo.8 minix-man
|
||||
./usr/man/man8/groupmod.8 minix-man
|
||||
./usr/man/man8/halt.8 minix-man
|
||||
./usr/man/man8/httpd.8 minix-man obsolete
|
||||
./usr/man/man8/httpd.8 minix-man
|
||||
./usr/man/man8/i2cscan.8 minix-man
|
||||
./usr/man/man8/ifconfig.8 minix-man
|
||||
./usr/man/man8/in.httpd.8 minix-man obsolete
|
||||
|
|
|
|||
|
|
@ -735,6 +735,7 @@
|
|||
./var/spool/ftp/bin
|
||||
./var/spool/ftp/etc
|
||||
./var/spool/ftp/hidden #breaks cd image generation with non-root users: mode=0111
|
||||
./var/www
|
||||
|
||||
# Directories with special access rights
|
||||
/set type=dir uid=0 gid=0 mode=1777
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
.include <bsd.own.mk>
|
||||
|
||||
SUBDIR= \
|
||||
fingerd ftpd getty \
|
||||
fingerd ftpd getty httpd \
|
||||
ld.elf_so \
|
||||
rshd \
|
||||
telnetd
|
||||
|
|
|
|||
275
libexec/httpd/CHANGES
Normal file
275
libexec/httpd/CHANGES
Normal file
|
|
@ -0,0 +1,275 @@
|
|||
$eterna: CHANGES,v 1.78 2011/11/18 01:25:11 mrg Exp $
|
||||
|
||||
changes in bozohttpd 20150320:
|
||||
o fix redirection handling
|
||||
o support transport stream (.ts) and video object (.vob) files
|
||||
o directory listings show correct file sizes for large files
|
||||
|
||||
changes in bozohttpd 20140717:
|
||||
o properly handle SSL errors
|
||||
|
||||
changes in bozohttpd 20140708:
|
||||
o fixes for virtual host support, from rajeev_v_pillai@yahoo.com
|
||||
o avoid printing double errors, from shm@netbsd.org
|
||||
o fix a security issue in basic HTTP authentication which would allow
|
||||
authentication to be bypassed, from shm@netbsd.org
|
||||
|
||||
changes in bozohttpd 20140201:
|
||||
o support .svg files
|
||||
o fix a core dump when requests timeout
|
||||
|
||||
changes in bozohttpd 20140102:
|
||||
o update a few content types
|
||||
o add support for directly calling lua scripts to handle
|
||||
processes, from mbalmer@netbsd.org
|
||||
o properly escape generated HTML
|
||||
o add authentication for redirections, from martin@netbsd.org
|
||||
o handle chained ssl certifications, from elric@netbsd.org
|
||||
o add basic support for gzipped files, from elric@netbsd.org
|
||||
o properly escape generated URIs
|
||||
|
||||
changes in bozohttpd 20111118:
|
||||
o add -P <pidfile> option, from jmmv@netbsd.org
|
||||
o avoid crashes with http basic auth, from pooka@netbsd.org
|
||||
o add support for REDIRECT_STATUS variable, from tls@netbsd.org
|
||||
o support .mp4 files in the default map
|
||||
o directory indexes with files with : are now displayed properly, from
|
||||
reed@netbsd.org
|
||||
o allow -I option to be useful in non-inetd mode as well
|
||||
|
||||
changes in bozohttpd 20100920:
|
||||
o properly fully disable multi-file mode for now
|
||||
o fix the -t and -U options when used without the -e option, broken since
|
||||
the library-ifcation
|
||||
o be explicit that logs go to the FTP facility in syslog
|
||||
o use scandir() with alphasort() for sorted directory lists, from moof
|
||||
o fix a serious error in vhost handling; "Host:.." would allow access to
|
||||
the next level directory from the virtual root directory, from seanb
|
||||
o fix some various non standard compile time errors, from rudolf
|
||||
o fix dynamic CGI content maps, from rudolf
|
||||
|
||||
changes in bozohttpd 20100617:
|
||||
o fix some compile issues
|
||||
o fix SSL mode. from rtr
|
||||
o fix some cgi-bin issues, as seen with cvsweb
|
||||
o disable multi-file daemon mode for now, it breaks
|
||||
o return 404's instead of 403's when chdir of ~user dirs fail
|
||||
o remove "noreturn" attribute from bozo_http_error() that was
|
||||
causing incorrect runtime behaviour
|
||||
|
||||
changes in bozohttpd 20100509:
|
||||
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
|
||||
|
||||
changes in bozohttpd 20090522:
|
||||
o avoid dying in daemon mode for some uncommon, but recoverable, errors
|
||||
o close leaking file descriptors for CGI and daemon mode
|
||||
o handle poll errors properly
|
||||
o don't try to handle more than one request per process yet
|
||||
o add subdirs for build "debug" and "small" versions
|
||||
o clean up a bad merge / duplicate code
|
||||
o make mmap() usage portable, fixes linux & ranges: support
|
||||
o document the -f option
|
||||
o daemon mode now serves 6 files per child
|
||||
|
||||
changes in bozohttpd 20090417:
|
||||
o make bozohttpd internally more modular, preparing the way
|
||||
to handle more than one request per process
|
||||
o fix http-auth, set $REMOTE_USER not $REMOTEUSER. also fix
|
||||
cgi-bin with cvsweb, from Holger Weiss <holger@CIS.FU-Berlin.DE>
|
||||
o fix an uninitialised variable use in daemon mode
|
||||
o fix ssl mode with newer OpenSSL
|
||||
o mmap large files in manageable sizes so we can serve any size file
|
||||
o refactor url processing to handle query strings correctly for CGI
|
||||
from Sergey Katsev at Coyote Point
|
||||
o add If-Modified-Since support, from Joerg Sonnenberger
|
||||
<joerg@netbsd.org>
|
||||
o many more manual fixes, from NetBSD
|
||||
|
||||
changes in bozohttpd 20080303:
|
||||
o fix some cgi header processing, from <thelsdj@gmail.com>
|
||||
o add simple Range: header processing, from <bad@bsd.de>
|
||||
o man page fixes, from NetBSD
|
||||
o clean up various parts, from NetBSD
|
||||
|
||||
changes in bozohttpd 20060710:
|
||||
o prefix some function names with "bozo"
|
||||
o align directory indexing <hr> markers
|
||||
o clean up some code GCC4 grumbled about
|
||||
|
||||
changes in bozohttpd 20060517:
|
||||
o don't allow "/.." or "../" files
|
||||
o don't write ":80" into urls for the http port
|
||||
o fix a fd leak when fork() fails
|
||||
o make directory indexing mode not look so ugly
|
||||
o build a text version of the manual page
|
||||
o make "make clean" work properly
|
||||
|
||||
changes in bozohttpd 20050410:
|
||||
o fix some off-by-one errors from <roland.illig@gmx.de>
|
||||
o properly support nph- CGI
|
||||
o make content maps case insensitive
|
||||
o fix proto header merging to include the missing comma
|
||||
o major source reorganisation; most features are in separate files now
|
||||
o new -V flag that makes unknown virtualhosts use slashdir
|
||||
from <rumble@ephemeral.org>
|
||||
o HTTP/1.x protocol headers are now properly merged for CGI
|
||||
|
||||
changes in bozohttpd 20040808:
|
||||
o CGI status is now properly handled (-a flag has been removed)
|
||||
o CGI file upload support works
|
||||
o %xy translations are no longer ever applied after the first '?',
|
||||
ala RFC2396. from lukem
|
||||
o daemon mode (-b) should no longer hang spinning forever if it
|
||||
sees no children. from lukem
|
||||
o new .bzabsredirect file support. from <martin@netbsd.org>
|
||||
o return a 404 error if we see %00 or %2f (/)
|
||||
o don't print 2 "200" headers for CGI
|
||||
o support .torrent files
|
||||
|
||||
changes in bozohttpd 20040218:
|
||||
o new .bzredirect file support for sane directory redirection
|
||||
o new -Z option that enables SSL mode, from <rtr@eterna.com.au>
|
||||
o the -C option has been changed to take two explicit options, rather
|
||||
than a single option with a space separating the suffix and the
|
||||
interpreter. ``-C ".foo /path/to/bar"'' should now be written
|
||||
as ``-C .foo /path/to/bar''
|
||||
o the -M option has been changed like -C and no longer requires or
|
||||
supports a single argument with space-separated options
|
||||
o with -a, still print the 200 OK. from <rtr@eterna.com.au>
|
||||
o with -r, if a .bzdirect file appears in a directory, allow direct
|
||||
access to this directory
|
||||
|
||||
changes in bozohttpd 20031005:
|
||||
o fixes for basic authorisation. from <ecu@ipv42.net>
|
||||
o always display file size in directory index mode
|
||||
o add .xbel, .xml & .xsl -> text/xml mappings. from
|
||||
<wiz@danbala.ifoer.tuwien.ac.at>
|
||||
|
||||
changes in bozohttpd 20030626:
|
||||
o fix a recent core dump when given no input
|
||||
o add new -r flag that ensures referrer is set to this host
|
||||
o fix several compile time errors with -DNO_CGIBIN_SUPPORT
|
||||
o fix some man page details. from lukem@wasabisystems.com
|
||||
o re-add a missing memset(), fixing a core dump. from lukem
|
||||
o support HTTP basic authorisation, disabled by default. from lukem
|
||||
o print the port number in redirects and errors. from lukem
|
||||
o only syslog the basename of the program. from lukem
|
||||
o add __attribute__() format checking. from lukem
|
||||
o fix cgibin SCRIPT_NAME to have a leading /. from zakj@nox.cx
|
||||
o simplify some code in -C to avoid a core dump. from lukem
|
||||
o add a .css -> css/text entry to the content_map[]. from zakj@nox.cx
|
||||
|
||||
changes in bozohttpd 20030409:
|
||||
o -d without DEBUG enabled only prints one warning and continues
|
||||
o one can now define the C macro SERVER_SOFTWARE when building to
|
||||
change the Server: header and CGI variable of the same name
|
||||
o add new -s flag the force logging output to stderr. from zakj@nox.cx
|
||||
o add new -a flag for CGI bin that stops bozohttpd from outputting
|
||||
any HTTP reply, the CGI program must output these. from zakj@nox.cx
|
||||
o new REQUEST_URI and DATE_GMT environment variables for CGI. from
|
||||
zakj@nox.cx
|
||||
o add a "Makefile.boot" that should work with any make program
|
||||
o build on linux again
|
||||
o fix core dumps when using -C
|
||||
|
||||
changes in bozohttpd 20030313:
|
||||
o deprecate -r flag; make this the default and silently ignore -r now
|
||||
o add support for file extentions to call CGI programs (from lukem)
|
||||
o add dynamic support to add new content map entries, allowing both
|
||||
new file types and non /cgi-bin CGI programs to be run with the
|
||||
new -C "suffix cgihandler" and -M "suffix type encoding encoding11"
|
||||
options
|
||||
o in -b mode, set the http date after accept() returns, not before we
|
||||
call accept()
|
||||
o in -b mode, bind all addresses found not just the first one
|
||||
o unsupport old hostname API
|
||||
o in -b mode, set the SO_REUSEADDR socket option (lukem)
|
||||
o allow -x (index.html) mode to work with CGI handlers
|
||||
|
||||
changes in bozohttpd 20021106:
|
||||
o add .bz2 support
|
||||
o properly escape <, > and & in error messages, partly from
|
||||
Nicolas Jombart <ecu@mariejeanne.net>
|
||||
o new -H flag to hide .* files in directory index mode
|
||||
o fix buffer reallocation when parsing a request, to avoid
|
||||
overflowing the buffer with carriage returns (\r)
|
||||
o do not decode "%XY"-style cgi-bin data beyond the "?"
|
||||
|
||||
changes in bozohttpd 5.15 (20020913):
|
||||
o add .ogg support -> `application/x-ogg'
|
||||
o fix CGI requests with "/" in the query part
|
||||
|
||||
changes in bozohttpd 5.14 (20020823):
|
||||
o allow -X mode to work for "/"
|
||||
o work on systems without MADV_SEQUENTIAL
|
||||
o make a local cut-down copy of "queue.h" (fixes linux & solaris
|
||||
support at the very least)
|
||||
o portability fixes for pre-ipv6 socket api systems (eg, solaris 7)
|
||||
o portability fixes for missing _PATH_DEFPATH, LOG_FTP and __progname
|
||||
o better documentation on virtual host support
|
||||
|
||||
changes in bozohttpd 5.13 (20020804):
|
||||
o support .mp3 files (type audio/mpeg)
|
||||
o use stat() to find out if something is a directory, for -X mode
|
||||
|
||||
changes in bozohttpd 5.12 (20020803):
|
||||
o constification
|
||||
o fixes & enhancements for directory index mode (-X)
|
||||
|
||||
changes in bozohttpd 5.11 (20020730):
|
||||
o more man page fixes from Thomas Klausner
|
||||
<wiz@danbala.ifoer.tuwien.ac.at>
|
||||
o de-K&R C-ification
|
||||
o fix Date: header for daemon mode
|
||||
o fix core dump when asking for /cgi-bin/ when CGI isn't configured
|
||||
o use a valid Server: header
|
||||
|
||||
changes in bozohttpd 5.10 (20020710):
|
||||
- add freebsd support
|
||||
- fix a couple of header typos
|
||||
- many cgi-bin fixes from lukem@netbsd.org
|
||||
- add -T chrootdir and -U user, plus several minor other cleanups
|
||||
with signals and return values. from xs@kittenz.org
|
||||
- add -e that does not clear the environment for -T/-U
|
||||
- fix a formatting error noticed by ISIHARA Takanori <ishit@oak.dti.ne.jp>
|
||||
|
||||
changes in bozohttpd 5.09 (20010922):
|
||||
- add a daemon mode
|
||||
- document how to use bozohttpd in netbsd inetd with more than 40
|
||||
connections per minute and also with cgibin
|
||||
- man page fixes from wiz@netbsd.org
|
||||
|
||||
changes in bozohttpd 5.08 (20010812):
|
||||
- add directory index generation support (-X) from ad@netbsd.org
|
||||
- add .pa as an alias for .pac
|
||||
- make server software version configurable (RFC)
|
||||
|
||||
changes in bozohttpd 5.07 (20010610):
|
||||
- add .png support
|
||||
- new "-x index.html" flag to change default file
|
||||
- new "-p public_html" flag to change default ~user directory
|
||||
- fixes cgi-bin support and more from chuck@research.att.com
|
||||
- add many new content-types, now support most common ones
|
||||
|
||||
changes in bozohttpd 5.06 (20000825):
|
||||
- add IPv6 suppor from itojun@iijlab.net
|
||||
- man page fixes from jlam@netbsd.org
|
||||
|
||||
changes in bozohttpd 5.05 (20000815):
|
||||
- fix a virtual host bug, from kleink@netbsd.org
|
||||
|
||||
changes in bozohttpd 5.04 (20000427):
|
||||
- fix virtual host support; URI takes precedence over Host:
|
||||
|
||||
changes in bozohttpd 5.03 (20000427):
|
||||
- fix a bug with chdir()
|
||||
|
||||
changes in bozohttpd 5.02 (20000426):
|
||||
- .pac spport from simonb
|
||||
|
||||
changes in bozohttpd 5.01 (20000421):
|
||||
- .swf support
|
||||
- virtual hosting support
|
||||
108
libexec/httpd/Makefile
Normal file
108
libexec/httpd/Makefile
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
# $NetBSD: Makefile,v 1.24 2015/08/05 06:50:44 mrg Exp $
|
||||
#
|
||||
# $eterna: Makefile,v 1.30 2010/07/11 00:34:27 mrg Exp $
|
||||
#
|
||||
# berkeley (netbsd) makefile. see Makefile.boot for other systems.
|
||||
|
||||
# compile-time options are:
|
||||
# NO_DEBUG /* don't include debugging support */
|
||||
# NO_USER_SUPPORT /* don't support /~user requests */
|
||||
# NO_CGIBIN_SUPPORT /* don't support cgi-bin requests */
|
||||
# NO_DIRINDEX_SUPPORT /* don't support directory indexing */
|
||||
# NO_DAEMON_MODE /* don't support daemon mode */
|
||||
# NO_DYNAMIC_CONTENT /* don't support dynamic content updates */
|
||||
# NO_SSL_SUPPORT /* don't support ssl (https) */
|
||||
# DO_HTPASSWD /* support .htpasswd files */
|
||||
# NO_LUA_SUPPORT /* don't support Lua for dynamic content */
|
||||
#
|
||||
# other system specific defines:
|
||||
# HAVE_NBUTIL_H /* netbsd compat is in <nbutil.h>
|
||||
# (don't forget to also enable -lnbutil)
|
||||
#
|
||||
# these are usually set via the "COPTS" variable, or some other method
|
||||
# for setting CFLAGS relevant to your make, eg
|
||||
# % make COPTS="-DDO_HTPASSWD"
|
||||
|
||||
COPTS+= -DDO_HTPASSWD
|
||||
PROG= bozohttpd
|
||||
LINKS= ${BINDIR}/bozohttpd ${BINDIR}/httpd
|
||||
MAN= bozohttpd.8
|
||||
MLINKS+=bozohttpd.8 httpd.8
|
||||
SRCS= bozohttpd.c ssl-bozo.c auth-bozo.c cgi-bozo.c daemon-bozo.c \
|
||||
tilde-luzah-bozo.c dir-index-bozo.c content-bozo.c lua-bozo.c
|
||||
SRCS+= main.c
|
||||
|
||||
LDADD= -lcrypt -llua -lm
|
||||
DPADD= ${LIBCRYPT} ${LIBLUA} ${LIBM}
|
||||
|
||||
WARNS?= 4
|
||||
|
||||
.if defined(.OS.MAKE)
|
||||
OPSYS= ${.OS.MAKE}
|
||||
.else
|
||||
OPSYS:= ${:!uname -s!:S/-//g:S/\///g}
|
||||
.endif
|
||||
|
||||
.if ${OPSYS} == "QNX"
|
||||
CPPFLAGS+= -DHAVE_NBUTIL_H
|
||||
LDADD+= -lnbutil
|
||||
.endif
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
.if ${MKCRYPTO} != "no"
|
||||
|
||||
LDADD+= -lssl -lcrypto
|
||||
DPADD+= ${LIBSSL} ${LIBCRYPTO}
|
||||
|
||||
.else
|
||||
|
||||
COPTS+= -DNO_SSL_SUPPORT
|
||||
|
||||
.endif
|
||||
|
||||
#
|
||||
# Build release things.
|
||||
#
|
||||
NROFF?= nroff
|
||||
|
||||
PREHTMLFROB= sed \
|
||||
-e 's/&/\&/' \
|
||||
-e 's/</\</' \
|
||||
-e 's/>/\>/'
|
||||
|
||||
HTMLFROB= sed \
|
||||
-e 's/\([MC] "[^"]*\)<dd>$$/\1<b>"<\/b><dd>/' \
|
||||
-e 's/'"''"'/\”/' \
|
||||
-e 's/""/\“/' \
|
||||
-e 's/<a href="\.\.\/html[^>]*>\(.*\)<\/a>/\1/'
|
||||
|
||||
TXTFROB= col -b
|
||||
|
||||
bozohttpd.8.html: bozohttpd.8
|
||||
$(PREHTMLFROB) $> | $(NROFF) -mdoc2html | $(HTMLFROB) > $@
|
||||
|
||||
bozohttpd.8.txt: bozohttpd.8
|
||||
$(NROFF) -mdoc -Tascii $> | $(TXTFROB) > $@
|
||||
|
||||
CLEANFILES+= bozohttpd.8.html bozohttpd.8.txt
|
||||
|
||||
# Create a distfile: uses /tmp
|
||||
BASE=bozohttpd-${BOZOVER}
|
||||
TAR=${BASE}.tar
|
||||
export-distfile:
|
||||
dir=`mktemp -d /tmp/bozo-export-XXXXXX`; \
|
||||
cd "$${dir}" || exit; \
|
||||
mkdir ${BASE}; \
|
||||
( cd ${BASE} || exit; \
|
||||
cp -r "${.CURDIR}/." "."; \
|
||||
find . -name .CVS | xargs rm -r; \
|
||||
); \
|
||||
pax -wf ${TAR} ${BASE}; \
|
||||
gzip -nc9 ${TAR} > ${TAR}.gz; \
|
||||
bzip2 -9 ${TAR}; \
|
||||
echo "Exported two files in $${dir}:"; \
|
||||
echo ${TAR}.gz; \
|
||||
echo ${TAR}.bz2
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
26
libexec/httpd/Makefile.boot
Normal file
26
libexec/httpd/Makefile.boot
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# $eterna: Makefile.boot,v 1.9 2010/05/10 04:57:50 mrg Exp $
|
||||
#
|
||||
# very simple makefile to compile bozohttpd, should work with every make.
|
||||
# see Makefile for a list of compile options that may be placed in CFLAGS.
|
||||
|
||||
CC= cc
|
||||
OPT= -O
|
||||
LARGE_CFLAGS= -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
|
||||
LOCAL_CFLAGS= -DNO_LUA_SUPPORT
|
||||
CFLAGS= $(OPT) $(LARGE_CFLAGS) $(LOCAL_CFLAGS)
|
||||
|
||||
GROFF= groff -Tascii
|
||||
CRYPTOLIBDIR= # -L/usr/local/lib
|
||||
CRYPTOLIBS= $(CRYPTOLIBDIR) -lcrypto -lssl
|
||||
|
||||
FILES= bozohttpd.c auth-bozo.c cgi-bozo.c content-bozo.c daemon-bozo.c \
|
||||
dir-index-bozo.c lua-bozo.c ssl-bozo.c tilde-luzah-bozo.c main.c
|
||||
|
||||
all:
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o bozohttpd $(FILES) $(CRYPTOLIBS)
|
||||
|
||||
man:
|
||||
$(GROFF) -mandoc bozohttpd.8 > bozohttpd.cat8
|
||||
|
||||
clean:
|
||||
rm -f bozohttpd bozohttpd.cat8 *.o
|
||||
272
libexec/httpd/auth-bozo.c
Normal file
272
libexec/httpd/auth-bozo.c
Normal file
|
|
@ -0,0 +1,272 @@
|
|||
/* $NetBSD: auth-bozo.c,v 1.16 2014/12/26 19:52:00 mrg Exp $ */
|
||||
|
||||
/* $eterna: auth-bozo.c,v 1.17 2011/11/18 09:21:15 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997-2014 Matthew R. Green
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 and
|
||||
* dedication in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* this code implements "http basic authorisation" for bozohttpd */
|
||||
|
||||
#ifdef DO_HTPASSWD
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "bozohttpd.h"
|
||||
|
||||
#ifndef AUTH_FILE
|
||||
#define AUTH_FILE ".htpasswd"
|
||||
#endif
|
||||
|
||||
static ssize_t base64_decode(const unsigned char *, size_t,
|
||||
unsigned char *, size_t);
|
||||
|
||||
/*
|
||||
* Check if HTTP authentication is required
|
||||
*/
|
||||
int
|
||||
bozo_auth_check(bozo_httpreq_t *request, const char *file)
|
||||
{
|
||||
bozohttpd_t *httpd = request->hr_httpd;
|
||||
struct stat sb;
|
||||
char dir[MAXPATHLEN], authfile[MAXPATHLEN], *basename;
|
||||
char user[BUFSIZ], *pass;
|
||||
FILE *fp;
|
||||
int len;
|
||||
|
||||
/* get dir=dirname(file) */
|
||||
snprintf(dir, sizeof(dir), "%s", file);
|
||||
if ((basename = strrchr(dir, '/')) == NULL)
|
||||
strcpy(dir, ".");
|
||||
else {
|
||||
*basename++ = '\0';
|
||||
/* ensure basename(file) != AUTH_FILE */
|
||||
if (bozo_check_special_files(request, basename))
|
||||
return 1;
|
||||
}
|
||||
request->hr_authrealm = bozostrdup(httpd, dir);
|
||||
|
||||
if ((size_t)snprintf(authfile, sizeof(authfile), "%s/%s", dir, AUTH_FILE) >=
|
||||
sizeof(authfile)) {
|
||||
return bozo_http_error(httpd, 404, request,
|
||||
"authfile path too long");
|
||||
}
|
||||
if (stat(authfile, &sb) < 0) {
|
||||
debug((httpd, DEBUG_NORMAL,
|
||||
"bozo_auth_check realm `%s' dir `%s' authfile `%s' missing",
|
||||
dir, file, authfile));
|
||||
return 0;
|
||||
}
|
||||
if ((fp = fopen(authfile, "r")) == NULL)
|
||||
return bozo_http_error(httpd, 403, request,
|
||||
"no permission to open authfile");
|
||||
debug((httpd, DEBUG_NORMAL,
|
||||
"bozo_auth_check realm `%s' dir `%s' authfile `%s' open",
|
||||
dir, file, authfile));
|
||||
if (request->hr_authuser && request->hr_authpass) {
|
||||
while (fgets(user, sizeof(user), fp) != NULL) {
|
||||
len = strlen(user);
|
||||
if (len > 0 && user[len-1] == '\n')
|
||||
user[--len] = '\0';
|
||||
if ((pass = strchr(user, ':')) == NULL)
|
||||
continue;
|
||||
*pass++ = '\0';
|
||||
debug((httpd, DEBUG_NORMAL,
|
||||
"bozo_auth_check authfile `%s':`%s' "
|
||||
"client `%s':`%s'",
|
||||
user, pass, request->hr_authuser,
|
||||
request->hr_authpass));
|
||||
if (strcmp(request->hr_authuser, user) != 0)
|
||||
continue;
|
||||
if (strcmp(crypt(request->hr_authpass, pass),
|
||||
pass) != 0)
|
||||
break;
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
return bozo_http_error(httpd, 401, request, "bad auth");
|
||||
}
|
||||
|
||||
void
|
||||
bozo_auth_init(bozo_httpreq_t *request)
|
||||
{
|
||||
request->hr_authuser = NULL;
|
||||
request->hr_authpass = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
bozo_auth_cleanup(bozo_httpreq_t *request)
|
||||
{
|
||||
|
||||
if (request == NULL)
|
||||
return;
|
||||
free(request->hr_authuser);
|
||||
free(request->hr_authpass);
|
||||
free(request->hr_authrealm);
|
||||
}
|
||||
|
||||
int
|
||||
bozo_auth_check_headers(bozo_httpreq_t *request, char *val, char *str, ssize_t len)
|
||||
{
|
||||
bozohttpd_t *httpd = request->hr_httpd;
|
||||
|
||||
if (strcasecmp(val, "authorization") == 0 &&
|
||||
strncasecmp(str, "Basic ", 6) == 0) {
|
||||
char authbuf[BUFSIZ];
|
||||
char *pass = NULL;
|
||||
ssize_t alen;
|
||||
|
||||
alen = base64_decode((unsigned char *)str + 6,
|
||||
(size_t)(len - 6),
|
||||
(unsigned char *)authbuf,
|
||||
sizeof(authbuf) - 1);
|
||||
if (alen != -1)
|
||||
authbuf[alen] = '\0';
|
||||
if (alen == -1 ||
|
||||
(pass = strchr(authbuf, ':')) == NULL)
|
||||
return bozo_http_error(httpd, 400, request,
|
||||
"bad authorization field");
|
||||
*pass++ = '\0';
|
||||
free(request->hr_authuser);
|
||||
free(request->hr_authpass);
|
||||
request->hr_authuser = bozostrdup(httpd, authbuf);
|
||||
request->hr_authpass = bozostrdup(httpd, pass);
|
||||
debug((httpd, DEBUG_FAT,
|
||||
"decoded authorization `%s' as `%s':`%s'",
|
||||
str, request->hr_authuser, request->hr_authpass));
|
||||
/* don't store in request->headers */
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bozo_auth_check_special_files(bozo_httpreq_t *request,
|
||||
const char *name)
|
||||
{
|
||||
bozohttpd_t *httpd = request->hr_httpd;
|
||||
|
||||
if (strcmp(name, AUTH_FILE) == 0)
|
||||
return bozo_http_error(httpd, 403, request,
|
||||
"no permission to open authfile");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
bozo_auth_check_401(bozo_httpreq_t *request, int code)
|
||||
{
|
||||
bozohttpd_t *httpd = request->hr_httpd;
|
||||
|
||||
if (code == 401)
|
||||
bozo_printf(httpd,
|
||||
"WWW-Authenticate: Basic realm=\"%s\"\r\n",
|
||||
(request && request->hr_authrealm) ?
|
||||
request->hr_authrealm : "default realm");
|
||||
}
|
||||
|
||||
#ifndef NO_CGIBIN_SUPPORT
|
||||
void
|
||||
bozo_auth_cgi_setenv(bozo_httpreq_t *request,
|
||||
char ***curenvpp)
|
||||
{
|
||||
bozohttpd_t *httpd = request->hr_httpd;
|
||||
|
||||
if (request->hr_authuser && *request->hr_authuser) {
|
||||
bozo_setenv(httpd, "AUTH_TYPE", "Basic", (*curenvpp)++);
|
||||
bozo_setenv(httpd, "REMOTE_USER", request->hr_authuser,
|
||||
(*curenvpp)++);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
bozo_auth_cgi_count(bozo_httpreq_t *request)
|
||||
{
|
||||
return (request->hr_authuser && *request->hr_authuser) ? 2 : 0;
|
||||
}
|
||||
#endif /* NO_CGIBIN_SUPPORT */
|
||||
|
||||
/*
|
||||
* Decode len bytes starting at in using base64 encoding into out.
|
||||
* Result is *not* NUL terminated.
|
||||
* Written by Luke Mewburn <lukem@NetBSD.org>
|
||||
*/
|
||||
const unsigned char decodetable[] = {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 0, 255, 255,
|
||||
255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
|
||||
255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255,
|
||||
};
|
||||
|
||||
static ssize_t
|
||||
base64_decode(const unsigned char *in, size_t ilen, unsigned char *out,
|
||||
size_t olen)
|
||||
{
|
||||
unsigned char *cp;
|
||||
size_t i;
|
||||
|
||||
if (ilen == 0) {
|
||||
if (olen)
|
||||
*out = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
cp = out;
|
||||
for (i = 0; i < ilen; i += 4) {
|
||||
if (cp + 3 > out + olen)
|
||||
return (-1);
|
||||
#define IN_CHECK(x) \
|
||||
if ((x) > sizeof(decodetable) || decodetable[(x)] == 255) \
|
||||
return(-1)
|
||||
|
||||
IN_CHECK(in[i + 0]);
|
||||
/*LINTED*/
|
||||
*(cp++) = decodetable[in[i + 0]] << 2
|
||||
| decodetable[in[i + 1]] >> 4;
|
||||
IN_CHECK(in[i + 1]);
|
||||
/*LINTED*/
|
||||
*(cp++) = decodetable[in[i + 1]] << 4
|
||||
| decodetable[in[i + 2]] >> 2;
|
||||
IN_CHECK(in[i + 2]);
|
||||
*(cp++) = decodetable[in[i + 2]] << 6
|
||||
| decodetable[in[i + 3]];
|
||||
#undef IN_CHECK
|
||||
}
|
||||
while (i > 0 && in[i - 1] == '=')
|
||||
cp--,i--;
|
||||
return (cp - out);
|
||||
}
|
||||
#endif /* DO_HTPASSWD */
|
||||
683
libexec/httpd/bozohttpd.8
Normal file
683
libexec/httpd/bozohttpd.8
Normal file
|
|
@ -0,0 +1,683 @@
|
|||
.\" $NetBSD: bozohttpd.8,v 1.53 2015/08/13 12:30:08 wiz Exp $
|
||||
.\"
|
||||
.\" $eterna: bozohttpd.8,v 1.101 2011/11/18 01:25:11 mrg Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1997-2015 Matthew R. Green
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" 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 AUTHOR ``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 AUTHOR 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.
|
||||
.\"
|
||||
.Dd May 1, 2015
|
||||
.Dt BOZOHTTPD 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm bozohttpd
|
||||
.Nd hyper text transfer protocol version 1.1 daemon
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl CIMPSZciptvx
|
||||
.Op Fl C Ar suffix cgihandler
|
||||
.Op Fl I Ar port
|
||||
.Op Fl L Ar prefix script
|
||||
.Op Fl M Ar suffix type encoding encoding11
|
||||
.Op Fl P Ar pidfile
|
||||
.Op Fl S Ar server_software
|
||||
.Op Fl Z Ar cert privkey
|
||||
.Op Fl c Ar cgibin
|
||||
.Op Fl i Ar address
|
||||
.Op Fl p Ar pubdir
|
||||
.Op Fl t Ar chrootdir
|
||||
.Op Fl v Ar virtualroot
|
||||
.Op Fl x Ar index
|
||||
.Ar slashdir
|
||||
.Op Ar myname
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
program reads a
|
||||
.Em HTTP
|
||||
request from the standard input, and sends a reply to the standard output.
|
||||
Besides ~user translation and virtual hosting support (see below), all file
|
||||
requests are from
|
||||
.Ar slashdir
|
||||
directory.
|
||||
The server uses
|
||||
.Ar myname
|
||||
as its name, which defaults to the local hostname, obtained from
|
||||
.Xr gethostname 3
|
||||
(but see the
|
||||
.Fl v
|
||||
option for virtual hosting.)
|
||||
.Nm
|
||||
writes logs to
|
||||
.Xr syslog 3
|
||||
using the ftp facility (but see the
|
||||
.Fl s
|
||||
option for testing.)
|
||||
.Nm
|
||||
is designed to be small, simple and relatively featureless,
|
||||
hopefully increasing its security.
|
||||
.Ss OPTIONS
|
||||
The following options are available:
|
||||
.Bl -tag -width xxxcgibin
|
||||
.It Fl b
|
||||
Enables daemon mode, where
|
||||
.Nm
|
||||
detaches from the current terminal, running in the background and
|
||||
servicing HTTP requests.
|
||||
.It Fl C Ar suffix cgihandler
|
||||
Adds a new CGI handler program for a particular file type.
|
||||
The
|
||||
.Ar suffix
|
||||
should be any normal file suffix, and the
|
||||
.Ar cgihandler
|
||||
should be a full path to an interpreter.
|
||||
This option is the only way to enable CGI programs that exist
|
||||
outside of the cgibin directory to be executed.
|
||||
Multiple
|
||||
.Fl C
|
||||
options may be passed.
|
||||
.It Fl c Ar cgibin
|
||||
Enables the CGI/1.1 interface.
|
||||
The
|
||||
.Ar cgibin
|
||||
directory is expected to contain the CGI programs to be used.
|
||||
.Nm
|
||||
looks for URL's in the form of
|
||||
.Em /cgi-bin/\*[Lt]scriptname\*[Gt]
|
||||
where
|
||||
.Aq scriptname
|
||||
is a valid CGI program in the
|
||||
.Ar cgibin
|
||||
directory.
|
||||
In other words, all CGI URL's must begin with
|
||||
.Em \%/cgi-bin/ .
|
||||
Note that the CGI/1.1 interface is not available with
|
||||
.Em ~user
|
||||
translation.
|
||||
.It Fl e
|
||||
Causes
|
||||
.Nm
|
||||
to not clear the environment when used with either the
|
||||
.Fl t
|
||||
or
|
||||
.Fl U
|
||||
options.
|
||||
.It Fl f
|
||||
Stops the
|
||||
.Fl b
|
||||
flag from
|
||||
.Nm
|
||||
detaching from the tty and going into the background.
|
||||
.It Fl H
|
||||
Causes directory index mode to hide files and directories
|
||||
that start with a period, except for
|
||||
.Pa .. .
|
||||
Also see
|
||||
.Fl X .
|
||||
.It Fl I Ar port
|
||||
Causes
|
||||
.Nm
|
||||
to use
|
||||
.Ar port
|
||||
instead of the default
|
||||
.Dq http
|
||||
port.
|
||||
When used with the
|
||||
.Fl b
|
||||
option, it changes the bound port.
|
||||
Otherwise it forces redirections to use this port instead of the
|
||||
value obtained via
|
||||
.Xr getsockname 2 .
|
||||
.It Fl i Ar address
|
||||
Causes
|
||||
.Ar address
|
||||
to be used as the address to bind daemon mode.
|
||||
If otherwise unspecified, the address used to bind is derived from the
|
||||
.Ar myname ,
|
||||
which defaults to the name returned by
|
||||
.Xr gethostname 3 .
|
||||
Only the last
|
||||
.Fl i
|
||||
option is used.
|
||||
This option is only valid with the
|
||||
.Fl b
|
||||
option.
|
||||
.It Fl L Ar prefix script
|
||||
Adds a new Lua script for a particular prefix.
|
||||
The
|
||||
.Ar prefix
|
||||
should be an arbitrary text, and the
|
||||
.Ar script
|
||||
should be a full path to a Lua script.
|
||||
Multiple
|
||||
.Fl L
|
||||
options may be passed.
|
||||
A separate Lua state is created for each prefix.
|
||||
The Lua script can register callbacks using the
|
||||
httpd.register_handler('<name>', function) Lua function,
|
||||
which will trigger the execution of the Lua function
|
||||
.Em function
|
||||
when a URL in the form
|
||||
.Em http://<hostname>/<prefix>/<name>
|
||||
is being accessed.
|
||||
The function is passed three tables as arguments, the server
|
||||
environment, the request headers, and the decoded query string
|
||||
plus any data that was send as application/x-www-form-urlencoded.
|
||||
.It Fl M Ar suffix type encoding encoding11
|
||||
Adds a new entry to the table that converts file suffixes to
|
||||
content type and encoding.
|
||||
This option takes four additional arguments containing
|
||||
the file prefix, its
|
||||
.Dq Content-Type ,
|
||||
.Dq Content-Encoding ,
|
||||
and
|
||||
.Dq Content-Encoding
|
||||
for HTTP/1.1 connections, respectively.
|
||||
If any of these are a single dash
|
||||
.Pq Dq - ,
|
||||
the empty string is used instead.
|
||||
Multiple
|
||||
.Fl M
|
||||
options may be passed.
|
||||
.It Fl n
|
||||
Stops
|
||||
.Nm
|
||||
from doing IP address to name resolution of hosts for setting the
|
||||
.Ev REMOTE_HOST
|
||||
variable before running a CGI program.
|
||||
This option has no effect without the
|
||||
.Fl c
|
||||
option.
|
||||
.It Fl P Ar pidfile
|
||||
Causes
|
||||
.Nm
|
||||
to create a pid file in
|
||||
.Ar pidfile
|
||||
when run in daemon mode with the
|
||||
.Fl b
|
||||
option.
|
||||
.It Fl p Ar pubdir
|
||||
Changes the default user directory for
|
||||
.Em /~user/
|
||||
translations from
|
||||
.Dq public_html
|
||||
to
|
||||
.Ar pubdir .
|
||||
.It Fl r
|
||||
Forces pages besides the
|
||||
.Dq index.html
|
||||
(see the
|
||||
.Fl X
|
||||
option) page to require that the Referrer: header be present and
|
||||
refer to this web server, otherwise a redirect to the
|
||||
.Dq index.html
|
||||
page will be returned instead.
|
||||
.It Fl S Ar server_software
|
||||
Sets the internal server version to
|
||||
.Ar server_software .
|
||||
.It Fl s
|
||||
Forces logging to be set to stderr always.
|
||||
.It Fl t Ar chrootdir
|
||||
Makes
|
||||
.Nm
|
||||
chroot to the specified directory
|
||||
before answering requests.
|
||||
Every other path should be specified relative
|
||||
to the new root, if this option is used.
|
||||
Note that the current environment
|
||||
is normally replaced with an empty environment with this option, unless the
|
||||
.Fl e
|
||||
option is also used.
|
||||
.It Fl U Ar username
|
||||
Causes
|
||||
.Nm
|
||||
to switch to the user and the groups of
|
||||
.Ar username
|
||||
after initialization.
|
||||
This option, like
|
||||
.Fl t
|
||||
above, causes
|
||||
.Nm
|
||||
to clear the environment unless the
|
||||
.Fl e
|
||||
option is given.
|
||||
.It Fl u
|
||||
Enables the transformation of Uniform Resource Locators of
|
||||
the form
|
||||
.Em /~user/
|
||||
into the directory
|
||||
.Pa ~user/public_html
|
||||
(but see the
|
||||
.Fl p
|
||||
option above).
|
||||
.It Fl V
|
||||
Sets the default virtual host directory to
|
||||
.Ar slashdir .
|
||||
If no directory exists in
|
||||
.Ar virtualroot
|
||||
for the request, then
|
||||
.Ar slashdir
|
||||
will be used.
|
||||
The default behaviour is to return 404 (Not Found.)
|
||||
.It Fl v Ar virtualroot
|
||||
Enables virtual hosting support.
|
||||
Directories in
|
||||
.Ar virtualroot
|
||||
will be searched for a matching virtual host name, when parsing
|
||||
the HTML request.
|
||||
If a matching name is found, it will be used
|
||||
as both the server's real name,
|
||||
.Op Ar myname ,
|
||||
and as the
|
||||
.Ar slashdir .
|
||||
See the
|
||||
.Sx EXAMPLES
|
||||
section for an example of using this option.
|
||||
.It Fl X
|
||||
Enables directory indexing.
|
||||
A directory index will be generated only when the default file (i.e.
|
||||
.Pa index.html
|
||||
normally) is not present.
|
||||
.It Fl x Ar index
|
||||
Changes the default file read for directories from
|
||||
.Dq index.html
|
||||
to
|
||||
.Ar index .
|
||||
.It Fl Z Ar certificate_path privatekey_path
|
||||
Sets the path to the server certificate file and the private key file
|
||||
in pem format.
|
||||
It also causes
|
||||
.Nm
|
||||
to start SSL mode.
|
||||
.El
|
||||
.Pp
|
||||
Note that in
|
||||
.Nm
|
||||
versions 20031005 and prior that supported the
|
||||
.Fl C
|
||||
and
|
||||
.Fl M
|
||||
options, they took a single space-separated argument that was parsed.
|
||||
since version 20040828, they take multiple options (2 in the case of
|
||||
.Fl C
|
||||
and 4 in the case of
|
||||
.Fl M . )
|
||||
.Ss INETD CONFIGURATION
|
||||
As
|
||||
.Nm
|
||||
uses
|
||||
.Xr inetd 8
|
||||
by default to process incoming TCP connections for HTTP requests
|
||||
(but see the
|
||||
.Fl b
|
||||
option),
|
||||
.Nm
|
||||
has little internal networking knowledge.
|
||||
(Indeed, you can run it on the command line with little change of functionality.)
|
||||
A typical
|
||||
.Xr inetd.conf 5
|
||||
entry would be:
|
||||
.Bd -literal
|
||||
http stream tcp nowait:600 _httpd /usr/libexec/httpd httpd /var/www
|
||||
http stream tcp6 nowait:600 _httpd /usr/libexec/httpd httpd /var/www
|
||||
.Ed
|
||||
.Pp
|
||||
This would serve web pages from
|
||||
.Pa /var/www
|
||||
on both IPv4 and IPv6 ports.
|
||||
The
|
||||
.Em :600
|
||||
changes the
|
||||
requests per minute to 600, up from the
|
||||
.Xr inetd 8
|
||||
default of 40.
|
||||
.Pp
|
||||
Using the
|
||||
.Nx
|
||||
.Xr inetd 8 ,
|
||||
you can provide multiple IP-address based HTTP servers by having multiple
|
||||
listening ports with different configurations.
|
||||
.Ss NOTES
|
||||
This server supports the
|
||||
.Em HTTP/0.9 ,
|
||||
.Em HTTP/1.0 ,
|
||||
and
|
||||
.Em HTTP/1.1
|
||||
standards.
|
||||
Support for these protocols is very minimal and many optional features are
|
||||
not supported.
|
||||
.Pp
|
||||
.Nm
|
||||
can be compiled without
|
||||
CGI support (NO_CGIBIN_SUPPORT),
|
||||
user transformations (NO_USER_SUPPORT),
|
||||
directory index support (NO_DIRINDEX_SUPPORT),
|
||||
daemon mode support (NO_DAEMON_MODE),
|
||||
dynamic MIME content (NO_DYNAMIC_CONTENT),
|
||||
Lua suport (NO_LUA_SUPPORT),
|
||||
and SSL support (NO_SSL_SUPPORT)
|
||||
by defining the listed macros when building
|
||||
.Nm .
|
||||
.Ss HTTP BASIC AUTHORISATION
|
||||
.Nm
|
||||
has support for HTTP Basic Authorisation.
|
||||
If a file named
|
||||
.Pa .htpasswd
|
||||
exists in the directory of the current request,
|
||||
.Nm
|
||||
will restrict access to documents in that directory
|
||||
using the RFC 2617 HTTP
|
||||
.Dq Basic
|
||||
authentication scheme.
|
||||
.Pp
|
||||
Note:
|
||||
This does not recursively protect any sub-directories.
|
||||
.Pp
|
||||
The
|
||||
.Pa .htpasswd
|
||||
file contains lines delimited with a colon containing
|
||||
usernames and passwords hashed with
|
||||
.Xr crypt 3 ,
|
||||
for example:
|
||||
.Bd -literal
|
||||
heather:$1$pZWI4tH/$DzDPl63i6VvVRv2lJNV7k1
|
||||
jeremy:A.xewbx2DpQ8I
|
||||
.Ed
|
||||
.Pp
|
||||
On
|
||||
.Nx ,
|
||||
the
|
||||
.Xr pwhash 1
|
||||
utility may be used to generate hashed passwords.
|
||||
.Pp
|
||||
While
|
||||
.Nm
|
||||
distributed with
|
||||
.Nx
|
||||
has support for HTTP Basic Authorisation enabled by default,
|
||||
in the portable distribution it is excluded.
|
||||
Compile
|
||||
.Nm
|
||||
with
|
||||
.Dq -DDO_HTPASSWD
|
||||
on the compiler command line to enable this support.
|
||||
It may require linking with the crypt library, using
|
||||
.Dq -lcrypt .
|
||||
.Ss SSL SUPPORT
|
||||
.Nm
|
||||
has support for SSLv2, SSLv3, and TLSv1 protocols that is included by
|
||||
default.
|
||||
It requires linking with the crypto and ssl library, using
|
||||
.Dq -lcrypto -lssl .
|
||||
To disable SSL SUPPORT compile
|
||||
.Nm
|
||||
with
|
||||
.Dq -DNO_SSL_SUPPORT
|
||||
on the compiler command line.
|
||||
.Ss COMPRESSION
|
||||
.Nm
|
||||
supports a very basic form compression.
|
||||
.Nm
|
||||
will serve the requested file postpended with
|
||||
.Dq Pa .gz
|
||||
if it exists, it is readable, the client requested gzip compression, and
|
||||
the client did not make a ranged request.
|
||||
.Sh FILES
|
||||
.Nm
|
||||
looks for a couple of special files in directories that allow certain features
|
||||
to be provided on a per-directory basis.
|
||||
In addition to the
|
||||
.Pa .htpasswd
|
||||
used by HTTP basic authorisation,
|
||||
if a
|
||||
.Pa .bzdirect
|
||||
file is found (contents are irrelevant)
|
||||
.Nm
|
||||
will allow direct access even with the
|
||||
.Fl r
|
||||
option.
|
||||
If a
|
||||
.Pa .bzredirect
|
||||
symbolic link is found,
|
||||
.Nm
|
||||
will perform a smart redirect to the target of this symlink.
|
||||
The target is assumed to live on the same server.
|
||||
If a
|
||||
.Pa .bzabsredirect
|
||||
symbolic link is found,
|
||||
.Nm
|
||||
will redirect to the absolute url pointed to by this symlink.
|
||||
This is useful to redirect to different servers.
|
||||
.Sh EXAMPLES
|
||||
To configure set of virtual hosts, one would use an
|
||||
.Xr inetd.conf 5
|
||||
entry like:
|
||||
.Bd -literal
|
||||
http stream tcp nowait:600 _httpd /usr/libexec/httpd httpd -v /var/vroot /var/www
|
||||
.Ed
|
||||
.Pp
|
||||
and inside
|
||||
.Pa /var/vroot
|
||||
create a directory (or a symlink to a directory) with the same name as
|
||||
the virtual host, for each virtual host.
|
||||
Lookups for these names are done in a case-insensitive manner, and may
|
||||
include the port number part of the request, allowing for distinct
|
||||
virtual hosts on the same name.
|
||||
.Pp
|
||||
To use
|
||||
.Nm
|
||||
with PHP, one must use the
|
||||
.Fl C
|
||||
option to specify a CGI handler for a particular file type.
|
||||
Typically this will be like:
|
||||
.Bd -literal
|
||||
httpd -C .php /usr/pkg/bin/php /var/www
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr inetd.conf 5 ,
|
||||
.Xr inetd 8
|
||||
.Sh HISTORY
|
||||
.Nm
|
||||
was first written in perl, based on another perl http server
|
||||
called
|
||||
.Dq tinyhttpd .
|
||||
It was then rewritten from scratch in perl, and then once again in C.
|
||||
From
|
||||
.Dq bozohttpd
|
||||
version 20060517, it has been integrated into
|
||||
.Nx .
|
||||
The focus has always been simplicity and security, with minimal features
|
||||
and regular code audits.
|
||||
This manual documents
|
||||
.Nm
|
||||
version 20150501.
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
.Nm
|
||||
was written by
|
||||
.An Matthew R. Green
|
||||
.Aq Mt mrg@eterna.com.au .
|
||||
.Pp
|
||||
The large list of contributors includes:
|
||||
.Bl -dash
|
||||
.It
|
||||
.An Marc Balmer
|
||||
.Aq Mt mbalmer@NetBSD.org
|
||||
added Lua support for dynamic content creation
|
||||
.It
|
||||
.An Christoph Badura
|
||||
.Aq Mt bad@bsd.de
|
||||
provided Range: header support
|
||||
.It
|
||||
.An Sean Boudreau
|
||||
.Aq Mt seanb@NetBSD.org
|
||||
provided a security fix for virtual hosting
|
||||
.It
|
||||
.An Julian Coleman
|
||||
.Aq Mt jdc@coris.org.uk
|
||||
provided an IPv6 bugfix
|
||||
.It
|
||||
.An Chuck Cranor
|
||||
.Aq Mt chuck@research.att.com
|
||||
provided cgi-bin support fixes, and more
|
||||
.It
|
||||
.An Alistair G. Crooks
|
||||
.Aq Mt agc@NetBSD.org
|
||||
cleaned up many internal interfaces, made
|
||||
.Nm
|
||||
linkable as a library and provided the Lua binding.
|
||||
.It
|
||||
.An DEGROOTE Arnaud
|
||||
.Aq Mt degroote@NetBSD.org
|
||||
provided a fix for daemon mode
|
||||
.It
|
||||
.An Andrew Doran
|
||||
.Aq Mt ad@NetBSD.org
|
||||
provided directory indexing support
|
||||
.It
|
||||
.An Per Ekman
|
||||
.Aq Mt pek@pdc.kth.se
|
||||
provided a fix for a minor (non-security) buffer overflow condition
|
||||
.It
|
||||
.An Roland Dowdeswell
|
||||
.Aq Mt elric@NetBSD.org
|
||||
added support for serving gzipped files and better SSL handling
|
||||
.It
|
||||
.An Jun-ichiro itojun Hagino, KAME
|
||||
.Aq Mt itojun@iijlab.net
|
||||
provided initial IPv6 support
|
||||
.It
|
||||
.An Martin Husemann
|
||||
.Aq Mt martin@NetBSD.org
|
||||
provided .bzabsredirect support, and fixed various redirection issues
|
||||
.It
|
||||
.An Arto Huusko
|
||||
.Aq Mt arto.huusko@pp2.inet.fi
|
||||
provided fixes cgi-bin
|
||||
.It
|
||||
.An Roland Illig
|
||||
.Aq Mt roland.illig@gmx.de
|
||||
provided some off-by-one fixes
|
||||
.It
|
||||
.An Zak Johnson
|
||||
.Aq Mt zakj@nox.cx
|
||||
provided cgi-bin enhancements
|
||||
.It
|
||||
.An Nicolas Jombart
|
||||
.Aq Mt ecu@ipv42.net
|
||||
provided fixes for HTTP basic authorisation support
|
||||
.It
|
||||
.An Antti Kantee
|
||||
.Aq Mt pooka@NetBSD.org
|
||||
provided fixes for HTTP basic authorisation support
|
||||
.It
|
||||
.An Thomas Klausner
|
||||
.Aq Mt wiz@NetBSD.org
|
||||
provided many fixes and enhancements for the man page
|
||||
.It
|
||||
.An Mateusz Kocielski
|
||||
.Aq Mt shm@NetBSD.org
|
||||
fixed memory leaks, various issues with userdir support,
|
||||
information disclosure issues, added support for using CGI handlers
|
||||
with directory indexing and provided various other fixes.
|
||||
.It
|
||||
.An Arnaud Lacombe
|
||||
.Aq Mt alc@NetBSD.org
|
||||
provided some clean up for memory leaks
|
||||
.It
|
||||
.An Johnny Lam
|
||||
.Aq Mt jlam@NetBSD.org
|
||||
provided man page fixes
|
||||
.It
|
||||
.An Julio Merino
|
||||
.Aq Mt jmmv@NetBSD.org
|
||||
Added the
|
||||
.Fl P
|
||||
option.
|
||||
.It
|
||||
.An Luke Mewburn
|
||||
.Aq Mt lukem@NetBSD.org
|
||||
provided many various fixes, including cgi-bin fixes and enhancements,
|
||||
HTTP basic authorisation support and much code clean up
|
||||
.It
|
||||
.An Rajeev V. Pillai
|
||||
.Aq Mt rajeev_v_pillai@yahoo.com
|
||||
provided several fixes for virtual hosting
|
||||
.It
|
||||
.An Jeremy C. Reed
|
||||
.Aq Mt reed@NetBSD.org
|
||||
provided several clean up fixes, and man page updates
|
||||
.It
|
||||
.An Scott Reynolds
|
||||
.Aq Mt scottr@NetBSD.org
|
||||
provided various fixes
|
||||
.It
|
||||
.An Tyler Retzlaff
|
||||
.Aq Mt rtr@eterna.com.au
|
||||
provided SSL support, cgi-bin fixes and much other random other stuff
|
||||
.It
|
||||
.An rudolf
|
||||
.Aq Mt netbsd@eq.cz
|
||||
provided minor compile fixes and a CGI content map fix
|
||||
.It
|
||||
.An Steve Rumble
|
||||
.Aq Mt rumble@ephemeral.org
|
||||
provided the
|
||||
.Fl V
|
||||
option.
|
||||
.It
|
||||
.An Thor Lancelot Simon
|
||||
.Aq Mt tls@NetBSD.org
|
||||
enhanced cgi-bin support.
|
||||
.It
|
||||
.An Joerg Sonnenberger
|
||||
.Aq Mt joerg@NetBSD.org
|
||||
implemented If-Modified-Since support
|
||||
.It
|
||||
.An ISIHARA Takanori
|
||||
.Aq Mt ishit@oak.dti.ne.jp
|
||||
provided a man page fix
|
||||
.It
|
||||
.An Holger Weiss
|
||||
.Aq Mt holger@CIS.FU-Berlin.DE
|
||||
provided http authorisation fixes
|
||||
.It
|
||||
.Aq Mt xs@kittenz.org
|
||||
provided chroot and change-to-user support, and other various fixes
|
||||
.It
|
||||
Coyote Point provided various CGI fixes.
|
||||
.It
|
||||
.An Julio Merino
|
||||
added pidfile support and provided some man page fixes.
|
||||
.El
|
||||
.Pp
|
||||
There are probably others I have forgotten (let me know if you care)
|
||||
.Pp
|
||||
Please send all updates to
|
||||
.Nm
|
||||
to
|
||||
.Aq Mt mrg@eterna.com.au
|
||||
for inclusion in future releases.
|
||||
.Sh BUGS
|
||||
.Nm
|
||||
does not handle HTTP/1.1 chunked input from the client yet.
|
||||
2321
libexec/httpd/bozohttpd.c
Normal file
2321
libexec/httpd/bozohttpd.c
Normal file
File diff suppressed because it is too large
Load Diff
350
libexec/httpd/bozohttpd.h
Normal file
350
libexec/httpd/bozohttpd.h
Normal file
|
|
@ -0,0 +1,350 @@
|
|||
/* $NetBSD: bozohttpd.h,v 1.36 2015/08/05 06:50:44 mrg Exp $ */
|
||||
|
||||
/* $eterna: bozohttpd.h,v 1.39 2011/11/18 09:21:15 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997-2015 Matthew R. Green
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 and
|
||||
* dedication in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*
|
||||
*/
|
||||
#ifndef BOZOHTTOPD_H_
|
||||
#define BOZOHTTOPD_H_ 1
|
||||
|
||||
#include "netbsd_queue.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifndef NO_LUA_SUPPORT
|
||||
#include <lua.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
|
||||
/* QNX provides a lot of NetBSD things in nbutil.h */
|
||||
#ifdef USE_NBUTIL
|
||||
#include <nbutil.h>
|
||||
#endif
|
||||
|
||||
/* lots of "const" but gets free()'ed etc at times, sigh */
|
||||
|
||||
/* headers */
|
||||
typedef struct bozoheaders {
|
||||
/*const*/ char *h_header;
|
||||
/*const*/ char *h_value; /* this gets free()'ed etc at times */
|
||||
SIMPLEQ_ENTRY(bozoheaders) h_next;
|
||||
} bozoheaders_t;
|
||||
|
||||
#ifndef NO_LUA_SUPPORT
|
||||
typedef struct lua_handler {
|
||||
const char *name;
|
||||
int ref;
|
||||
SIMPLEQ_ENTRY(lua_handler) h_next;
|
||||
} lua_handler_t;
|
||||
|
||||
typedef struct lua_state_map {
|
||||
const char *script;
|
||||
const char *prefix;
|
||||
lua_State *L;
|
||||
SIMPLEQ_HEAD(, lua_handler) handlers;
|
||||
SIMPLEQ_ENTRY(lua_state_map) s_next;
|
||||
} lua_state_map_t;
|
||||
#endif
|
||||
|
||||
typedef struct bozo_content_map_t {
|
||||
const char *name; /* postfix of file */
|
||||
const char *type; /* matching content-type */
|
||||
const char *encoding; /* matching content-encoding */
|
||||
const char *encoding11; /* matching content-encoding (HTTP/1.1) */
|
||||
const char *cgihandler; /* optional CGI handler */
|
||||
} bozo_content_map_t;
|
||||
|
||||
/* this struct holds the bozo constants */
|
||||
typedef struct bozo_consts_t {
|
||||
const char *http_09; /* "HTTP/0.9" */
|
||||
const char *http_10; /* "HTTP/1.0" */
|
||||
const char *http_11; /* "HTTP/1.1" */
|
||||
const char *text_plain; /* "text/plain" */
|
||||
} bozo_consts_t;
|
||||
|
||||
/* this structure encapsulates all the bozo flags and control vars */
|
||||
typedef struct bozohttpd_t {
|
||||
char *rootdir; /* root directory */
|
||||
char *username; /* username to switch to */
|
||||
int numeric; /* avoid gethostby*() */
|
||||
char *virtbase; /* virtual directory base */
|
||||
int unknown_slash; /* unknown vhosts go to normal slashdir */
|
||||
int untrustedref; /* make sure referrer = me unless url = / */
|
||||
int logstderr; /* log to stderr (even if not tty) */
|
||||
int background; /* drop into daemon mode */
|
||||
int foreground; /* keep daemon mode in foreground */
|
||||
char *pidfile; /* path to the pid file, if any */
|
||||
size_t page_size; /* page size */
|
||||
char *slashdir; /* www slash directory */
|
||||
char *bindport; /* bind port; default "http" */
|
||||
char *bindaddress; /* address for binding - INADDR_ANY */
|
||||
int debug; /* debugging level */
|
||||
char *virthostname; /* my name */
|
||||
const char *server_software;/* our brand :-) */
|
||||
const char *index_html; /* our home page */
|
||||
const char *public_html; /* ~user/public_html page */
|
||||
int enable_users; /* enable public_html */
|
||||
int *sock; /* bound sockets */
|
||||
int nsock; /* number of above */
|
||||
struct pollfd *fds; /* current poll fd set */
|
||||
int request_times; /* # times a request was processed */
|
||||
int dir_indexing; /* handle directories */
|
||||
int hide_dots; /* hide .* */
|
||||
int process_cgi; /* use the cgi handler */
|
||||
char *cgibin; /* cgi-bin directory */
|
||||
#ifndef NO_LUA_SUPPORT
|
||||
int process_lua; /* use the Lua handler */
|
||||
SIMPLEQ_HEAD(, lua_state_map) lua_states;
|
||||
#endif
|
||||
void *sslinfo; /* pointer to ssl struct */
|
||||
int dynamic_content_map_size;/* size of dyn cont map */
|
||||
bozo_content_map_t *dynamic_content_map;/* dynamic content map */
|
||||
size_t mmapsz; /* size of region to mmap */
|
||||
char *getln_buffer; /* space for getln buffer */
|
||||
ssize_t getln_buflen; /* length of allocated space */
|
||||
char *errorbuf; /* no dynamic allocation allowed */
|
||||
bozo_consts_t consts; /* various constants */
|
||||
} bozohttpd_t;
|
||||
|
||||
/* bozo_httpreq_t */
|
||||
typedef struct bozo_httpreq_t {
|
||||
bozohttpd_t *hr_httpd;
|
||||
int hr_method;
|
||||
#define HTTP_GET 0x01
|
||||
#define HTTP_POST 0x02
|
||||
#define HTTP_HEAD 0x03
|
||||
#define HTTP_OPTIONS 0x04 /* not supported */
|
||||
#define HTTP_PUT 0x05 /* not supported */
|
||||
#define HTTP_DELETE 0x06 /* not supported */
|
||||
#define HTTP_TRACE 0x07 /* not supported */
|
||||
#define HTTP_CONNECT 0x08 /* not supported */
|
||||
const char *hr_methodstr;
|
||||
char *hr_virthostname; /* server name (if not identical
|
||||
to hr_httpd->virthostname) */
|
||||
char *hr_file;
|
||||
char *hr_oldfile; /* if we added an index_html */
|
||||
char *hr_query;
|
||||
char *hr_host; /* HTTP/1.1 Host: or virtual hostname,
|
||||
possibly including a port number */
|
||||
const char *hr_proto;
|
||||
const char *hr_content_type;
|
||||
const char *hr_content_length;
|
||||
const char *hr_allow;
|
||||
const char *hr_referrer;
|
||||
const char *hr_range;
|
||||
const char *hr_if_modified_since;
|
||||
const char *hr_accept_encoding;
|
||||
int hr_have_range;
|
||||
off_t hr_first_byte_pos;
|
||||
off_t hr_last_byte_pos;
|
||||
/*const*/ char *hr_remotehost;
|
||||
/*const*/ char *hr_remoteaddr;
|
||||
/*const*/ char *hr_serverport;
|
||||
#ifdef DO_HTPASSWD
|
||||
/*const*/ char *hr_authrealm;
|
||||
/*const*/ char *hr_authuser;
|
||||
/*const*/ char *hr_authpass;
|
||||
#endif
|
||||
SIMPLEQ_HEAD(, bozoheaders) hr_headers;
|
||||
int hr_nheaders;
|
||||
} bozo_httpreq_t;
|
||||
|
||||
/* helper to access the "active" host name from a httpd/request pair */
|
||||
#define BOZOHOST(HTTPD,REQUEST) ((REQUEST)->hr_virthostname ? \
|
||||
(REQUEST)->hr_virthostname : \
|
||||
(HTTPD)->virthostname)
|
||||
|
||||
/* structure to hold string based (name, value) pairs with preferences */
|
||||
typedef struct bozoprefs_t {
|
||||
unsigned size; /* size of the two arrays */
|
||||
unsigned c; /* # of entries in arrays */
|
||||
char **name; /* names of each entry */
|
||||
char **value; /* values for the name entries */
|
||||
} bozoprefs_t;
|
||||
|
||||
/* by default write in upto 64KiB chunks, and mmap in upto 64MiB chunks */
|
||||
#ifndef BOZO_WRSZ
|
||||
#define BOZO_WRSZ (64 * 1024)
|
||||
#endif
|
||||
#ifndef BOZO_MMAPSZ
|
||||
#define BOZO_MMAPSZ (BOZO_WRSZ * 1024)
|
||||
#endif
|
||||
|
||||
/* debug flags */
|
||||
#define DEBUG_NORMAL 1
|
||||
#define DEBUG_FAT 2
|
||||
#define DEBUG_OBESE 3
|
||||
#define DEBUG_EXPLODING 4
|
||||
|
||||
#define strornull(x) ((x) ? (x) : "<null>")
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ >= 3
|
||||
#define BOZO_PRINTFLIKE(x,y) __attribute__((__format__(__printf__, x,y)))
|
||||
#define BOZO_DEAD __attribute__((__noreturn__))
|
||||
#endif
|
||||
|
||||
#ifndef NO_DEBUG
|
||||
void debug__(bozohttpd_t *, int, const char *, ...) BOZO_PRINTFLIKE(3, 4);
|
||||
#define debug(x) debug__ x
|
||||
#else
|
||||
#define debug(x)
|
||||
#endif /* NO_DEBUG */
|
||||
|
||||
void bozo_warn(bozohttpd_t *, const char *, ...)
|
||||
BOZO_PRINTFLIKE(2, 3);
|
||||
void bozo_err(bozohttpd_t *, int, const char *, ...)
|
||||
BOZO_PRINTFLIKE(3, 4)
|
||||
BOZO_DEAD;
|
||||
int bozo_http_error(bozohttpd_t *, int, bozo_httpreq_t *, const char *);
|
||||
|
||||
int bozo_check_special_files(bozo_httpreq_t *, const char *);
|
||||
char *bozo_http_date(char *, size_t);
|
||||
void bozo_print_header(bozo_httpreq_t *, struct stat *, const char *, const char *);
|
||||
char *bozo_escape_rfc3986(bozohttpd_t *httpd, const char *url);
|
||||
char *bozo_escape_html(bozohttpd_t *httpd, const char *url);
|
||||
|
||||
char *bozodgetln(bozohttpd_t *, int, ssize_t *, ssize_t (*)(bozohttpd_t *, int, void *, size_t));
|
||||
char *bozostrnsep(char **, const char *, ssize_t *);
|
||||
|
||||
void *bozomalloc(bozohttpd_t *, size_t);
|
||||
void *bozorealloc(bozohttpd_t *, void *, size_t);
|
||||
char *bozostrdup(bozohttpd_t *, const char *);
|
||||
|
||||
/* ssl-bozo.c */
|
||||
#ifdef NO_SSL_SUPPORT
|
||||
#define bozo_ssl_set_opts(w, x, y) do { /* nothing */ } while (0)
|
||||
#define bozo_ssl_init(x) do { /* nothing */ } while (0)
|
||||
#define bozo_ssl_accept(x) (0)
|
||||
#define bozo_ssl_destroy(x) do { /* nothing */ } while (0)
|
||||
#else
|
||||
void bozo_ssl_set_opts(bozohttpd_t *, const char *, const char *);
|
||||
void bozo_ssl_init(bozohttpd_t *);
|
||||
int bozo_ssl_accept(bozohttpd_t *);
|
||||
void bozo_ssl_destroy(bozohttpd_t *);
|
||||
#endif
|
||||
|
||||
|
||||
/* auth-bozo.c */
|
||||
#ifdef DO_HTPASSWD
|
||||
void bozo_auth_init(bozo_httpreq_t *);
|
||||
int bozo_auth_check(bozo_httpreq_t *, const char *);
|
||||
void bozo_auth_cleanup(bozo_httpreq_t *);
|
||||
int bozo_auth_check_headers(bozo_httpreq_t *, char *, char *, ssize_t);
|
||||
int bozo_auth_check_special_files(bozo_httpreq_t *, const char *);
|
||||
void bozo_auth_check_401(bozo_httpreq_t *, int);
|
||||
void bozo_auth_cgi_setenv(bozo_httpreq_t *, char ***);
|
||||
int bozo_auth_cgi_count(bozo_httpreq_t *);
|
||||
#else
|
||||
#define bozo_auth_init(x) do { /* nothing */ } while (0)
|
||||
#define bozo_auth_check(x, y) 0
|
||||
#define bozo_auth_cleanup(x) do { /* nothing */ } while (0)
|
||||
#define bozo_auth_check_headers(y, z, a, b) 0
|
||||
#define bozo_auth_check_special_files(x, y) 0
|
||||
#define bozo_auth_check_401(x, y) do { /* nothing */ } while (0)
|
||||
#define bozo_auth_cgi_setenv(x, y) do { /* nothing */ } while (0)
|
||||
#define bozo_auth_cgi_count(x) 0
|
||||
#endif /* DO_HTPASSWD */
|
||||
|
||||
|
||||
/* cgi-bozo.c */
|
||||
#ifdef NO_CGIBIN_SUPPORT
|
||||
#define bozo_process_cgi(h) 0
|
||||
#else
|
||||
void bozo_cgi_setbin(bozohttpd_t *, const char *);
|
||||
void bozo_setenv(bozohttpd_t *, const char *, const char *, char **);
|
||||
int bozo_process_cgi(bozo_httpreq_t *);
|
||||
void bozo_add_content_map_cgi(bozohttpd_t *, const char *, const char *);
|
||||
#endif /* NO_CGIBIN_SUPPORT */
|
||||
|
||||
|
||||
/* lua-bozo.c */
|
||||
#ifdef NO_LUA_SUPPORT
|
||||
#define bozo_process_lua(h) 0
|
||||
#else
|
||||
void bozo_add_lua_map(bozohttpd_t *, const char *, const char *);
|
||||
int bozo_process_lua(bozo_httpreq_t *);
|
||||
#endif /* NO_LUA_SUPPORT */
|
||||
|
||||
|
||||
/* daemon-bozo.c */
|
||||
#ifdef NO_DAEMON_MODE
|
||||
#define bozo_daemon_init(x) do { /* nothing */ } while (0)
|
||||
#define bozo_daemon_fork(x) 0
|
||||
#define bozo_daemon_closefds(x) do { /* nothing */ } while (0)
|
||||
#else
|
||||
void bozo_daemon_init(bozohttpd_t *);
|
||||
int bozo_daemon_fork(bozohttpd_t *);
|
||||
void bozo_daemon_closefds(bozohttpd_t *);
|
||||
#endif /* NO_DAEMON_MODE */
|
||||
|
||||
|
||||
/* tilde-luzah-bozo.c */
|
||||
#ifdef NO_USER_SUPPORT
|
||||
#define bozo_user_transform(a, c) 0
|
||||
#else
|
||||
int bozo_user_transform(bozo_httpreq_t *, int *);
|
||||
#endif /* NO_USER_SUPPORT */
|
||||
|
||||
|
||||
/* dir-index-bozo.c */
|
||||
#ifdef NO_DIRINDEX_SUPPORT
|
||||
#define bozo_dir_index(a, b, c) 0
|
||||
#else
|
||||
int bozo_dir_index(bozo_httpreq_t *, const char *, int);
|
||||
#endif /* NO_DIRINDEX_SUPPORT */
|
||||
|
||||
|
||||
/* content-bozo.c */
|
||||
const char *bozo_content_type(bozo_httpreq_t *, const char *);
|
||||
const char *bozo_content_encoding(bozo_httpreq_t *, const char *);
|
||||
bozo_content_map_t *bozo_match_content_map(bozohttpd_t *, const char *, int);
|
||||
bozo_content_map_t *bozo_get_content_map(bozohttpd_t *, const char *);
|
||||
#ifndef NO_DYNAMIC_CONTENT
|
||||
void bozo_add_content_map_mime(bozohttpd_t *, const char *, const char *, const char *, const char *);
|
||||
#endif
|
||||
|
||||
/* I/O */
|
||||
int bozo_printf(bozohttpd_t *, const char *, ...) BOZO_PRINTFLIKE(2, 3);;
|
||||
ssize_t bozo_read(bozohttpd_t *, int, void *, size_t);
|
||||
ssize_t bozo_write(bozohttpd_t *, int, const void *, size_t);
|
||||
int bozo_flush(bozohttpd_t *, FILE *);
|
||||
|
||||
/* misc */
|
||||
int bozo_init_httpd(bozohttpd_t *);
|
||||
int bozo_init_prefs(bozoprefs_t *);
|
||||
int bozo_set_defaults(bozohttpd_t *, bozoprefs_t *);
|
||||
int bozo_setup(bozohttpd_t *, bozoprefs_t *, const char *, const char *);
|
||||
bozo_httpreq_t *bozo_read_request(bozohttpd_t *);
|
||||
void bozo_process_request(bozo_httpreq_t *);
|
||||
void bozo_clean_request(bozo_httpreq_t *);
|
||||
|
||||
/* variables */
|
||||
int bozo_set_pref(bozoprefs_t *, const char *, const char *);
|
||||
char *bozo_get_pref(bozoprefs_t *, const char *);
|
||||
|
||||
#endif /* BOZOHTTOPD_H_ */
|
||||
523
libexec/httpd/cgi-bozo.c
Normal file
523
libexec/httpd/cgi-bozo.c
Normal file
|
|
@ -0,0 +1,523 @@
|
|||
/* $NetBSD: cgi-bozo.c,v 1.27 2015/05/02 11:35:48 mrg Exp $ */
|
||||
|
||||
/* $eterna: cgi-bozo.c,v 1.40 2011/11/18 09:21:15 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997-2015 Matthew R. Green
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 and
|
||||
* dedication in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* this code implements CGI/1.2 for bozohttpd */
|
||||
|
||||
#ifndef NO_CGIBIN_SUPPORT
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <paths.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "bozohttpd.h"
|
||||
|
||||
#define CGIBIN_PREFIX "cgi-bin/"
|
||||
#define CGIBIN_PREFIX_LEN (sizeof(CGIBIN_PREFIX)-1)
|
||||
|
||||
#ifndef USE_ARG
|
||||
#define USE_ARG(x) /*LINTED*/(void)&(x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* given the file name, return a CGI interpreter
|
||||
*/
|
||||
static const char *
|
||||
content_cgihandler(bozohttpd_t *httpd, bozo_httpreq_t *request,
|
||||
const char *file)
|
||||
{
|
||||
bozo_content_map_t *map;
|
||||
|
||||
USE_ARG(request);
|
||||
debug((httpd, DEBUG_FAT, "content_cgihandler: trying file %s", file));
|
||||
map = bozo_match_content_map(httpd, file, 0);
|
||||
if (map)
|
||||
return map->cgihandler;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_header(bozohttpd_t *httpd, const char *str, ssize_t len, char **hdr_str,
|
||||
char **hdr_val)
|
||||
{
|
||||
char *name, *value;
|
||||
|
||||
/* if the string passed is zero-length bail out */
|
||||
if (*str == '\0')
|
||||
return -1;
|
||||
|
||||
value = bozostrdup(httpd, str);
|
||||
|
||||
/* locate the ':' separator in the header/value */
|
||||
name = bozostrnsep(&value, ":", &len);
|
||||
|
||||
if (NULL == name || -1 == len) {
|
||||
free(name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* skip leading space/tab */
|
||||
while (*value == ' ' || *value == '\t')
|
||||
len--, value++;
|
||||
|
||||
*hdr_str = name;
|
||||
*hdr_val = value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* handle parsing a CGI header output, transposing a Status: header
|
||||
* into the HTTP reply (ie, instead of "200 OK").
|
||||
*/
|
||||
static void
|
||||
finish_cgi_output(bozohttpd_t *httpd, bozo_httpreq_t *request, int in, int nph)
|
||||
{
|
||||
char buf[BOZO_WRSZ];
|
||||
char *str;
|
||||
ssize_t len;
|
||||
ssize_t rbytes;
|
||||
SIMPLEQ_HEAD(, bozoheaders) headers;
|
||||
bozoheaders_t *hdr, *nhdr;
|
||||
int write_header, nheaders = 0;
|
||||
|
||||
/* much of this code is like bozo_read_request()'s header loop. */
|
||||
SIMPLEQ_INIT(&headers);
|
||||
write_header = nph == 0;
|
||||
/* was read(2) here - XXX - agc */
|
||||
while (nph == 0 &&
|
||||
(str = bozodgetln(httpd, in, &len, bozo_read)) != NULL) {
|
||||
char *hdr_name, *hdr_value;
|
||||
|
||||
if (parse_header(httpd, str, len, &hdr_name, &hdr_value))
|
||||
break;
|
||||
|
||||
/*
|
||||
* The CGI 1.{1,2} spec both say that if the cgi program
|
||||
* returns a `Status:' header field then the server MUST
|
||||
* return it in the response. If the cgi program does
|
||||
* not return any `Status:' header then the server should
|
||||
* respond with 200 OK.
|
||||
* XXX The CGI 1.1 and 1.2 specification differ slightly on
|
||||
* this in that v1.2 says that the script MUST NOT return a
|
||||
* `Status:' header if it is returning a `Location:' header.
|
||||
* For compatibility we are going with the CGI 1.1 behavior.
|
||||
*/
|
||||
if (strcasecmp(hdr_name, "status") == 0) {
|
||||
debug((httpd, DEBUG_OBESE,
|
||||
"bozo_process_cgi: writing HTTP header "
|
||||
"from status %s ..", hdr_value));
|
||||
bozo_printf(httpd, "%s %s\r\n", request->hr_proto,
|
||||
hdr_value);
|
||||
bozo_flush(httpd, stdout);
|
||||
write_header = 0;
|
||||
free(hdr_name);
|
||||
break;
|
||||
}
|
||||
|
||||
hdr = bozomalloc(httpd, sizeof *hdr);
|
||||
hdr->h_header = hdr_name;
|
||||
hdr->h_value = hdr_value;
|
||||
SIMPLEQ_INSERT_TAIL(&headers, hdr, h_next);
|
||||
nheaders++;
|
||||
}
|
||||
|
||||
if (write_header) {
|
||||
debug((httpd, DEBUG_OBESE,
|
||||
"bozo_process_cgi: writing HTTP header .."));
|
||||
bozo_printf(httpd,
|
||||
"%s 200 OK\r\n", request->hr_proto);
|
||||
bozo_flush(httpd, stdout);
|
||||
}
|
||||
|
||||
if (nheaders) {
|
||||
debug((httpd, DEBUG_OBESE,
|
||||
"bozo_process_cgi: writing delayed HTTP headers .."));
|
||||
SIMPLEQ_FOREACH_SAFE(hdr, &headers, h_next, nhdr) {
|
||||
bozo_printf(httpd, "%s: %s\r\n", hdr->h_header,
|
||||
hdr->h_value);
|
||||
free(hdr->h_header);
|
||||
free(hdr);
|
||||
}
|
||||
bozo_printf(httpd, "\r\n");
|
||||
bozo_flush(httpd, stdout);
|
||||
}
|
||||
|
||||
/* XXX we should have some goo that times us out
|
||||
*/
|
||||
while ((rbytes = read(in, buf, sizeof buf)) > 0) {
|
||||
ssize_t wbytes;
|
||||
char *bp = buf;
|
||||
|
||||
while (rbytes) {
|
||||
wbytes = bozo_write(httpd, STDOUT_FILENO, buf,
|
||||
(size_t)rbytes);
|
||||
if (wbytes > 0) {
|
||||
rbytes -= wbytes;
|
||||
bp += wbytes;
|
||||
} else
|
||||
bozo_err(httpd, 1,
|
||||
"cgi output write failed: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
append_index_html(bozohttpd_t *httpd, char **url)
|
||||
{
|
||||
*url = bozorealloc(httpd, *url,
|
||||
strlen(*url) + strlen(httpd->index_html) + 1);
|
||||
strcat(*url, httpd->index_html);
|
||||
debug((httpd, DEBUG_NORMAL,
|
||||
"append_index_html: url adjusted to `%s'", *url));
|
||||
}
|
||||
|
||||
void
|
||||
bozo_cgi_setbin(bozohttpd_t *httpd, const char *path)
|
||||
{
|
||||
httpd->cgibin = strdup(path);
|
||||
debug((httpd, DEBUG_OBESE, "cgibin (cgi-bin directory) is %s",
|
||||
httpd->cgibin));
|
||||
}
|
||||
|
||||
/* help build up the environ pointer */
|
||||
void
|
||||
bozo_setenv(bozohttpd_t *httpd, const char *env, const char *val,
|
||||
char **envp)
|
||||
{
|
||||
char *s1 = bozomalloc(httpd, strlen(env) + strlen(val) + 2);
|
||||
|
||||
strcpy(s1, env);
|
||||
strcat(s1, "=");
|
||||
strcat(s1, val);
|
||||
debug((httpd, DEBUG_OBESE, "bozo_setenv: %s", s1));
|
||||
*envp = s1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks if the request has asked for a cgi-bin. Should only be called if
|
||||
* cgibin is set. If it starts CGIBIN_PREFIX or has a ncontent handler,
|
||||
* process the cgi, otherwise just return. Returns 0 if it did not handle
|
||||
* the request.
|
||||
*/
|
||||
int
|
||||
bozo_process_cgi(bozo_httpreq_t *request)
|
||||
{
|
||||
bozohttpd_t *httpd = request->hr_httpd;
|
||||
char buf[BOZO_WRSZ];
|
||||
char date[40];
|
||||
bozoheaders_t *headp;
|
||||
const char *type, *clen, *info, *cgihandler;
|
||||
char *query, *s, *t, *path, *env, *file, *url;
|
||||
char command[MAXPATHLEN];
|
||||
char **envp, **curenvp, *argv[4];
|
||||
char *uri;
|
||||
size_t len;
|
||||
ssize_t rbytes;
|
||||
pid_t pid;
|
||||
int envpsize, ix, nph;
|
||||
int sv[2];
|
||||
|
||||
if (!httpd->cgibin && !httpd->process_cgi)
|
||||
return 0;
|
||||
|
||||
if (request->hr_oldfile && strcmp(request->hr_oldfile, "/") != 0)
|
||||
uri = request->hr_oldfile;
|
||||
else
|
||||
uri = request->hr_file;
|
||||
|
||||
if (uri[0] == '/')
|
||||
file = bozostrdup(httpd, uri);
|
||||
else
|
||||
asprintf(&file, "/%s", uri);
|
||||
if (file == NULL)
|
||||
return 0;
|
||||
|
||||
if (request->hr_query && strlen(request->hr_query))
|
||||
query = bozostrdup(httpd, request->hr_query);
|
||||
else
|
||||
query = NULL;
|
||||
|
||||
asprintf(&url, "%s%s%s", file, query ? "?" : "", query ? query : "");
|
||||
if (url == NULL)
|
||||
goto out;
|
||||
debug((httpd, DEBUG_NORMAL, "bozo_process_cgi: url `%s'", url));
|
||||
|
||||
path = NULL;
|
||||
envp = NULL;
|
||||
cgihandler = NULL;
|
||||
info = NULL;
|
||||
|
||||
len = strlen(url);
|
||||
|
||||
if (bozo_auth_check(request, url + 1))
|
||||
goto out;
|
||||
|
||||
if (!httpd->cgibin ||
|
||||
strncmp(url + 1, CGIBIN_PREFIX, CGIBIN_PREFIX_LEN) != 0) {
|
||||
cgihandler = content_cgihandler(httpd, request, file + 1);
|
||||
if (cgihandler == NULL) {
|
||||
debug((httpd, DEBUG_FAT,
|
||||
"bozo_process_cgi: no handler, returning"));
|
||||
goto out;
|
||||
}
|
||||
if (len == 0 || file[len - 1] == '/')
|
||||
append_index_html(httpd, &file);
|
||||
debug((httpd, DEBUG_NORMAL, "bozo_process_cgi: cgihandler `%s'",
|
||||
cgihandler));
|
||||
} else if (len - 1 == CGIBIN_PREFIX_LEN) /* url is "/cgi-bin/" */
|
||||
append_index_html(httpd, &file);
|
||||
|
||||
ix = 0;
|
||||
if (cgihandler) {
|
||||
snprintf(command, sizeof(command), "%s", file + 1);
|
||||
path = bozostrdup(httpd, cgihandler);
|
||||
argv[ix++] = path;
|
||||
/* argv[] = [ path, command, query, NULL ] */
|
||||
} else {
|
||||
snprintf(command, sizeof(command), "%s",
|
||||
file + CGIBIN_PREFIX_LEN + 1);
|
||||
if ((s = strchr(command, '/')) != NULL) {
|
||||
info = bozostrdup(httpd, s);
|
||||
*s = '\0';
|
||||
}
|
||||
path = bozomalloc(httpd,
|
||||
strlen(httpd->cgibin) + 1 + strlen(command) + 1);
|
||||
strcpy(path, httpd->cgibin);
|
||||
strcat(path, "/");
|
||||
strcat(path, command);
|
||||
/* argv[] = [ command, query, NULL ] */
|
||||
}
|
||||
argv[ix++] = command;
|
||||
argv[ix++] = query;
|
||||
argv[ix++] = NULL;
|
||||
|
||||
nph = strncmp(command, "nph-", 4) == 0;
|
||||
|
||||
type = request->hr_content_type;
|
||||
clen = request->hr_content_length;
|
||||
|
||||
envpsize = 13 + request->hr_nheaders +
|
||||
(info && *info ? 1 : 0) +
|
||||
(query && *query ? 1 : 0) +
|
||||
(type && *type ? 1 : 0) +
|
||||
(clen && *clen ? 1 : 0) +
|
||||
(request->hr_remotehost && *request->hr_remotehost ? 1 : 0) +
|
||||
(request->hr_remoteaddr && *request->hr_remoteaddr ? 1 : 0) +
|
||||
bozo_auth_cgi_count(request) +
|
||||
(request->hr_serverport && *request->hr_serverport ? 1 : 0);
|
||||
|
||||
debug((httpd, DEBUG_FAT,
|
||||
"bozo_process_cgi: path `%s', cmd `%s', info `%s', "
|
||||
"query `%s', nph `%d', envpsize `%d'",
|
||||
path, command, strornull(info),
|
||||
strornull(query), nph, envpsize));
|
||||
|
||||
envp = bozomalloc(httpd, sizeof(*envp) * envpsize);
|
||||
for (ix = 0; ix < envpsize; ix++)
|
||||
envp[ix] = NULL;
|
||||
curenvp = envp;
|
||||
|
||||
SIMPLEQ_FOREACH(headp, &request->hr_headers, h_next) {
|
||||
const char *s2;
|
||||
env = bozomalloc(httpd, 6 + strlen(headp->h_header) + 1 +
|
||||
strlen(headp->h_value));
|
||||
|
||||
t = env;
|
||||
strcpy(t, "HTTP_");
|
||||
t += strlen(t);
|
||||
for (s2 = headp->h_header; *s2; t++, s2++)
|
||||
if (islower((u_int)*s2))
|
||||
*t = toupper((u_int)*s2);
|
||||
else if (*s2 == '-')
|
||||
*t = '_';
|
||||
else
|
||||
*t = *s2;
|
||||
*t = '\0';
|
||||
debug((httpd, DEBUG_OBESE, "setting header %s as %s = %s",
|
||||
headp->h_header, env, headp->h_value));
|
||||
bozo_setenv(httpd, env, headp->h_value, curenvp++);
|
||||
free(env);
|
||||
}
|
||||
|
||||
#ifndef _PATH_DEFPATH
|
||||
#define _PATH_DEFPATH "/usr/bin:/bin"
|
||||
#endif
|
||||
|
||||
bozo_setenv(httpd, "PATH", _PATH_DEFPATH, curenvp++);
|
||||
bozo_setenv(httpd, "IFS", " \t\n", curenvp++);
|
||||
bozo_setenv(httpd, "SERVER_NAME", BOZOHOST(httpd,request), curenvp++);
|
||||
bozo_setenv(httpd, "GATEWAY_INTERFACE", "CGI/1.1", curenvp++);
|
||||
bozo_setenv(httpd, "SERVER_PROTOCOL", request->hr_proto, curenvp++);
|
||||
bozo_setenv(httpd, "REQUEST_METHOD", request->hr_methodstr, curenvp++);
|
||||
bozo_setenv(httpd, "SCRIPT_NAME", file, curenvp++);
|
||||
bozo_setenv(httpd, "SCRIPT_FILENAME", file + 1, curenvp++);
|
||||
bozo_setenv(httpd, "SERVER_SOFTWARE", httpd->server_software,
|
||||
curenvp++);
|
||||
bozo_setenv(httpd, "REQUEST_URI", uri, curenvp++);
|
||||
bozo_setenv(httpd, "DATE_GMT", bozo_http_date(date, sizeof(date)),
|
||||
curenvp++);
|
||||
if (query && *query)
|
||||
bozo_setenv(httpd, "QUERY_STRING", query, curenvp++);
|
||||
if (info && *info)
|
||||
bozo_setenv(httpd, "PATH_INFO", info, curenvp++);
|
||||
if (type && *type)
|
||||
bozo_setenv(httpd, "CONTENT_TYPE", type, curenvp++);
|
||||
if (clen && *clen)
|
||||
bozo_setenv(httpd, "CONTENT_LENGTH", clen, curenvp++);
|
||||
if (request->hr_serverport && *request->hr_serverport)
|
||||
bozo_setenv(httpd, "SERVER_PORT", request->hr_serverport,
|
||||
curenvp++);
|
||||
if (request->hr_remotehost && *request->hr_remotehost)
|
||||
bozo_setenv(httpd, "REMOTE_HOST", request->hr_remotehost,
|
||||
curenvp++);
|
||||
if (request->hr_remoteaddr && *request->hr_remoteaddr)
|
||||
bozo_setenv(httpd, "REMOTE_ADDR", request->hr_remoteaddr,
|
||||
curenvp++);
|
||||
/*
|
||||
* XXX Apache does this when invoking content handlers, and PHP
|
||||
* XXX 5.3 requires it as a "security" measure.
|
||||
*/
|
||||
if (cgihandler)
|
||||
bozo_setenv(httpd, "REDIRECT_STATUS", "200", curenvp++);
|
||||
bozo_auth_cgi_setenv(request, &curenvp);
|
||||
|
||||
free(file);
|
||||
free(url);
|
||||
|
||||
debug((httpd, DEBUG_FAT, "bozo_process_cgi: going exec %s, %s %s %s",
|
||||
path, argv[0], strornull(argv[1]), strornull(argv[2])));
|
||||
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sv) == -1)
|
||||
bozo_err(httpd, 1, "child socketpair failed: %s",
|
||||
strerror(errno));
|
||||
|
||||
/*
|
||||
* We create 2 procs: one to become the CGI, one read from
|
||||
* the CGI and output to the network, and this parent will
|
||||
* continue reading from the network and writing to the
|
||||
* CGI procsss.
|
||||
*/
|
||||
switch (fork()) {
|
||||
case -1: /* eep, failure */
|
||||
bozo_err(httpd, 1, "child fork failed: %s", strerror(errno));
|
||||
/*NOTREACHED*/
|
||||
case 0:
|
||||
close(sv[0]);
|
||||
dup2(sv[1], STDIN_FILENO);
|
||||
dup2(sv[1], STDOUT_FILENO);
|
||||
close(2);
|
||||
close(sv[1]);
|
||||
closelog();
|
||||
bozo_daemon_closefds(httpd);
|
||||
|
||||
if (-1 == execve(path, argv, envp))
|
||||
bozo_err(httpd, 1, "child exec failed: %s: %s",
|
||||
path, strerror(errno));
|
||||
/* NOT REACHED */
|
||||
bozo_err(httpd, 1, "child execve returned?!");
|
||||
}
|
||||
|
||||
close(sv[1]);
|
||||
|
||||
/* parent: read from stdin (bozo_read()) write to sv[0] */
|
||||
/* child: read from sv[0] (bozo_write()) write to stdout */
|
||||
pid = fork();
|
||||
if (pid == -1)
|
||||
bozo_err(httpd, 1, "io child fork failed: %s", strerror(errno));
|
||||
else if (pid == 0) {
|
||||
/* child reader/writer */
|
||||
close(STDIN_FILENO);
|
||||
finish_cgi_output(httpd, request, sv[0], nph);
|
||||
/* if we're done output, our parent is useless... */
|
||||
kill(getppid(), SIGKILL);
|
||||
debug((httpd, DEBUG_FAT, "done processing cgi output"));
|
||||
_exit(0);
|
||||
}
|
||||
close(STDOUT_FILENO);
|
||||
|
||||
/* XXX we should have some goo that times us out
|
||||
*/
|
||||
while ((rbytes = bozo_read(httpd, STDIN_FILENO, buf, sizeof buf)) > 0) {
|
||||
ssize_t wbytes;
|
||||
char *bp = buf;
|
||||
|
||||
while (rbytes) {
|
||||
wbytes = write(sv[0], buf, (size_t)rbytes);
|
||||
if (wbytes > 0) {
|
||||
rbytes -= wbytes;
|
||||
bp += wbytes;
|
||||
} else
|
||||
bozo_err(httpd, 1, "write failed: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
}
|
||||
debug((httpd, DEBUG_FAT, "done processing cgi input"));
|
||||
exit(0);
|
||||
|
||||
out:
|
||||
free(query);
|
||||
free(file);
|
||||
free(url);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef NO_DYNAMIC_CONTENT
|
||||
/* cgi maps are simple ".postfix /path/to/prog" */
|
||||
void
|
||||
bozo_add_content_map_cgi(bozohttpd_t *httpd, const char *arg, const char *cgihandler)
|
||||
{
|
||||
bozo_content_map_t *map;
|
||||
|
||||
debug((httpd, DEBUG_NORMAL, "bozo_add_content_map_cgi: name %s cgi %s",
|
||||
arg, cgihandler));
|
||||
|
||||
httpd->process_cgi = 1;
|
||||
|
||||
map = bozo_get_content_map(httpd, arg);
|
||||
map->name = arg;
|
||||
map->type = map->encoding = map->encoding11 = NULL;
|
||||
map->cgihandler = cgihandler;
|
||||
}
|
||||
#endif /* NO_DYNAMIC_CONTENT */
|
||||
|
||||
#endif /* NO_CGIBIN_SUPPORT */
|
||||
301
libexec/httpd/content-bozo.c
Normal file
301
libexec/httpd/content-bozo.c
Normal file
|
|
@ -0,0 +1,301 @@
|
|||
/* $NetBSD: content-bozo.c,v 1.12 2015/05/02 11:35:48 mrg Exp $ */
|
||||
|
||||
/* $eterna: content-bozo.c,v 1.17 2011/11/18 09:21:15 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997-2015 Matthew R. Green
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 and
|
||||
* dedication in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* this code implements content-type handling for bozohttpd */
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bozohttpd.h"
|
||||
|
||||
/*
|
||||
* this map and the functions below map between filenames and the
|
||||
* content type and content encoding definitions. this should become
|
||||
* a configuration file, perhaps like apache's mime.types (but that
|
||||
* has less info per-entry).
|
||||
*/
|
||||
|
||||
static bozo_content_map_t static_content_map[] = {
|
||||
{ ".html", "text/html", "", "", NULL },
|
||||
{ ".htm", "text/html", "", "", NULL },
|
||||
{ ".gif", "image/gif", "", "", NULL },
|
||||
{ ".jpeg", "image/jpeg", "", "", NULL },
|
||||
{ ".jpg", "image/jpeg", "", "", NULL },
|
||||
{ ".jpe", "image/jpeg", "", "", NULL },
|
||||
{ ".png", "image/png", "", "", NULL },
|
||||
{ ".mp3", "audio/mpeg", "", "", NULL },
|
||||
{ ".css", "text/css", "", "", NULL },
|
||||
{ ".txt", "text/plain", "", "", NULL },
|
||||
{ ".swf", "application/x-shockwave-flash","", "", NULL },
|
||||
{ ".dcr", "application/x-director", "", "", NULL },
|
||||
{ ".pac", "application/x-ns-proxy-autoconfig", "", "", NULL },
|
||||
{ ".pa", "application/x-ns-proxy-autoconfig", "", "", NULL },
|
||||
{ ".tar", "multipart/x-tar", "", "", NULL },
|
||||
{ ".gtar", "multipart/x-gtar", "", "", NULL },
|
||||
{ ".tar.Z", "multipart/x-tar", "x-compress", "compress", NULL },
|
||||
{ ".tar.gz", "multipart/x-tar", "x-gzip", "gzip", NULL },
|
||||
{ ".taz", "multipart/x-tar", "x-gzip", "gzip", NULL },
|
||||
{ ".tgz", "multipart/x-tar", "x-gzip", "gzip", NULL },
|
||||
{ ".tar.z", "multipart/x-tar", "x-pack", "x-pack", NULL },
|
||||
{ ".Z", "application/x-compress", "x-compress", "compress", NULL },
|
||||
{ ".gz", "application/x-gzip", "x-gzip", "gzip", NULL },
|
||||
{ ".z", "unknown", "x-pack", "x-pack", NULL },
|
||||
{ ".bz2", "application/x-bzip2", "x-bzip2", "x-bzip2", NULL },
|
||||
{ ".ogg", "application/x-ogg", "", "", NULL },
|
||||
{ ".mkv", "video/x-matroska", "", "", NULL },
|
||||
{ ".xbel", "text/xml", "", "", NULL },
|
||||
{ ".xml", "text/xml", "", "", NULL },
|
||||
{ ".xsl", "text/xml", "", "", NULL },
|
||||
{ ".hqx", "application/mac-binhex40", "", "", NULL },
|
||||
{ ".cpt", "application/mac-compactpro", "", "", NULL },
|
||||
{ ".doc", "application/msword", "", "", NULL },
|
||||
{ ".bin", "application/octet-stream", "", "", NULL },
|
||||
{ ".dms", "application/octet-stream", "", "", NULL },
|
||||
{ ".lha", "application/octet-stream", "", "", NULL },
|
||||
{ ".lzh", "application/octet-stream", "", "", NULL },
|
||||
{ ".exe", "application/octet-stream", "", "", NULL },
|
||||
{ ".class", "application/octet-stream", "", "", NULL },
|
||||
{ ".oda", "application/oda", "", "", NULL },
|
||||
{ ".pdf", "application/pdf", "", "", NULL },
|
||||
{ ".ai", "application/postscript", "", "", NULL },
|
||||
{ ".eps", "application/postscript", "", "", NULL },
|
||||
{ ".ps", "application/postscript", "", "", NULL },
|
||||
{ ".ppt", "application/powerpoint", "", "", NULL },
|
||||
{ ".rtf", "application/rtf", "", "", NULL },
|
||||
{ ".bcpio", "application/x-bcpio", "", "", NULL },
|
||||
{ ".torrent", "application/x-bittorrent", "", "", NULL },
|
||||
{ ".vcd", "application/x-cdlink", "", "", NULL },
|
||||
{ ".cpio", "application/x-cpio", "", "", NULL },
|
||||
{ ".csh", "application/x-csh", "", "", NULL },
|
||||
{ ".dir", "application/x-director", "", "", NULL },
|
||||
{ ".dxr", "application/x-director", "", "", NULL },
|
||||
{ ".dvi", "application/x-dvi", "", "", NULL },
|
||||
{ ".hdf", "application/x-hdf", "", "", NULL },
|
||||
{ ".cgi", "application/x-httpd-cgi", "", "", NULL },
|
||||
{ ".skp", "application/x-koan", "", "", NULL },
|
||||
{ ".skd", "application/x-koan", "", "", NULL },
|
||||
{ ".skt", "application/x-koan", "", "", NULL },
|
||||
{ ".skm", "application/x-koan", "", "", NULL },
|
||||
{ ".latex", "application/x-latex", "", "", NULL },
|
||||
{ ".mif", "application/x-mif", "", "", NULL },
|
||||
{ ".nc", "application/x-netcdf", "", "", NULL },
|
||||
{ ".cdf", "application/x-netcdf", "", "", NULL },
|
||||
{ ".patch", "application/x-patch", "", "", NULL },
|
||||
{ ".sh", "application/x-sh", "", "", NULL },
|
||||
{ ".shar", "application/x-shar", "", "", NULL },
|
||||
{ ".sit", "application/x-stuffit", "", "", NULL },
|
||||
{ ".sv4cpio", "application/x-sv4cpio", "", "", NULL },
|
||||
{ ".sv4crc", "application/x-sv4crc", "", "", NULL },
|
||||
{ ".tar", "application/x-tar", "", "", NULL },
|
||||
{ ".tcl", "application/x-tcl", "", "", NULL },
|
||||
{ ".tex", "application/x-tex", "", "", NULL },
|
||||
{ ".texinfo", "application/x-texinfo", "", "", NULL },
|
||||
{ ".texi", "application/x-texinfo", "", "", NULL },
|
||||
{ ".t", "application/x-troff", "", "", NULL },
|
||||
{ ".tr", "application/x-troff", "", "", NULL },
|
||||
{ ".roff", "application/x-troff", "", "", NULL },
|
||||
{ ".man", "application/x-troff-man", "", "", NULL },
|
||||
{ ".me", "application/x-troff-me", "", "", NULL },
|
||||
{ ".ms", "application/x-troff-ms", "", "", NULL },
|
||||
{ ".ustar", "application/x-ustar", "", "", NULL },
|
||||
{ ".src", "application/x-wais-source", "", "", NULL },
|
||||
{ ".zip", "application/zip", "", "", NULL },
|
||||
{ ".au", "audio/basic", "", "", NULL },
|
||||
{ ".snd", "audio/basic", "", "", NULL },
|
||||
{ ".mpga", "audio/mpeg", "", "", NULL },
|
||||
{ ".mp2", "audio/mpeg", "", "", NULL },
|
||||
{ ".aif", "audio/x-aiff", "", "", NULL },
|
||||
{ ".aiff", "audio/x-aiff", "", "", NULL },
|
||||
{ ".aifc", "audio/x-aiff", "", "", NULL },
|
||||
{ ".ram", "audio/x-pn-realaudio", "", "", NULL },
|
||||
{ ".rpm", "audio/x-pn-realaudio-plugin", "", "", NULL },
|
||||
{ ".ra", "audio/x-realaudio", "", "", NULL },
|
||||
{ ".wav", "audio/x-wav", "", "", NULL },
|
||||
{ ".pdb", "chemical/x-pdb", "", "", NULL },
|
||||
{ ".xyz", "chemical/x-pdb", "", "", NULL },
|
||||
{ ".ief", "image/ief", "", "", NULL },
|
||||
{ ".tiff", "image/tiff", "", "", NULL },
|
||||
{ ".tif", "image/tiff", "", "", NULL },
|
||||
{ ".ras", "image/x-cmu-raster", "", "", NULL },
|
||||
{ ".pnm", "image/x-portable-anymap", "", "", NULL },
|
||||
{ ".pbm", "image/x-portable-bitmap", "", "", NULL },
|
||||
{ ".pgm", "image/x-portable-graymap", "", "", NULL },
|
||||
{ ".ppm", "image/x-portable-pixmap", "", "", NULL },
|
||||
{ ".rgb", "image/x-rgb", "", "", NULL },
|
||||
{ ".xbm", "image/x-xbitmap", "", "", NULL },
|
||||
{ ".xpm", "image/x-xpixmap", "", "", NULL },
|
||||
{ ".xwd", "image/x-xwindowdump", "", "", NULL },
|
||||
{ ".rtx", "text/richtext", "", "", NULL },
|
||||
{ ".tsv", "text/tab-separated-values", "", "", NULL },
|
||||
{ ".etx", "text/x-setext", "", "", NULL },
|
||||
{ ".sgml", "text/x-sgml", "", "", NULL },
|
||||
{ ".sgm", "text/x-sgml", "", "", NULL },
|
||||
{ ".mpeg", "video/mpeg", "", "", NULL },
|
||||
{ ".mpg", "video/mpeg", "", "", NULL },
|
||||
{ ".mpe", "video/mpeg", "", "", NULL },
|
||||
{ ".ts", "video/mpeg", "", "", NULL },
|
||||
{ ".vob", "video/mpeg", "", "", NULL },
|
||||
{ ".mp4", "video/mp4", "", "", NULL },
|
||||
{ ".qt", "video/quicktime", "", "", NULL },
|
||||
{ ".mov", "video/quicktime", "", "", NULL },
|
||||
{ ".avi", "video/x-msvideo", "", "", NULL },
|
||||
{ ".movie", "video/x-sgi-movie", "", "", NULL },
|
||||
{ ".ice", "x-conference/x-cooltalk", "", "", NULL },
|
||||
{ ".wrl", "x-world/x-vrml", "", "", NULL },
|
||||
{ ".vrml", "x-world/x-vrml", "", "", NULL },
|
||||
{ ".svg", "image/svg+xml", "", "", NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
static bozo_content_map_t *
|
||||
search_map(bozo_content_map_t *map, const char *name, size_t len)
|
||||
{
|
||||
for ( ; map && map->name; map++) {
|
||||
const size_t namelen = strlen(map->name);
|
||||
|
||||
if (namelen < len &&
|
||||
strcasecmp(map->name, name + (len - namelen)) == 0)
|
||||
return map;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* match a suffix on a file - dynamiconly means no static content search */
|
||||
bozo_content_map_t *
|
||||
bozo_match_content_map(bozohttpd_t *httpd, const char *name,
|
||||
const int dynamiconly)
|
||||
{
|
||||
bozo_content_map_t *map;
|
||||
size_t len;
|
||||
|
||||
len = strlen(name);
|
||||
if ((map = search_map(httpd->dynamic_content_map, name, len)) != NULL) {
|
||||
return map;
|
||||
}
|
||||
if (!dynamiconly) {
|
||||
if ((map = search_map(static_content_map, name, len)) != NULL) {
|
||||
return map;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* given the file name, return a valid Content-Type: value.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
const char *
|
||||
bozo_content_type(bozo_httpreq_t *request, const char *file)
|
||||
{
|
||||
bozohttpd_t *httpd = request->hr_httpd;
|
||||
bozo_content_map_t *map;
|
||||
|
||||
map = bozo_match_content_map(httpd, file, 0);
|
||||
if (map)
|
||||
return map->type;
|
||||
return httpd->consts.text_plain;
|
||||
}
|
||||
|
||||
/*
|
||||
* given the file name, return a valid Content-Encoding: value.
|
||||
*/
|
||||
const char *
|
||||
bozo_content_encoding(bozo_httpreq_t *request, const char *file)
|
||||
{
|
||||
bozohttpd_t *httpd = request->hr_httpd;
|
||||
bozo_content_map_t *map;
|
||||
|
||||
map = bozo_match_content_map(httpd, file, 0);
|
||||
if (map)
|
||||
return (request->hr_proto == httpd->consts.http_11) ?
|
||||
map->encoding11 : map->encoding;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef NO_DYNAMIC_CONTENT
|
||||
|
||||
bozo_content_map_t *
|
||||
bozo_get_content_map(bozohttpd_t *httpd, const char *name)
|
||||
{
|
||||
bozo_content_map_t *map;
|
||||
|
||||
if ((map = bozo_match_content_map(httpd, name, 1)) != NULL)
|
||||
return map;
|
||||
|
||||
httpd->dynamic_content_map_size++;
|
||||
httpd->dynamic_content_map = bozorealloc(httpd,
|
||||
httpd->dynamic_content_map,
|
||||
(httpd->dynamic_content_map_size + 1) * sizeof *map);
|
||||
if (httpd->dynamic_content_map == NULL)
|
||||
bozo_err(httpd, 1, "out of memory allocating content map");
|
||||
map = &httpd->dynamic_content_map[httpd->dynamic_content_map_size];
|
||||
map->name = map->type = map->encoding = map->encoding11 =
|
||||
map->cgihandler = NULL;
|
||||
map--;
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
/*
|
||||
* mime content maps look like:
|
||||
* ".name type encoding encoding11"
|
||||
* where any of type, encoding or encoding11 a dash "-" means "".
|
||||
* eg the .gtar, .tar.Z from above could be written like:
|
||||
* ".gtar multipart/x-gtar - -"
|
||||
* ".tar.Z multipart/x-tar x-compress compress"
|
||||
* or
|
||||
* ".gtar multipart/x-gtar"
|
||||
* ".tar.Z multipart/x-tar x-compress compress"
|
||||
* NOTE: we destroy 'arg'
|
||||
*/
|
||||
void
|
||||
bozo_add_content_map_mime(bozohttpd_t *httpd, const char *cmap0,
|
||||
const char *cmap1, const char *cmap2, const char *cmap3)
|
||||
{
|
||||
bozo_content_map_t *map;
|
||||
|
||||
debug((httpd, DEBUG_FAT,
|
||||
"add_content_map: name %s type %s enc %s enc11 %s ",
|
||||
cmap0, cmap1, cmap2, cmap3));
|
||||
|
||||
map = bozo_get_content_map(httpd, cmap0);
|
||||
#define CHECKMAP(s) (!s || ((s)[0] == '-' && (s)[1] == '\0') ? "" : (s))
|
||||
map->name = CHECKMAP(cmap0);
|
||||
map->type = CHECKMAP(cmap1);
|
||||
map->encoding = CHECKMAP(cmap2);
|
||||
map->encoding11 = CHECKMAP(cmap3);
|
||||
#undef CHECKMAP
|
||||
map->cgihandler = NULL;
|
||||
}
|
||||
#endif /* NO_DYNAMIC_CONTENT */
|
||||
339
libexec/httpd/daemon-bozo.c
Normal file
339
libexec/httpd/daemon-bozo.c
Normal file
|
|
@ -0,0 +1,339 @@
|
|||
/* $NetBSD: daemon-bozo.c,v 1.16 2014/01/02 08:21:38 mrg Exp $ */
|
||||
|
||||
/* $eterna: daemon-bozo.c,v 1.24 2011/11/18 09:21:15 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997-2014 Matthew R. Green
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 and
|
||||
* dedication in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* this code implements daemon mode for bozohttpd */
|
||||
|
||||
#ifndef NO_DAEMON_MODE
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <poll.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "bozohttpd.h"
|
||||
|
||||
static void sigchild(int); /* SIGCHLD handler */
|
||||
|
||||
#ifndef POLLRDNORM
|
||||
#define POLLRDNORM 0
|
||||
#endif
|
||||
#ifndef POLLRDBAND
|
||||
#define POLLRDBAND 0
|
||||
#endif
|
||||
#ifndef INFTIM
|
||||
#define INFTIM -1
|
||||
#endif
|
||||
|
||||
static const char* pidfile_path = NULL;
|
||||
static pid_t pidfile_pid = 0;
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
sigchild(int signo)
|
||||
{
|
||||
while (waitpid(-1, NULL, WNOHANG) > 0) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Signal handler to exit in a controlled manner. This ensures that
|
||||
* any atexit(3) handlers are properly executed. */
|
||||
/* ARGSUSED */
|
||||
BOZO_DEAD static void
|
||||
controlled_exit(int signo)
|
||||
{
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
remove_pidfile(void)
|
||||
{
|
||||
|
||||
if (pidfile_path != NULL && pidfile_pid == getpid()) {
|
||||
(void)unlink(pidfile_path);
|
||||
pidfile_path = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
create_pidfile(bozohttpd_t *httpd)
|
||||
{
|
||||
FILE *file;
|
||||
|
||||
assert(pidfile_path == NULL);
|
||||
|
||||
if (httpd->pidfile == NULL)
|
||||
return;
|
||||
|
||||
if (atexit(remove_pidfile) == -1)
|
||||
bozo_err(httpd, 1, "Failed to install pidfile handler");
|
||||
|
||||
if ((file = fopen(httpd->pidfile, "w")) == NULL)
|
||||
bozo_err(httpd, 1, "Failed to create pidfile '%s'",
|
||||
httpd->pidfile);
|
||||
(void)fprintf(file, "%d\n", getpid());
|
||||
(void)fclose(file);
|
||||
|
||||
pidfile_path = httpd->pidfile;
|
||||
pidfile_pid = getpid();
|
||||
|
||||
debug((httpd, DEBUG_FAT, "Created pid file '%s' for pid %d",
|
||||
pidfile_path, pidfile_pid));
|
||||
}
|
||||
|
||||
void
|
||||
bozo_daemon_init(bozohttpd_t *httpd)
|
||||
{
|
||||
struct addrinfo h, *r, *r0;
|
||||
const char *portnum;
|
||||
int e, i, on = 1;
|
||||
|
||||
if (!httpd->background)
|
||||
return;
|
||||
|
||||
portnum = (httpd->bindport) ? httpd->bindport : "http";
|
||||
|
||||
memset(&h, 0, sizeof(h));
|
||||
h.ai_family = PF_UNSPEC;
|
||||
h.ai_socktype = SOCK_STREAM;
|
||||
h.ai_flags = AI_PASSIVE;
|
||||
e = getaddrinfo(httpd->bindaddress, portnum, &h, &r0);
|
||||
if (e)
|
||||
bozo_err(httpd, 1, "getaddrinfo([%s]:%s): %s",
|
||||
httpd->bindaddress ? httpd->bindaddress : "*",
|
||||
portnum, gai_strerror(e));
|
||||
for (r = r0; r != NULL; r = r->ai_next)
|
||||
httpd->nsock++;
|
||||
httpd->sock = bozomalloc(httpd, httpd->nsock * sizeof(*httpd->sock));
|
||||
httpd->fds = bozomalloc(httpd, httpd->nsock * sizeof(*httpd->fds));
|
||||
for (i = 0, r = r0; r != NULL; r = r->ai_next) {
|
||||
httpd->sock[i] = socket(r->ai_family, SOCK_STREAM, 0);
|
||||
if (httpd->sock[i] == -1)
|
||||
continue;
|
||||
if (setsockopt(httpd->sock[i], SOL_SOCKET, SO_REUSEADDR, &on,
|
||||
sizeof(on)) == -1)
|
||||
bozo_warn(httpd, "setsockopt SO_REUSEADDR: %s",
|
||||
strerror(errno));
|
||||
if (bind(httpd->sock[i], r->ai_addr, r->ai_addrlen) == -1)
|
||||
continue;
|
||||
if (listen(httpd->sock[i], SOMAXCONN) == -1)
|
||||
continue;
|
||||
httpd->fds[i].events = POLLIN | POLLPRI | POLLRDNORM |
|
||||
POLLRDBAND | POLLERR;
|
||||
httpd->fds[i].fd = httpd->sock[i];
|
||||
i++;
|
||||
}
|
||||
if (i == 0)
|
||||
bozo_err(httpd, 1, "could not find any addresses to bind");
|
||||
httpd->nsock = i;
|
||||
freeaddrinfo(r0);
|
||||
|
||||
if (httpd->foreground == 0)
|
||||
daemon(1, 0);
|
||||
|
||||
create_pidfile(httpd);
|
||||
|
||||
bozo_warn(httpd, "started in daemon mode as `%s' port `%s' root `%s'",
|
||||
httpd->virthostname, portnum, httpd->slashdir);
|
||||
|
||||
signal(SIGHUP, controlled_exit);
|
||||
signal(SIGINT, controlled_exit);
|
||||
signal(SIGTERM, controlled_exit);
|
||||
|
||||
signal(SIGCHLD, sigchild);
|
||||
}
|
||||
|
||||
void
|
||||
bozo_daemon_closefds(bozohttpd_t *httpd)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < httpd->nsock; i++)
|
||||
close(httpd->sock[i]);
|
||||
}
|
||||
|
||||
static void
|
||||
daemon_runchild(bozohttpd_t *httpd, int fd)
|
||||
{
|
||||
httpd->request_times++;
|
||||
|
||||
/* setup stdin/stdout/stderr */
|
||||
dup2(fd, 0);
|
||||
dup2(fd, 1);
|
||||
/*dup2(fd, 2);*/
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static int
|
||||
daemon_poll_err(bozohttpd_t *httpd, int fd, int idx)
|
||||
{
|
||||
if ((httpd->fds[idx].revents & (POLLNVAL|POLLERR|POLLHUP)) == 0)
|
||||
return 0;
|
||||
|
||||
bozo_warn(httpd, "poll on fd %d pid %d revents %d: %s",
|
||||
httpd->fds[idx].fd, getpid(), httpd->fds[idx].revents,
|
||||
strerror(errno));
|
||||
bozo_warn(httpd, "nsock = %d", httpd->nsock);
|
||||
close(httpd->sock[idx]);
|
||||
httpd->nsock--;
|
||||
bozo_warn(httpd, "nsock now = %d", httpd->nsock);
|
||||
/* no sockets left */
|
||||
if (httpd->nsock == 0)
|
||||
exit(0);
|
||||
/* last socket closed is the easy case */
|
||||
if (httpd->nsock != idx) {
|
||||
memmove(&httpd->fds[idx], &httpd->fds[idx+1],
|
||||
(httpd->nsock - idx) * sizeof(*httpd->fds));
|
||||
memmove(&httpd->sock[idx], &httpd->sock[idx+1],
|
||||
(httpd->nsock - idx) * sizeof(*httpd->sock));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* the parent never returns from this function, only children that
|
||||
* are ready to run... XXXMRG - still true in fork-lesser bozo?
|
||||
*/
|
||||
int
|
||||
bozo_daemon_fork(bozohttpd_t *httpd)
|
||||
{
|
||||
int i;
|
||||
|
||||
debug((httpd, DEBUG_FAT, "%s: pid %u request_times %d",
|
||||
__func__, getpid(),
|
||||
httpd->request_times));
|
||||
/* if we've handled 5 files, exit and let someone else work */
|
||||
if (httpd->request_times > 5 ||
|
||||
(httpd->background == 2 && httpd->request_times > 0))
|
||||
_exit(0);
|
||||
|
||||
#if 1
|
||||
if (httpd->request_times > 0)
|
||||
_exit(0);
|
||||
#endif
|
||||
|
||||
while (httpd->background) {
|
||||
struct sockaddr_storage ss;
|
||||
socklen_t slen;
|
||||
int fd;
|
||||
|
||||
if (httpd->nsock == 0)
|
||||
exit(0);
|
||||
|
||||
/*
|
||||
* wait for a connection, then fork() and return NULL in
|
||||
* the parent, who will come back here waiting for another
|
||||
* connection. read the request in in the child, and return
|
||||
* it, for processing.
|
||||
*/
|
||||
again:
|
||||
if (poll(httpd->fds, (unsigned)httpd->nsock, INFTIM) == -1) {
|
||||
/* fail on programmer errors */
|
||||
if (errno == EFAULT ||
|
||||
errno == EINVAL)
|
||||
bozo_err(httpd, 1, "poll: %s",
|
||||
strerror(errno));
|
||||
|
||||
/* sleep on some temporary kernel failures */
|
||||
if (errno == ENOMEM ||
|
||||
errno == EAGAIN)
|
||||
sleep(1);
|
||||
|
||||
goto again;
|
||||
}
|
||||
|
||||
for (i = 0; i < httpd->nsock; i++) {
|
||||
if (daemon_poll_err(httpd, fd, i))
|
||||
break;
|
||||
if (httpd->fds[i].revents == 0)
|
||||
continue;
|
||||
|
||||
slen = sizeof(ss);
|
||||
fd = accept(httpd->fds[i].fd,
|
||||
(struct sockaddr *)(void *)&ss, &slen);
|
||||
if (fd == -1) {
|
||||
if (errno == EFAULT ||
|
||||
errno == EINVAL)
|
||||
bozo_err(httpd, 1, "accept: %s",
|
||||
strerror(errno));
|
||||
|
||||
if (errno == ENOMEM ||
|
||||
errno == EAGAIN)
|
||||
sleep(1);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* This code doesn't work. It interacts very poorly
|
||||
* with ~user translation and needs to be fixed.
|
||||
*/
|
||||
if (httpd->request_times > 0) {
|
||||
daemon_runchild(httpd, fd);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (fork()) {
|
||||
case -1: /* eep, failure */
|
||||
bozo_warn(httpd, "fork() failed, sleeping for "
|
||||
"10 seconds: %s", strerror(errno));
|
||||
close(fd);
|
||||
sleep(10);
|
||||
break;
|
||||
|
||||
case 0: /* child */
|
||||
daemon_runchild(httpd, fd);
|
||||
return 0;
|
||||
|
||||
default: /* parent */
|
||||
close(fd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* NO_DAEMON_MODE */
|
||||
9
libexec/httpd/debug/Makefile
Normal file
9
libexec/httpd/debug/Makefile
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# $eterna: Makefile,v 1.1 2009/05/22 21:51:39 mrg Exp $
|
||||
|
||||
# build a debug bozohttpd
|
||||
PROG= bozohttpd-debug
|
||||
COPTS+= -DDEBUG -I$(.CURDIR)/..
|
||||
|
||||
.include "../Makefile"
|
||||
|
||||
.PATH: $(.CURDIR)/..
|
||||
212
libexec/httpd/dir-index-bozo.c
Normal file
212
libexec/httpd/dir-index-bozo.c
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
/* $NetBSD: dir-index-bozo.c,v 1.21 2015/08/27 17:12:18 mrg Exp $ */
|
||||
|
||||
/* $eterna: dir-index-bozo.c,v 1.20 2011/11/18 09:21:15 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997-2014 Matthew R. Green
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 and
|
||||
* dedication in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* this code implements directory index generation for bozohttpd */
|
||||
|
||||
#ifndef NO_DIRINDEX_SUPPORT
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "bozohttpd.h"
|
||||
|
||||
static void
|
||||
directory_hr(bozohttpd_t *httpd)
|
||||
{
|
||||
|
||||
bozo_printf(httpd,
|
||||
"<hr noshade align=\"left\" width=\"80%%\">\r\n\r\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* output a directory index. return 1 if it actually did something..
|
||||
*/
|
||||
int
|
||||
bozo_dir_index(bozo_httpreq_t *request, const char *dirpath, int isindex)
|
||||
{
|
||||
bozohttpd_t *httpd = request->hr_httpd;
|
||||
struct stat sb;
|
||||
struct dirent **de, **deo;
|
||||
struct tm *tm;
|
||||
DIR *dp;
|
||||
char buf[MAXPATHLEN];
|
||||
char spacebuf[48];
|
||||
char *file = NULL;
|
||||
int l, k, j, i;
|
||||
|
||||
if (!isindex || !httpd->dir_indexing)
|
||||
return 0;
|
||||
|
||||
if (strlen(dirpath) <= strlen(httpd->index_html))
|
||||
dirpath = ".";
|
||||
else {
|
||||
file = bozostrdup(httpd, dirpath);
|
||||
|
||||
file[strlen(file) - strlen(httpd->index_html)] = '\0';
|
||||
dirpath = file;
|
||||
}
|
||||
debug((httpd, DEBUG_FAT, "bozo_dir_index: dirpath ``%s''", dirpath));
|
||||
if (stat(dirpath, &sb) < 0 ||
|
||||
(dp = opendir(dirpath)) == NULL) {
|
||||
if (errno == EPERM)
|
||||
(void)bozo_http_error(httpd, 403, request,
|
||||
"no permission to open directory");
|
||||
else if (errno == ENOENT)
|
||||
(void)bozo_http_error(httpd, 404, request, "no file");
|
||||
else
|
||||
(void)bozo_http_error(httpd, 500, request,
|
||||
"open directory");
|
||||
goto done;
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
bozo_printf(httpd, "%s 200 OK\r\n", request->hr_proto);
|
||||
|
||||
if (request->hr_proto != httpd->consts.http_09) {
|
||||
bozo_print_header(request, NULL, "text/html", "");
|
||||
bozo_printf(httpd, "\r\n");
|
||||
}
|
||||
bozo_flush(httpd, stdout);
|
||||
|
||||
if (request->hr_method == HTTP_HEAD) {
|
||||
closedir(dp);
|
||||
goto done;
|
||||
}
|
||||
|
||||
bozo_printf(httpd,
|
||||
"<html><head><title>Index of %s</title></head>\r\n",
|
||||
request->hr_file);
|
||||
bozo_printf(httpd, "<body><h1>Index of %s</h1>\r\n",
|
||||
request->hr_file);
|
||||
bozo_printf(httpd, "<pre>\r\n");
|
||||
#define NAMELEN 40
|
||||
#define LMODLEN 19
|
||||
bozo_printf(httpd, "Name "
|
||||
"Last modified "
|
||||
"Size\n");
|
||||
bozo_printf(httpd, "</pre>");
|
||||
directory_hr(httpd);
|
||||
bozo_printf(httpd, "<pre>");
|
||||
|
||||
for (j = k = scandir(dirpath, &de, NULL, alphasort), deo = de;
|
||||
j--; de++) {
|
||||
int nostat = 0;
|
||||
char *name = (*de)->d_name;
|
||||
char *urlname, *htmlname;
|
||||
|
||||
if (strcmp(name, ".") == 0 ||
|
||||
(strcmp(name, "..") != 0 &&
|
||||
httpd->hide_dots && name[0] == '.'))
|
||||
continue;
|
||||
|
||||
snprintf(buf, sizeof buf, "%s/%s", dirpath, name);
|
||||
if (stat(buf, &sb))
|
||||
nostat = 1;
|
||||
|
||||
l = 0;
|
||||
|
||||
urlname = bozo_escape_rfc3986(httpd, name);
|
||||
htmlname = bozo_escape_html(httpd, name);
|
||||
if (htmlname == NULL)
|
||||
htmlname = name;
|
||||
if (strcmp(name, "..") == 0) {
|
||||
bozo_printf(httpd, "<a href=\"../\">");
|
||||
l += bozo_printf(httpd, "Parent Directory");
|
||||
} else if (S_ISDIR(sb.st_mode)) {
|
||||
bozo_printf(httpd, "<a href=\"%s/\">", urlname);
|
||||
l += bozo_printf(httpd, "%s/", htmlname);
|
||||
} else if (strchr(name, ':') != NULL) {
|
||||
/* RFC 3986 4.2 */
|
||||
bozo_printf(httpd, "<a href=\"./%s\">", urlname);
|
||||
l += bozo_printf(httpd, "%s", htmlname);
|
||||
} else {
|
||||
bozo_printf(httpd, "<a href=\"%s\">", urlname);
|
||||
l += bozo_printf(httpd, "%s", htmlname);
|
||||
}
|
||||
if (htmlname != name)
|
||||
free(htmlname);
|
||||
bozo_printf(httpd, "</a>");
|
||||
|
||||
/* NAMELEN spaces */
|
||||
/*LINTED*/
|
||||
assert(/*CONSTCOND*/sizeof(spacebuf) > NAMELEN);
|
||||
i = (l < NAMELEN) ? (NAMELEN - l) : 0;
|
||||
i++;
|
||||
memset(spacebuf, ' ', (size_t)i);
|
||||
spacebuf[i] = '\0';
|
||||
bozo_printf(httpd, "%s", spacebuf);
|
||||
l += i;
|
||||
|
||||
if (nostat)
|
||||
bozo_printf(httpd, "? ?");
|
||||
else {
|
||||
tm = gmtime(&sb.st_mtime);
|
||||
strftime(buf, sizeof buf, "%d-%b-%Y %R", tm);
|
||||
l += bozo_printf(httpd, "%s", buf);
|
||||
|
||||
/* LMODLEN spaces */
|
||||
/*LINTED*/
|
||||
assert(/*CONSTCOND*/sizeof(spacebuf) > LMODLEN);
|
||||
i = (l < (LMODLEN+NAMELEN+1)) ?
|
||||
((LMODLEN+NAMELEN+1) - l) : 0;
|
||||
i++;
|
||||
memset(spacebuf, ' ', (size_t)i);
|
||||
spacebuf[i] = '\0';
|
||||
bozo_printf(httpd, "%s", spacebuf);
|
||||
|
||||
bozo_printf(httpd, "%12llukB",
|
||||
(unsigned long long)sb.st_size >> 10);
|
||||
}
|
||||
bozo_printf(httpd, "\r\n");
|
||||
}
|
||||
|
||||
closedir(dp);
|
||||
while (k--)
|
||||
free(deo[k]);
|
||||
free(deo);
|
||||
bozo_printf(httpd, "</pre>");
|
||||
directory_hr(httpd);
|
||||
bozo_printf(httpd, "</body></html>\r\n\r\n");
|
||||
bozo_flush(httpd, stdout);
|
||||
|
||||
done:
|
||||
free(file);
|
||||
return 1;
|
||||
}
|
||||
#endif /* NO_DIRINDEX_SUPPORT */
|
||||
|
||||
37
libexec/httpd/libbozohttpd/Makefile
Normal file
37
libexec/httpd/libbozohttpd/Makefile
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
# $eterna: Makefile,v 1.1 2010/05/10 02:24:31 mrg Exp $
|
||||
|
||||
.PATH: $(.CURDIR)/..
|
||||
|
||||
# build bozohttpd library
|
||||
LIB= bozohttpd
|
||||
COPTS+= -I$(.CURDIR)/..
|
||||
|
||||
COPTS+= -DDO_HTPASSWD
|
||||
CPPFLAGS+= -DDO_HTPASSWD
|
||||
SRCS= bozohttpd.c ssl-bozo.c auth-bozo.c cgi-bozo.c daemon-bozo.c
|
||||
SRCS+= tilde-luzah-bozo.c dir-index-bozo.c content-bozo.c
|
||||
SRCS+= lua-bozo.c
|
||||
|
||||
LDADD= -lcrypt
|
||||
DPADD= ${LIBCRYPT}
|
||||
|
||||
MAN= libbozohttpd.3
|
||||
WARNS= 4
|
||||
|
||||
INCS= bozohttpd.h
|
||||
INCSDIR= /usr/include
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
.if ${MKCRYPTO} != "no"
|
||||
|
||||
LDADD+= -lssl -lcrypto
|
||||
DPADD+= ${LIBSSL} ${LIBCRYPTO}
|
||||
|
||||
.else
|
||||
|
||||
COPTS+= -DNO_SSL_SUPPORT
|
||||
|
||||
.endif
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
143
libexec/httpd/libbozohttpd/libbozohttpd.3
Normal file
143
libexec/httpd/libbozohttpd/libbozohttpd.3
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
.\" $NetBSD: libbozohttpd.3,v 1.3 2014/03/18 18:20:38 riastradh Exp $
|
||||
.\"
|
||||
.\" $eterna: libbozohttpd.3,v 1.2 2010/05/10 02:48:23 mrg Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This manual page 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.
|
||||
.\"
|
||||
.Dd November 5, 2009
|
||||
.Dt LIBBOZOHTTPD 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm libbozohttpd
|
||||
.Nd embedded web server library
|
||||
.Sh LIBRARY
|
||||
.Lb libbozohttpd
|
||||
.Sh SYNOPSIS
|
||||
.In bozohttpd.h
|
||||
.Ft int
|
||||
.Fo bozo_set_pref
|
||||
.Fa "bozoprefs_t *prefs" "char *name" "char *value"
|
||||
.Fc
|
||||
.Ft char *
|
||||
.Fo bozo_get_pref
|
||||
.Fa "bozoprefs_t *prefs" "char *name"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo bozo_set_defaults
|
||||
.Fa "bozohttpd_t *httpd" "bozoprefs_t *prefs"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo bozo_setup
|
||||
.Fa "bozohttpd_t *httpd" "bozoprefs_t *prefs" "const char *vhost" "char *slash"
|
||||
.Fc
|
||||
.Ft bozo_httpreq_t *
|
||||
.Fo bozo_read_request
|
||||
.Fa "bozohttpd_t *httpd"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo bozo_process_request
|
||||
.Fa "bozo_httpreq_t *"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo bozo_clean_request
|
||||
.Fa "bozo_httpreq_t *"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
is a library interface to the
|
||||
.Xr bozohttpd 8
|
||||
web server.
|
||||
The
|
||||
.Nm
|
||||
library can be used to embed a webserver
|
||||
in your applications.
|
||||
.Pp
|
||||
Normal operation sees the
|
||||
.Nm
|
||||
process be initialised using the
|
||||
.Fn bozo_set_defaults
|
||||
function, which will set up the default port
|
||||
and other internal settings, allocating
|
||||
any necessary space as needed.
|
||||
The
|
||||
.Fn bozo_set_defaults
|
||||
function returns 1 on sucess, 0 on failure.
|
||||
.Pp
|
||||
The
|
||||
.Fn bozo_setup
|
||||
function is used to specify the virtual host name
|
||||
for the web server.
|
||||
A NULL host name will mean that
|
||||
.Nm
|
||||
will use the local value for the host name,
|
||||
as returned by
|
||||
.Xr gethostname 3 .
|
||||
This virtual hostname should be a fully qualified domain name.
|
||||
The final argument to
|
||||
.Fn bozo_setup
|
||||
is the name of the directory to serve as the root
|
||||
directory of the web server tree.
|
||||
.Pp
|
||||
Once the server has been set up, it serves
|
||||
requests by using the
|
||||
.Fn bozo_read_request
|
||||
function, which returns a pointer to a request structure,
|
||||
and
|
||||
.Fn bozo_process_request ,
|
||||
which deals with the request, and answers the client.
|
||||
The request space is de-allocated
|
||||
using the
|
||||
.Fn bozo_clean_request
|
||||
function.
|
||||
.Pp
|
||||
Preferences are set
|
||||
using the function
|
||||
.Fn bozo_set_pref
|
||||
function
|
||||
and queried using the two
|
||||
.Fn bozo_get_pref
|
||||
function.
|
||||
This is the main interface for selecting options, and for
|
||||
setting preferences.
|
||||
.Sh SEE ALSO
|
||||
.Xr gethostname 3 ,
|
||||
.Xr ssl 3 ,
|
||||
.Xr services 5 ,
|
||||
.Xr httpd 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
library first appeared in
|
||||
.Nx 6.0 .
|
||||
.Sh AUTHORS
|
||||
.An Matthew R. Green Aq Mt mrg@eterna.com.au
|
||||
.An Alistair Crooks Aq Mt agc@NetBSD.org
|
||||
wrote this high-level interface.
|
||||
.Pp
|
||||
This manual page was written by
|
||||
.An Alistair Crooks .
|
||||
2
libexec/httpd/libbozohttpd/shlib_version
Normal file
2
libexec/httpd/libbozohttpd/shlib_version
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
major=0
|
||||
minor=0
|
||||
452
libexec/httpd/lua-bozo.c
Normal file
452
libexec/httpd/lua-bozo.c
Normal file
|
|
@ -0,0 +1,452 @@
|
|||
/* $NetBSD: lua-bozo.c,v 1.12 2015/07/04 22:39:23 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013 Marc Balmer <marc@msys.ch>
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 and
|
||||
* dedication in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* this code implements dynamic content generation using Lua for bozohttpd */
|
||||
|
||||
#ifndef NO_LUA_SUPPORT
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <lualib.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "bozohttpd.h"
|
||||
|
||||
/* Lua binding for bozohttp */
|
||||
|
||||
#if LUA_VERSION_NUM < 502
|
||||
#define LUA_HTTPDLIBNAME "httpd"
|
||||
#endif
|
||||
|
||||
#define FORM "application/x-www-form-urlencoded"
|
||||
|
||||
static int
|
||||
lua_flush(lua_State *L)
|
||||
{
|
||||
bozohttpd_t *httpd;
|
||||
|
||||
lua_pushstring(L, "bozohttpd");
|
||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||
httpd = lua_touserdata(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
bozo_flush(httpd, stdout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
lua_print(lua_State *L)
|
||||
{
|
||||
bozohttpd_t *httpd;
|
||||
|
||||
lua_pushstring(L, "bozohttpd");
|
||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||
httpd = lua_touserdata(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
bozo_printf(httpd, "%s\r\n", lua_tostring(L, -1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
lua_read(lua_State *L)
|
||||
{
|
||||
bozohttpd_t *httpd;
|
||||
int n, len;
|
||||
char *data;
|
||||
|
||||
lua_pushstring(L, "bozohttpd");
|
||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||
httpd = lua_touserdata(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
len = luaL_checkinteger(L, -1);
|
||||
data = bozomalloc(httpd, len + 1);
|
||||
n = bozo_read(httpd, STDIN_FILENO, data, len);
|
||||
if (n >= 0) {
|
||||
data[n] = '\0';
|
||||
lua_pushstring(L, data);
|
||||
} else
|
||||
lua_pushnil(L);
|
||||
free(data);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
lua_register_handler(lua_State *L)
|
||||
{
|
||||
lua_state_map_t *map;
|
||||
lua_handler_t *handler;
|
||||
bozohttpd_t *httpd;
|
||||
|
||||
lua_pushstring(L, "lua_state_map");
|
||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||
map = lua_touserdata(L, -1);
|
||||
lua_pushstring(L, "bozohttpd");
|
||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||
httpd = lua_touserdata(L, -1);
|
||||
lua_pop(L, 2);
|
||||
|
||||
luaL_checkstring(L, 1);
|
||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||
|
||||
handler = bozomalloc(httpd, sizeof(lua_handler_t));
|
||||
|
||||
handler->name = bozostrdup(httpd, lua_tostring(L, 1));
|
||||
handler->ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
SIMPLEQ_INSERT_TAIL(&map->handlers, handler, h_next);
|
||||
httpd->process_lua = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
lua_write(lua_State *L)
|
||||
{
|
||||
bozohttpd_t *httpd;
|
||||
const char *data;
|
||||
|
||||
lua_pushstring(L, "bozohttpd");
|
||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||
httpd = lua_touserdata(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
data = luaL_checkstring(L, -1);
|
||||
lua_pushinteger(L, bozo_write(httpd, STDIN_FILENO, data, strlen(data)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
luaopen_httpd(lua_State *L)
|
||||
{
|
||||
struct luaL_Reg functions[] = {
|
||||
{ "flush", lua_flush },
|
||||
{ "print", lua_print },
|
||||
{ "read", lua_read },
|
||||
{ "register_handler", lua_register_handler },
|
||||
{ "write", lua_write },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
#if LUA_VERSION_NUM >= 502
|
||||
luaL_newlib(L, functions);
|
||||
#else
|
||||
luaL_register(L, LUA_HTTPDLIBNAME, functions);
|
||||
#endif
|
||||
lua_pushstring(L, "httpd 1.0.0");
|
||||
lua_setfield(L, -2, "_VERSION");
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if LUA_VERSION_NUM < 502
|
||||
static void
|
||||
lua_openlib(lua_State *L, const char *name, lua_CFunction fn)
|
||||
{
|
||||
lua_pushcfunction(L, fn);
|
||||
lua_pushstring(L, name);
|
||||
lua_call(L, 1, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* bozohttpd integration */
|
||||
void
|
||||
bozo_add_lua_map(bozohttpd_t *httpd, const char *prefix, const char *script)
|
||||
{
|
||||
lua_state_map_t *map;
|
||||
|
||||
map = bozomalloc(httpd, sizeof(lua_state_map_t));
|
||||
map->prefix = bozostrdup(httpd, prefix);
|
||||
if (*script == '/')
|
||||
map->script = bozostrdup(httpd, script);
|
||||
else {
|
||||
char cwd[MAXPATHLEN], *path;
|
||||
|
||||
getcwd(cwd, sizeof(cwd) - 1);
|
||||
asprintf(&path, "%s/%s", cwd, script);
|
||||
map->script = path;
|
||||
}
|
||||
map->L = luaL_newstate();
|
||||
if (map->L == NULL)
|
||||
bozo_err(httpd, 1, "can't create Lua state");
|
||||
SIMPLEQ_INIT(&map->handlers);
|
||||
|
||||
#if LUA_VERSION_NUM >= 502
|
||||
luaL_openlibs(map->L);
|
||||
lua_getglobal(map->L, "package");
|
||||
lua_getfield(map->L, -1, "preload");
|
||||
lua_pushcfunction(map->L, luaopen_httpd);
|
||||
lua_setfield(map->L, -2, "httpd");
|
||||
lua_pop(map->L, 2);
|
||||
#else
|
||||
lua_openlib(map->L, "", luaopen_base);
|
||||
lua_openlib(map->L, LUA_LOADLIBNAME, luaopen_package);
|
||||
lua_openlib(map->L, LUA_TABLIBNAME, luaopen_table);
|
||||
lua_openlib(map->L, LUA_STRLIBNAME, luaopen_string);
|
||||
lua_openlib(map->L, LUA_MATHLIBNAME, luaopen_math);
|
||||
lua_openlib(map->L, LUA_OSLIBNAME, luaopen_os);
|
||||
lua_openlib(map->L, LUA_IOLIBNAME, luaopen_io);
|
||||
lua_openlib(map->L, LUA_HTTPDLIBNAME, luaopen_httpd);
|
||||
#endif
|
||||
lua_pushstring(map->L, "lua_state_map");
|
||||
lua_pushlightuserdata(map->L, map);
|
||||
lua_settable(map->L, LUA_REGISTRYINDEX);
|
||||
|
||||
lua_pushstring(map->L, "bozohttpd");
|
||||
lua_pushlightuserdata(map->L, httpd);
|
||||
lua_settable(map->L, LUA_REGISTRYINDEX);
|
||||
|
||||
if (luaL_loadfile(map->L, script))
|
||||
bozo_err(httpd, 1, "failed to load script %s: %s", script,
|
||||
lua_tostring(map->L, -1));
|
||||
if (lua_pcall(map->L, 0, 0, 0))
|
||||
bozo_err(httpd, 1, "failed to execute script %s: %s", script,
|
||||
lua_tostring(map->L, -1));
|
||||
SIMPLEQ_INSERT_TAIL(&httpd->lua_states, map, s_next);
|
||||
}
|
||||
|
||||
static void
|
||||
lua_env(lua_State *L, const char *name, const char *value)
|
||||
{
|
||||
lua_pushstring(L, value);
|
||||
lua_setfield(L, -2, name);
|
||||
}
|
||||
|
||||
/* decode query string */
|
||||
static void
|
||||
lua_url_decode(lua_State *L, char *s)
|
||||
{
|
||||
char *v, *p, *val, *q;
|
||||
char buf[3];
|
||||
int c;
|
||||
|
||||
v = strchr(s, '=');
|
||||
if (v == NULL)
|
||||
return;
|
||||
*v++ = '\0';
|
||||
val = malloc(strlen(v) + 1);
|
||||
if (val == NULL)
|
||||
return;
|
||||
|
||||
for (p = v, q = val; *p; p++) {
|
||||
switch (*p) {
|
||||
case '%':
|
||||
if (*(p + 1) == '\0' || *(p + 2) == '\0') {
|
||||
free(val);
|
||||
return;
|
||||
}
|
||||
buf[0] = *++p;
|
||||
buf[1] = *++p;
|
||||
buf[2] = '\0';
|
||||
sscanf(buf, "%2x", &c);
|
||||
*q++ = (char)c;
|
||||
break;
|
||||
case '+':
|
||||
*q++ = ' ';
|
||||
break;
|
||||
default:
|
||||
*q++ = *p;
|
||||
}
|
||||
}
|
||||
*q = '\0';
|
||||
lua_pushstring(L, val);
|
||||
lua_setfield(L, -2, s);
|
||||
free(val);
|
||||
}
|
||||
|
||||
static void
|
||||
lua_decode_query(lua_State *L, char *query)
|
||||
{
|
||||
char *s;
|
||||
|
||||
s = strtok(query, "&");
|
||||
while (s) {
|
||||
lua_url_decode(L, s);
|
||||
s = strtok(NULL, "&");
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
bozo_process_lua(bozo_httpreq_t *request)
|
||||
{
|
||||
bozohttpd_t *httpd = request->hr_httpd;
|
||||
lua_state_map_t *map;
|
||||
lua_handler_t *hndlr;
|
||||
int n, ret, length;
|
||||
char date[40];
|
||||
bozoheaders_t *headp;
|
||||
char *s, *query, *uri, *file, *command, *info, *content;
|
||||
const char *type, *clen;
|
||||
char *prefix, *handler, *p;
|
||||
int rv = 0;
|
||||
|
||||
if (!httpd->process_lua)
|
||||
return 0;
|
||||
|
||||
info = NULL;
|
||||
query = NULL;
|
||||
prefix = NULL;
|
||||
uri = request->hr_oldfile ? request->hr_oldfile : request->hr_file;
|
||||
|
||||
if (*uri == '/') {
|
||||
file = bozostrdup(httpd, uri);
|
||||
if (file == NULL)
|
||||
goto out;
|
||||
prefix = bozostrdup(httpd, &uri[1]);
|
||||
} else {
|
||||
if (asprintf(&file, "/%s", uri) < 0)
|
||||
goto out;
|
||||
prefix = bozostrdup(httpd, uri);
|
||||
}
|
||||
if (prefix == NULL)
|
||||
goto out;
|
||||
|
||||
if (request->hr_query && request->hr_query[0])
|
||||
query = bozostrdup(httpd, request->hr_query);
|
||||
|
||||
p = strchr(prefix, '/');
|
||||
if (p == NULL)
|
||||
goto out;
|
||||
*p++ = '\0';
|
||||
handler = p;
|
||||
if (!*handler)
|
||||
goto out;
|
||||
p = strchr(handler, '/');
|
||||
if (p != NULL)
|
||||
*p++ = '\0';
|
||||
|
||||
command = file + 1;
|
||||
if ((s = strchr(command, '/')) != NULL) {
|
||||
info = bozostrdup(httpd, s);
|
||||
*s = '\0';
|
||||
}
|
||||
|
||||
type = request->hr_content_type;
|
||||
clen = request->hr_content_length;
|
||||
|
||||
SIMPLEQ_FOREACH(map, &httpd->lua_states, s_next) {
|
||||
if (strcmp(map->prefix, prefix))
|
||||
continue;
|
||||
|
||||
SIMPLEQ_FOREACH(hndlr, &map->handlers, h_next) {
|
||||
if (strcmp(hndlr->name, handler))
|
||||
continue;
|
||||
|
||||
lua_rawgeti(map->L, LUA_REGISTRYINDEX, hndlr->ref);
|
||||
|
||||
/* Create the "environment" */
|
||||
lua_newtable(map->L);
|
||||
lua_env(map->L, "SERVER_NAME",
|
||||
BOZOHOST(httpd, request));
|
||||
lua_env(map->L, "GATEWAY_INTERFACE", "Luigi/1.0");
|
||||
lua_env(map->L, "SERVER_PROTOCOL", request->hr_proto);
|
||||
lua_env(map->L, "REQUEST_METHOD",
|
||||
request->hr_methodstr);
|
||||
lua_env(map->L, "SCRIPT_PREFIX", map->prefix);
|
||||
lua_env(map->L, "SCRIPT_NAME", file);
|
||||
lua_env(map->L, "HANDLER_NAME", hndlr->name);
|
||||
lua_env(map->L, "SCRIPT_FILENAME", map->script);
|
||||
lua_env(map->L, "SERVER_SOFTWARE",
|
||||
httpd->server_software);
|
||||
lua_env(map->L, "REQUEST_URI", uri);
|
||||
lua_env(map->L, "DATE_GMT",
|
||||
bozo_http_date(date, sizeof(date)));
|
||||
if (query && *query)
|
||||
lua_env(map->L, "QUERY_STRING", query);
|
||||
if (info && *info)
|
||||
lua_env(map->L, "PATH_INFO", info);
|
||||
if (type && *type)
|
||||
lua_env(map->L, "CONTENT_TYPE", type);
|
||||
if (clen && *clen)
|
||||
lua_env(map->L, "CONTENT_LENGTH", clen);
|
||||
if (request->hr_serverport && *request->hr_serverport)
|
||||
lua_env(map->L, "SERVER_PORT",
|
||||
request->hr_serverport);
|
||||
if (request->hr_remotehost && *request->hr_remotehost)
|
||||
lua_env(map->L, "REMOTE_HOST",
|
||||
request->hr_remotehost);
|
||||
if (request->hr_remoteaddr && *request->hr_remoteaddr)
|
||||
lua_env(map->L, "REMOTE_ADDR",
|
||||
request->hr_remoteaddr);
|
||||
|
||||
/* Pass the headers in a separate table */
|
||||
lua_newtable(map->L);
|
||||
SIMPLEQ_FOREACH(headp, &request->hr_headers, h_next)
|
||||
lua_env(map->L, headp->h_header,
|
||||
headp->h_value);
|
||||
|
||||
/* Pass the query variables */
|
||||
if ((query && *query) ||
|
||||
(type && *type && !strcmp(type, FORM))) {
|
||||
lua_newtable(map->L);
|
||||
if (query && *query)
|
||||
lua_decode_query(map->L, query);
|
||||
if (type && *type && !strcmp(type, FORM)) {
|
||||
if (clen && *clen && atol(clen) > 0) {
|
||||
length = atol(clen);
|
||||
content = bozomalloc(httpd,
|
||||
length + 1);
|
||||
n = bozo_read(httpd,
|
||||
STDIN_FILENO, content,
|
||||
length);
|
||||
if (n >= 0) {
|
||||
content[n] = '\0';
|
||||
lua_decode_query(map->L,
|
||||
content);
|
||||
} else {
|
||||
lua_pop(map->L, 1);
|
||||
lua_pushnil(map->L);
|
||||
}
|
||||
free(content);
|
||||
}
|
||||
}
|
||||
} else
|
||||
lua_pushnil(map->L);
|
||||
|
||||
ret = lua_pcall(map->L, 3, 0, 0);
|
||||
if (ret)
|
||||
printf("<br>Lua error: %s\n",
|
||||
lua_tostring(map->L, -1));
|
||||
bozo_flush(httpd, stdout);
|
||||
rv = 1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
out:
|
||||
free(prefix);
|
||||
free(uri);
|
||||
free(info);
|
||||
free(query);
|
||||
free(file);
|
||||
return rv;
|
||||
}
|
||||
|
||||
#endif /* NO_LUA_SUPPORT */
|
||||
39
libexec/httpd/lua/Makefile
Normal file
39
libexec/httpd/lua/Makefile
Normal file
|
|
@ -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
|
||||
162
libexec/httpd/lua/bozo.lua
Executable file
162
libexec/httpd/lua/bozo.lua
Executable file
|
|
@ -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
|
||||
276
libexec/httpd/lua/glue.c
Normal file
276
libexec/httpd/lua/glue.c
Normal file
|
|
@ -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;
|
||||
}
|
||||
123
libexec/httpd/lua/optparse.lua
Normal file
123
libexec/httpd/lua/optparse.lua
Normal file
|
|
@ -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
|
||||
|
||||
2
libexec/httpd/lua/shlib_version
Normal file
2
libexec/httpd/lua/shlib_version
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
major=0
|
||||
minor=0
|
||||
356
libexec/httpd/main.c
Normal file
356
libexec/httpd/main.c
Normal file
|
|
@ -0,0 +1,356 @@
|
|||
/* $NetBSD: main.c,v 1.8 2014/07/16 07:41:43 mrg Exp $ */
|
||||
|
||||
/* $eterna: main.c,v 1.6 2011/11/18 09:21:15 mrg Exp $ */
|
||||
/* from: eterna: bozohttpd.c,v 1.159 2009/05/23 02:14:30 mrg Exp */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997-2014 Matthew R. Green
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 and
|
||||
* dedication in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* this program is dedicated to the Great God of Processed Cheese */
|
||||
|
||||
/*
|
||||
* main.c: C front end to bozohttpd
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "bozohttpd.h"
|
||||
|
||||
/* variables and functions */
|
||||
#ifndef LOG_FTP
|
||||
#define LOG_FTP LOG_DAEMON
|
||||
#endif
|
||||
|
||||
/* print a usage message, and then exit */
|
||||
BOZO_DEAD static void
|
||||
usage(bozohttpd_t *httpd, char *progname)
|
||||
{
|
||||
bozo_warn(httpd, "usage: %s [options] slashdir [virtualhostname]",
|
||||
progname);
|
||||
bozo_warn(httpd, "options:");
|
||||
#ifndef NO_DEBUG
|
||||
bozo_warn(httpd, " -d\t\t\tenable debug support");
|
||||
#endif
|
||||
bozo_warn(httpd, " -s\t\t\talways log to stderr");
|
||||
#ifndef NO_USER_SUPPORT
|
||||
bozo_warn(httpd, " -u\t\t\tenable ~user/public_html support");
|
||||
bozo_warn(httpd, " -p dir\t\tchange `public_html' directory name]");
|
||||
#endif
|
||||
#ifndef NO_DYNAMIC_CONTENT
|
||||
bozo_warn(httpd, " -M arg t c c11\tadd this mime extenstion");
|
||||
#endif
|
||||
#ifndef NO_CGIBIN_SUPPORT
|
||||
#ifndef NO_DYNAMIC_CONTENT
|
||||
bozo_warn(httpd, " -C arg prog\t\tadd this CGI handler");
|
||||
#endif
|
||||
bozo_warn(httpd,
|
||||
" -c cgibin\t\tenable cgi-bin support in this directory");
|
||||
#endif
|
||||
#ifndef NO_LUA_SUPPORT
|
||||
bozo_warn(httpd, " -L arg script\tadd this Lua script");
|
||||
#endif
|
||||
bozo_warn(httpd, " -I port\t\tbind or use on this port");
|
||||
#ifndef NO_DAEMON_MODE
|
||||
bozo_warn(httpd, " -b\t\t\tbackground and go into daemon mode");
|
||||
bozo_warn(httpd, " -f\t\t\tkeep daemon mode in the foreground");
|
||||
bozo_warn(httpd,
|
||||
" -i address\t\tbind on this address (daemon mode only)");
|
||||
bozo_warn(httpd, " -P pidfile\t\tpath to the pid file to create");
|
||||
#endif
|
||||
bozo_warn(httpd, " -S version\t\tset server version string");
|
||||
bozo_warn(httpd, " -t dir\t\tchroot to `dir'");
|
||||
bozo_warn(httpd, " -U username\t\tchange user to `user'");
|
||||
bozo_warn(httpd,
|
||||
" -e\t\t\tdon't clean the environment (-t and -U only)");
|
||||
bozo_warn(httpd,
|
||||
" -v virtualroot\tenable virtual host support "
|
||||
"in this directory");
|
||||
bozo_warn(httpd,
|
||||
" -r\t\t\tmake sure sub-pages come from "
|
||||
"this host via referrer");
|
||||
#ifndef NO_DIRINDEX_SUPPORT
|
||||
bozo_warn(httpd,
|
||||
" -X\t\t\tenable automatic directory index support");
|
||||
bozo_warn(httpd,
|
||||
" -H\t\t\thide files starting with a period (.)"
|
||||
" in index mode");
|
||||
#endif
|
||||
bozo_warn(httpd,
|
||||
" -x index\t\tchange default `index.html' file name");
|
||||
#ifndef NO_SSL_SUPPORT
|
||||
bozo_warn(httpd,
|
||||
" -Z cert privkey\tspecify path to server certificate"
|
||||
" and private key file\n"
|
||||
"\t\t\tin pem format and enable bozohttpd in SSL mode");
|
||||
#endif /* NO_SSL_SUPPORT */
|
||||
bozo_err(httpd, 1, "%s failed to start", progname);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
bozo_httpreq_t *request;
|
||||
bozohttpd_t httpd;
|
||||
bozoprefs_t prefs;
|
||||
char *progname;
|
||||
int c;
|
||||
|
||||
(void) memset(&httpd, 0x0, sizeof(httpd));
|
||||
(void) memset(&prefs, 0x0, sizeof(prefs));
|
||||
|
||||
if ((progname = strrchr(argv[0], '/')) == NULL)
|
||||
progname = argv[0];
|
||||
else
|
||||
progname++;
|
||||
|
||||
openlog(progname, LOG_PID|LOG_NDELAY, LOG_FTP);
|
||||
|
||||
bozo_set_defaults(&httpd, &prefs);
|
||||
|
||||
while ((c = getopt(argc, argv,
|
||||
"C:HI:L:M:P:S:U:VXZ:bc:defhi:np:rst:uv:x:z:")) != -1) {
|
||||
switch(c) {
|
||||
|
||||
case 'L':
|
||||
#ifdef NO_LUA_SUPPORT
|
||||
bozo_err(&httpd, 1,
|
||||
"Lua support is not enabled");
|
||||
/* NOTREACHED */
|
||||
#else
|
||||
/* make sure there's two argument */
|
||||
if (argc - optind < 1)
|
||||
usage(&httpd, progname);
|
||||
bozo_add_lua_map(&httpd, optarg, argv[optind]);
|
||||
optind++;
|
||||
break;
|
||||
#endif /* NO_LUA_SUPPORT */
|
||||
case 'M':
|
||||
#ifdef NO_DYNAMIC_CONTENT
|
||||
bozo_err(&httpd, 1,
|
||||
"dynamic mime content support is not enabled");
|
||||
/* NOTREACHED */
|
||||
#else
|
||||
/* make sure there's four arguments */
|
||||
if (argc - optind < 3)
|
||||
usage(&httpd, progname);
|
||||
bozo_add_content_map_mime(&httpd, optarg, argv[optind],
|
||||
argv[optind+1], argv[optind+2]);
|
||||
optind += 3;
|
||||
break;
|
||||
#endif /* NO_DYNAMIC_CONTENT */
|
||||
|
||||
case 'n':
|
||||
bozo_set_pref(&prefs, "numeric", "true");
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
bozo_set_pref(&prefs, "trusted referal", "true");
|
||||
break;
|
||||
|
||||
case 's':
|
||||
bozo_set_pref(&prefs, "log to stderr", "true");
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
bozo_set_pref(&prefs, "server software", optarg);
|
||||
break;
|
||||
case 'Z':
|
||||
#ifdef NO_SSL_SUPPORT
|
||||
bozo_err(&httpd, 1, "ssl support is not enabled");
|
||||
/* NOT REACHED */
|
||||
#else
|
||||
/* make sure there's two arguments */
|
||||
if (argc - optind < 1)
|
||||
usage(&httpd, progname);
|
||||
bozo_ssl_set_opts(&httpd, optarg, argv[optind++]);
|
||||
break;
|
||||
#endif /* NO_SSL_SUPPORT */
|
||||
case 'U':
|
||||
bozo_set_pref(&prefs, "username", optarg);
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
bozo_set_pref(&prefs, "unknown slash", "true");
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
bozo_set_pref(&prefs, "virtual base", optarg);
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
bozo_set_pref(&prefs, "index.html", optarg);
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
bozo_set_pref(&prefs, "port number", optarg);
|
||||
break;
|
||||
|
||||
#ifdef NO_DAEMON_MODE
|
||||
case 'b':
|
||||
case 'e':
|
||||
case 'f':
|
||||
case 'i':
|
||||
case 'P':
|
||||
bozo_err(&httpd, 1, "Daemon mode is not enabled");
|
||||
/* NOTREACHED */
|
||||
#else
|
||||
case 'b':
|
||||
/*
|
||||
* test suite support - undocumented
|
||||
* background == 2 (aka, -b -b) means to
|
||||
* only process 1 per kid
|
||||
*/
|
||||
if (bozo_get_pref(&prefs, "background") == NULL) {
|
||||
bozo_set_pref(&prefs, "background", "1");
|
||||
} else {
|
||||
bozo_set_pref(&prefs, "background", "2");
|
||||
}
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
bozo_set_pref(&prefs, "dirty environment", "true");
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
bozo_set_pref(&prefs, "foreground", "true");
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
bozo_set_pref(&prefs, "bind address", optarg);
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
bozo_set_pref(&prefs, "pid file", optarg);
|
||||
break;
|
||||
#endif /* NO_DAEMON_MODE */
|
||||
|
||||
#ifdef NO_CGIBIN_SUPPORT
|
||||
case 'c':
|
||||
case 'C':
|
||||
bozo_err(&httpd, 1, "CGI is not enabled");
|
||||
/* NOTREACHED */
|
||||
#else
|
||||
case 'c':
|
||||
bozo_cgi_setbin(&httpd, optarg);
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
# ifdef NO_DYNAMIC_CONTENT
|
||||
bozo_err(&httpd, 1,
|
||||
"dynamic CGI handler support is not enabled");
|
||||
/* NOTREACHED */
|
||||
# else
|
||||
/* make sure there's two arguments */
|
||||
if (argc - optind < 1)
|
||||
usage(&httpd, progname);
|
||||
bozo_add_content_map_cgi(&httpd, optarg,
|
||||
argv[optind++]);
|
||||
break;
|
||||
# endif /* NO_DYNAMIC_CONTENT */
|
||||
#endif /* NO_CGIBIN_SUPPORT */
|
||||
|
||||
case 'd':
|
||||
httpd.debug++;
|
||||
#ifdef NO_DEBUG
|
||||
if (httpd.debug == 1)
|
||||
bozo_warn(&httpd, "Debugging is not enabled");
|
||||
#endif /* NO_DEBUG */
|
||||
break;
|
||||
|
||||
case 't':
|
||||
bozo_set_pref(&prefs, "chroot dir", optarg);
|
||||
break;
|
||||
|
||||
#ifdef NO_USER_SUPPORT
|
||||
case 'p':
|
||||
case 'u':
|
||||
bozo_err(&httpd, 1, "User support is not enabled");
|
||||
/* NOTREACHED */
|
||||
#else
|
||||
case 'p':
|
||||
bozo_set_pref(&prefs, "public_html", optarg);
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
bozo_set_pref(&prefs, "enable users", "true");
|
||||
break;
|
||||
#endif /* NO_USER_SUPPORT */
|
||||
|
||||
#ifdef NO_DIRINDEX_SUPPORT
|
||||
case 'H':
|
||||
case 'X':
|
||||
bozo_err(&httpd, 1,
|
||||
"directory indexing is not enabled");
|
||||
/* NOTREACHED */
|
||||
#else
|
||||
case 'H':
|
||||
bozo_set_pref(&prefs, "hide dots", "true");
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
bozo_set_pref(&prefs, "directory indexing", "true");
|
||||
break;
|
||||
|
||||
#endif /* NO_DIRINDEX_SUPPORT */
|
||||
|
||||
default:
|
||||
usage(&httpd, progname);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc == 0 || argc > 2) {
|
||||
usage(&httpd, progname);
|
||||
}
|
||||
|
||||
/* virtual host, and root of tree to serve */
|
||||
bozo_setup(&httpd, &prefs, argv[1], argv[0]);
|
||||
|
||||
/*
|
||||
* read and process the HTTP request.
|
||||
*/
|
||||
do {
|
||||
if ((request = bozo_read_request(&httpd)) != NULL) {
|
||||
bozo_process_request(request);
|
||||
bozo_clean_request(request);
|
||||
}
|
||||
} while (httpd.background);
|
||||
|
||||
return (0);
|
||||
}
|
||||
82
libexec/httpd/netbsd_queue.h
Normal file
82
libexec/httpd/netbsd_queue.h
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/* $eterna: queue.h,v 1.6 2009/04/18 08:36:03 mrg Exp $ */
|
||||
/* from: NetBSD: queue.h,v 1.51 2009/03/11 06:51:53 mrg Exp */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
*
|
||||
* @(#)queue.h 8.5 (Berkeley) 8/20/94
|
||||
*/
|
||||
|
||||
#ifndef _SYS_QUEUE_H_
|
||||
#define _SYS_QUEUE_H_
|
||||
|
||||
/*
|
||||
* Simple queue definitions.
|
||||
*/
|
||||
#define SIMPLEQ_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *sqh_first; /* first element */ \
|
||||
struct type **sqh_last; /* addr of last next element */ \
|
||||
}
|
||||
|
||||
#define SIMPLEQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *sqe_next; /* next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple queue functions.
|
||||
*/
|
||||
#define SIMPLEQ_INIT(head) do { \
|
||||
(head)->sqh_first = NULL; \
|
||||
(head)->sqh_last = &(head)->sqh_first; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
|
||||
(elm)->field.sqe_next = NULL; \
|
||||
*(head)->sqh_last = (elm); \
|
||||
(head)->sqh_last = &(elm)->field.sqe_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define SIMPLEQ_FOREACH(var, head, field) \
|
||||
for ((var) = ((head)->sqh_first); \
|
||||
(var); \
|
||||
(var) = ((var)->field.sqe_next))
|
||||
|
||||
#define SIMPLEQ_FOREACH_SAFE(var, head, field, next) \
|
||||
for ((var) = ((head)->sqh_first); \
|
||||
(var) && ((next = ((var)->field.sqe_next)), 1); \
|
||||
(var) = (next))
|
||||
|
||||
/*
|
||||
* Simple queue access methods.
|
||||
*/
|
||||
#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
|
||||
#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
|
||||
|
||||
#endif /* !_SYS_QUEUE_H_ */
|
||||
85
libexec/httpd/printenv.lua
Normal file
85
libexec/httpd/printenv.lua
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
-- $NetBSD: printenv.lua,v 1.2 2014/01/02 08:21:38 mrg Exp $
|
||||
|
||||
-- this small Lua script demonstrates the use of Lua in (bozo)httpd
|
||||
-- it will simply output the "environment"
|
||||
|
||||
-- Keep in mind that bozohttpd forks for each request when started in
|
||||
-- daemon mode, you can set global veriables here, but they will have
|
||||
-- the same value on each invocation. You can not keep state between
|
||||
-- two calls.
|
||||
|
||||
local httpd = require 'httpd'
|
||||
|
||||
function printenv(env, headers, query)
|
||||
|
||||
-- we get the "environment" in the env table, the values are more
|
||||
-- or less the same as the variable for a CGI program
|
||||
|
||||
if count == nil then
|
||||
count = 1
|
||||
end
|
||||
|
||||
-- output a header
|
||||
print([[
|
||||
<html>
|
||||
<head>
|
||||
<title>Bozotic Lua Environment</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Bozotic Lua Environment</h1>
|
||||
]])
|
||||
|
||||
print('module version: ' .. httpd._VERSION .. '<br>')
|
||||
|
||||
print('<h2>Server Environment</h2>')
|
||||
-- print the list of "environment" variables
|
||||
for k, v in pairs(env) do
|
||||
print(k .. '=' .. v .. '<br/>')
|
||||
end
|
||||
|
||||
print('<h2>Request Headers</h2>')
|
||||
for k, v in pairs(headers) do
|
||||
print(k .. '=' .. v .. '<br/>')
|
||||
end
|
||||
|
||||
if query ~= nil then
|
||||
print('<h2>Query Variables</h2>')
|
||||
for k, v in pairs(query) do
|
||||
print(k .. '=' .. v .. '<br/>')
|
||||
end
|
||||
end
|
||||
|
||||
print('<h2>Form Test</h2>')
|
||||
|
||||
print([[
|
||||
<form method="POST" action="/rest/form?sender=me">
|
||||
<input type="text" name="a_value">
|
||||
<input type="submit">
|
||||
</form>
|
||||
]])
|
||||
-- output a footer
|
||||
print([[
|
||||
</body>
|
||||
</html>
|
||||
]])
|
||||
end
|
||||
|
||||
function form(env, header, query)
|
||||
if query ~= nil then
|
||||
print('<h2>Form Variables</h2>')
|
||||
|
||||
if env.CONTENT_TYPE ~= nil then
|
||||
print('Content-type: ' .. env.CONTENT_TYPE .. '<br>')
|
||||
end
|
||||
|
||||
for k, v in pairs(query) do
|
||||
print(k .. '=' .. v .. '<br/>')
|
||||
end
|
||||
else
|
||||
print('No values')
|
||||
end
|
||||
end
|
||||
|
||||
-- register this handler for http://<hostname>/<prefix>/printenv
|
||||
httpd.register_handler('printenv', printenv)
|
||||
httpd.register_handler('form', form)
|
||||
30
libexec/httpd/small/Makefile
Normal file
30
libexec/httpd/small/Makefile
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
# $eterna: Makefile,v 1.1 2009/05/22 21:51:39 mrg Exp $
|
||||
|
||||
# build a 100% lean bozohttpd-small.c
|
||||
PROG= bozohttpd-small
|
||||
NOMAN= # defined
|
||||
SRCS= bozohttpd-small.c content-bozo-small.c ssl-bozo.c main.c:
|
||||
|
||||
LEAN_IFDEF_FLAGS= -UDEBUG -DNO_USER_SUPPORT \
|
||||
-DNO_CGIBIN_SUPPORT -DNO_DIRINDEX_SUPPORT \
|
||||
-DNO_DAEMON_MODE -DNO_DYNAMIC_CONTENT \
|
||||
-DNO_SSL_SUPPORT -UDO_HTPASSWD \
|
||||
-DNO_LUA_SUPPORT
|
||||
|
||||
CFLAGS= -I$(.CURDIR)/.. ${LEAN_IFDEF_FLAGS}
|
||||
|
||||
bozohttpd-small.c: bozohttpd.c
|
||||
unifdef $(LEAN_IFDEF_FLAGS) < $> > $@.tmp ;\
|
||||
if [ $$? -ne 1 ]; then echo "unifdef returned $?, expecting 1" 2>&1; false; fi
|
||||
mv -f $@.tmp $@
|
||||
|
||||
content-bozo-small.c: content-bozo.c
|
||||
unifdef $(LEAN_IFDEF_FLAGS) < $> > $@.tmp ;\
|
||||
if [ $$? -ne 1 ]; then echo "unifdef returned $?, expecting 1" 2>&1; false; fi
|
||||
mv -f $@.tmp $@
|
||||
|
||||
CLEANFILES+= content-bozo-small.c bozohttpd-small.c
|
||||
|
||||
.PATH: $(.CURDIR)/..
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
321
libexec/httpd/ssl-bozo.c
Normal file
321
libexec/httpd/ssl-bozo.c
Normal file
|
|
@ -0,0 +1,321 @@
|
|||
/* $NetBSD: ssl-bozo.c,v 1.18 2014/07/17 06:27:52 mrg Exp $ */
|
||||
|
||||
/* $eterna: ssl-bozo.c,v 1.15 2011/11/18 09:21:15 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997-2014 Matthew R. Green
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 and
|
||||
* dedication in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* this code implements SSL and backend IO for bozohttpd */
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "bozohttpd.h"
|
||||
|
||||
#ifndef NO_SSL_SUPPORT
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#ifndef USE_ARG
|
||||
#define USE_ARG(x) /*LINTED*/(void)&(x)
|
||||
#endif
|
||||
|
||||
/* this structure encapsulates the ssl info */
|
||||
typedef struct sslinfo_t {
|
||||
SSL_CTX *ssl_context;
|
||||
const SSL_METHOD *ssl_method;
|
||||
SSL *bozossl;
|
||||
char *certificate_file;
|
||||
char *privatekey_file;
|
||||
} sslinfo_t;
|
||||
|
||||
/*
|
||||
* bozo_clear_ssl_queue: print the contents of the SSL error queue
|
||||
*/
|
||||
static void
|
||||
bozo_clear_ssl_queue(bozohttpd_t *httpd)
|
||||
{
|
||||
unsigned long sslcode = ERR_get_error();
|
||||
|
||||
do {
|
||||
static const char sslfmt[] = "SSL Error: %s:%s:%s";
|
||||
|
||||
if (httpd->logstderr || isatty(STDERR_FILENO)) {
|
||||
fprintf(stderr, sslfmt,
|
||||
ERR_lib_error_string(sslcode),
|
||||
ERR_func_error_string(sslcode),
|
||||
ERR_reason_error_string(sslcode));
|
||||
} else {
|
||||
syslog(LOG_ERR, sslfmt,
|
||||
ERR_lib_error_string(sslcode),
|
||||
ERR_func_error_string(sslcode),
|
||||
ERR_reason_error_string(sslcode));
|
||||
}
|
||||
} while (0 != (sslcode = ERR_get_error()));
|
||||
}
|
||||
|
||||
/*
|
||||
* bozo_ssl_warn works just like bozo_warn, plus the SSL error queue
|
||||
*/
|
||||
BOZO_PRINTFLIKE(2, 3) static void
|
||||
bozo_ssl_warn(bozohttpd_t *httpd, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
if (httpd->logstderr || isatty(STDERR_FILENO)) {
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fputs("\n", stderr);
|
||||
} else
|
||||
vsyslog(LOG_ERR, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
bozo_clear_ssl_queue(httpd);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* bozo_ssl_err works just like bozo_err, plus the SSL error queue
|
||||
*/
|
||||
BOZO_PRINTFLIKE(3, 4) BOZO_DEAD static void
|
||||
bozo_ssl_err(bozohttpd_t *httpd, int code, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
if (httpd->logstderr || isatty(STDERR_FILENO)) {
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fputs("\n", stderr);
|
||||
} else
|
||||
vsyslog(LOG_ERR, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
bozo_clear_ssl_queue(httpd);
|
||||
exit(code);
|
||||
}
|
||||
|
||||
/*
|
||||
* bozo_check_error_queue: print warnings if the error isn't expected
|
||||
*/
|
||||
static void
|
||||
bozo_check_error_queue(bozohttpd_t *httpd, const char *tag, int ret)
|
||||
{
|
||||
if (ret > 0)
|
||||
return;
|
||||
|
||||
const sslinfo_t *sslinfo = httpd->sslinfo;
|
||||
const int sslerr = SSL_get_error(sslinfo->bozossl, ret);
|
||||
|
||||
if (sslerr != SSL_ERROR_ZERO_RETURN &&
|
||||
sslerr != SSL_ERROR_SYSCALL &&
|
||||
sslerr != SSL_ERROR_NONE)
|
||||
bozo_ssl_warn(httpd, "%s: SSL_ERROR %d", tag, sslerr);
|
||||
}
|
||||
|
||||
static BOZO_PRINTFLIKE(2, 0) int
|
||||
bozo_ssl_printf(bozohttpd_t *httpd, const char * fmt, va_list ap)
|
||||
{
|
||||
char *buf;
|
||||
int nbytes;
|
||||
|
||||
if ((nbytes = vasprintf(&buf, fmt, ap)) != -1) {
|
||||
const sslinfo_t *sslinfo = httpd->sslinfo;
|
||||
int ret = SSL_write(sslinfo->bozossl, buf, nbytes);
|
||||
bozo_check_error_queue(httpd, "write", ret);
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
bozo_ssl_read(bozohttpd_t *httpd, int fd, void *buf, size_t nbytes)
|
||||
{
|
||||
const sslinfo_t *sslinfo = httpd->sslinfo;
|
||||
int ret;
|
||||
|
||||
USE_ARG(fd);
|
||||
ret = SSL_read(sslinfo->bozossl, buf, (int)nbytes);
|
||||
bozo_check_error_queue(httpd, "read", ret);
|
||||
|
||||
return (ssize_t)ret;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
bozo_ssl_write(bozohttpd_t *httpd, int fd, const void *buf, size_t nbytes)
|
||||
{
|
||||
const sslinfo_t *sslinfo = httpd->sslinfo;
|
||||
int ret;
|
||||
|
||||
USE_ARG(fd);
|
||||
ret = SSL_write(sslinfo->bozossl, buf, (int)nbytes);
|
||||
bozo_check_error_queue(httpd, "write", ret);
|
||||
|
||||
return (ssize_t)ret;
|
||||
}
|
||||
|
||||
void
|
||||
bozo_ssl_init(bozohttpd_t *httpd)
|
||||
{
|
||||
sslinfo_t *sslinfo = httpd->sslinfo;
|
||||
|
||||
if (sslinfo == NULL || !sslinfo->certificate_file)
|
||||
return;
|
||||
SSL_library_init();
|
||||
SSL_load_error_strings();
|
||||
|
||||
sslinfo->ssl_method = SSLv23_server_method();
|
||||
sslinfo->ssl_context = SSL_CTX_new(sslinfo->ssl_method);
|
||||
|
||||
if (NULL == sslinfo->ssl_context)
|
||||
bozo_ssl_err(httpd, EXIT_FAILURE,
|
||||
"SSL context creation failed");
|
||||
|
||||
if (1 != SSL_CTX_use_certificate_chain_file(sslinfo->ssl_context,
|
||||
sslinfo->certificate_file))
|
||||
bozo_ssl_err(httpd, EXIT_FAILURE,
|
||||
"Unable to use certificate file '%s'",
|
||||
sslinfo->certificate_file);
|
||||
|
||||
if (1 != SSL_CTX_use_PrivateKey_file(sslinfo->ssl_context,
|
||||
sslinfo->privatekey_file, SSL_FILETYPE_PEM))
|
||||
bozo_ssl_err(httpd, EXIT_FAILURE,
|
||||
"Unable to use private key file '%s'",
|
||||
sslinfo->privatekey_file);
|
||||
|
||||
/* check consistency of key vs certificate */
|
||||
if (!SSL_CTX_check_private_key(sslinfo->ssl_context))
|
||||
bozo_ssl_err(httpd, EXIT_FAILURE,
|
||||
"Check private key failed");
|
||||
}
|
||||
|
||||
/*
|
||||
* returns non-zero for failure
|
||||
*/
|
||||
int
|
||||
bozo_ssl_accept(bozohttpd_t *httpd)
|
||||
{
|
||||
sslinfo_t *sslinfo = httpd->sslinfo;
|
||||
|
||||
if (sslinfo == NULL || !sslinfo->ssl_context)
|
||||
return 0;
|
||||
|
||||
sslinfo->bozossl = SSL_new(sslinfo->ssl_context);
|
||||
if (sslinfo->bozossl == NULL)
|
||||
bozo_err(httpd, 1, "SSL_new failed");
|
||||
|
||||
SSL_set_rfd(sslinfo->bozossl, 0);
|
||||
SSL_set_wfd(sslinfo->bozossl, 1);
|
||||
|
||||
const int ret = SSL_accept(sslinfo->bozossl);
|
||||
bozo_check_error_queue(httpd, "accept", ret);
|
||||
|
||||
return ret != 1;
|
||||
}
|
||||
|
||||
void
|
||||
bozo_ssl_destroy(bozohttpd_t *httpd)
|
||||
{
|
||||
const sslinfo_t *sslinfo = httpd->sslinfo;
|
||||
|
||||
if (sslinfo && sslinfo->bozossl)
|
||||
SSL_free(sslinfo->bozossl);
|
||||
}
|
||||
|
||||
void
|
||||
bozo_ssl_set_opts(bozohttpd_t *httpd, const char *cert, const char *priv)
|
||||
{
|
||||
sslinfo_t *sslinfo = httpd->sslinfo;
|
||||
|
||||
if (sslinfo == NULL) {
|
||||
sslinfo = bozomalloc(httpd, sizeof(*sslinfo));
|
||||
if (sslinfo == NULL)
|
||||
bozo_err(httpd, 1, "sslinfo allocation failed");
|
||||
httpd->sslinfo = sslinfo;
|
||||
}
|
||||
sslinfo->certificate_file = strdup(cert);
|
||||
sslinfo->privatekey_file = strdup(priv);
|
||||
debug((httpd, DEBUG_NORMAL, "using cert/priv files: %s & %s",
|
||||
sslinfo->certificate_file,
|
||||
sslinfo->privatekey_file));
|
||||
if (!httpd->bindport)
|
||||
httpd->bindport = strdup("https");
|
||||
}
|
||||
|
||||
#endif /* NO_SSL_SUPPORT */
|
||||
|
||||
int
|
||||
bozo_printf(bozohttpd_t *httpd, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int cc;
|
||||
|
||||
va_start(args, fmt);
|
||||
#ifndef NO_SSL_SUPPORT
|
||||
if (httpd->sslinfo)
|
||||
cc = bozo_ssl_printf(httpd, fmt, args);
|
||||
else
|
||||
#endif
|
||||
cc = vprintf(fmt, args);
|
||||
va_end(args);
|
||||
return cc;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
bozo_read(bozohttpd_t *httpd, int fd, void *buf, size_t len)
|
||||
{
|
||||
#ifndef NO_SSL_SUPPORT
|
||||
if (httpd->sslinfo)
|
||||
return bozo_ssl_read(httpd, fd, buf, len);
|
||||
#endif
|
||||
return read(fd, buf, len);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
bozo_write(bozohttpd_t *httpd, int fd, const void *buf, size_t len)
|
||||
{
|
||||
#ifndef NO_SSL_SUPPORT
|
||||
if (httpd->sslinfo)
|
||||
return bozo_ssl_write(httpd, fd, buf, len);
|
||||
#endif
|
||||
return write(fd, buf, len);
|
||||
}
|
||||
|
||||
int
|
||||
bozo_flush(bozohttpd_t *httpd, FILE *fp)
|
||||
{
|
||||
#ifndef NO_SSL_SUPPORT
|
||||
if (httpd->sslinfo)
|
||||
return 0;
|
||||
#endif
|
||||
return fflush(fp);
|
||||
}
|
||||
32
libexec/httpd/testsuite/Makefile
Normal file
32
libexec/httpd/testsuite/Makefile
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
# $eterna: Makefile,v 1.14 2009/05/22 21:51:39 mrg Exp $
|
||||
|
||||
SIMPLETESTS= t1 t2 t3 t4 t5 t6 t7 t8 t9 t10
|
||||
BIGFILETESTS= partial4000 partial8000
|
||||
|
||||
BOZOHTTPD?= ../bozohttpd
|
||||
BOZOHTTPD?= ../debug/bozohttpd-debug
|
||||
WGET?= wget
|
||||
|
||||
all:
|
||||
|
||||
clean:
|
||||
for a in $(SIMPLETESTS); do \
|
||||
rm -f tmp.$$a.out; \
|
||||
done
|
||||
|
||||
check: check-simple check-bigfile
|
||||
|
||||
check-simple:
|
||||
.for a in $(SIMPLETESTS)
|
||||
echo "Running test $a"
|
||||
$(BOZOHTTPD) ./data < $(.CURDIR)/$a.in > tmp.$a.out || true
|
||||
$(.CURDIR)/html_cmp $(.CURDIR)/$a.out tmp.$a.out
|
||||
.endfor
|
||||
|
||||
check-bigfile:
|
||||
.for a in $(BIGFILETESTS)
|
||||
echo "Running test $a"
|
||||
$(.CURDIR)/test-bigfile "$a" "${BOZOHTTPD}" "${WGET}" "./data"
|
||||
.endfor
|
||||
|
||||
.include <bsd.obj.mk>
|
||||
127
libexec/httpd/testsuite/data/bigfile
Normal file
127
libexec/httpd/testsuite/data/bigfile
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
this is the big data file. it has to be over 1 page size in length. 0123456789
|
||||
these lines are all 80 long. this is the second line. 012345678901234567890123
|
||||
4567890123456789012345678901234567890123456789012345678901234567890123456789012
|
||||
3456789012345678901234567890123456789012345678901234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
012345678901 this is the seventh line. 12345678901234567890123456789012345678
|
||||
9012345678901234567890123456789012345678901234567890123456789012345678901234567
|
||||
8901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
7890123456789012345678901234567890123456789012345678901234567890123456789012345
|
||||
6789012345678901234567890123456789012345678901234567890123456789012345678901234
|
||||
5678901234567890123456789012345678901234567890123456789012345678901234567890123
|
||||
456789 this is the 13th line, and there 127 lines in total. 67890123456789012
|
||||
3456789012345678901234567890123456789012345678901234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
0123456789012345678901234567890123456789012345678901234567890123456789012345678
|
||||
901234567890123456789012345 this is the 18th line. 456789012345678901234567
|
||||
8901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
7890123456789012345678901234567890123456789012345678901234567890123456789012345
|
||||
6789012345678901234567890123456789012345678901234567890123456789012345678901234
|
||||
5678901234567890123456789012345678901234567890123456789012345678901234567890123
|
||||
4567890123456789012345678901234567890123456789012345678901234567890123456789012
|
||||
3456789012345678901234567890123456789012345678901234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
0123456789012345678901234567890123456789012345678901234567890123456789012345678
|
||||
9012345678901234567890123456789012345678901234567890123456789012345678901234567
|
||||
8901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
78901234567890123456 this is the 31st line. 345678901234567890123456789012345
|
||||
6789012345678901234567890123456789012345678901234567890123456789012345678901234
|
||||
5678901234567890123456789012345678901234567890123456789012345678901234567890123
|
||||
4567890123456789012345678901234567890123456789012345678901234567890123456789012
|
||||
3456789012345678901234567890123456789012345678901234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
0123456789012345678901234567890123456789012345678901234567890123456789012345678
|
||||
90123456789012345678901234567890123456789 this is the 38th line. 78901234567
|
||||
8901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
7890123456789012345678901234567890123456789012345678901234567890123456789012345
|
||||
6789012345678901234567890123456789012345678901234567890123456789012345678901234
|
||||
5678901234567890123456789012345678901234567890123456789012345678901234567890123
|
||||
4567890123456789012345678901234567890123456789012345678901234567890123456789012
|
||||
3456789012345678901234567890123456789012345678901234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
012345678901234567890123456 this is the 47th line. 4567890123456789012345678
|
||||
9012345678901234567890123456789012345678901234567890123456789012345678901234567
|
||||
8901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
789012345678901234567890123456789012345678901234567 50th 7890123456789012345
|
||||
6789012345678901234567890123456789012345678901234567890123456789012345678901234
|
||||
56789012 this is the 52nd line. 1234567890123456789012345678901234567890123
|
||||
4567890123456789012345678901234567890123456789012345678901234567890123456789012
|
||||
3456789012345678901234567890123456789012 54th 1234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
0123456789012345678901234567890123456789012345678901234567890123456789012345678
|
||||
9012345678901234567890123456789012345678901234567890123456789012345678901234567
|
||||
8901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
7890123456789012345 this is the 60th line. 2345678901234567890123456789012345
|
||||
6789012345678901234567890123456789012345678901234567890123456789012345678901234
|
||||
5678901234567890123456789012345678901234567890123456789012345678901234567890123
|
||||
4567890123456789012345678901234567890123456789012345678901234567890123456789012
|
||||
3456789012345678901234567890123456789012345678901234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
0123456789012345678901234567890123456789012345678901234567890123456789012345678
|
||||
9012345678901234567890123456789012345678901234567890123456789012345678901234567
|
||||
8901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
7890123456789012345678901234567890123456789012345678901234567890123456789012345
|
||||
678901234 this is the 71st line. 12345678901234567890123456789012345678901234
|
||||
5678901234567890123456789012345678901234567890123456789012345678901234567890123
|
||||
4567890123456789012345678901234567890123456789012345678901234567890123456789012
|
||||
3456789012345678901234567890123456789012345678901234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
0123456789012345678901234567890123456789012345678901234567890123456789012345678
|
||||
9012345678901234567890123456789012345678901234567890123456789012345678901234567
|
||||
8901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
7890123456789012345678901234567 this is the 80th line. 567890123456789012345
|
||||
6789012345678901234567890123456789012345678901234567890123456789012345678901234
|
||||
5678901234567890123456789012345678901234567890123456789012345678901234567890123
|
||||
4567890123456789012345678901234567890123456789012345678901234567890123456789012
|
||||
3456789012345678901234567890123456789012345678901234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
0123456789012345678901234567890123456789012345678901234567890123456789012345678
|
||||
9012345678901234567890123456789012345678901234567890123456789012345678901234567
|
||||
8901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
7890123456789012345678901234567890123456789012345678901234567890123456789012345
|
||||
6789012345678901234567890123456789012345678901234567890123456789012345678901234
|
||||
5678901234567890123456789012345678901234567890123456789012345678901234567890123
|
||||
4567890123456 this is the 93th line. 3456789012345678901234567890123456789012
|
||||
3456789012345678901234567890123456789012345678901234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
0123456789012345678901234567890123456789012345678901234567890123456789012345678
|
||||
9012345678901234567890123456789012345678901234567890123456789012345678901234567
|
||||
8901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
7890123456789012345678901234567890123456789012345678901234567890123456789012345
|
||||
6789012345678901234567890123456 this is the 101st line. 456789012345678901234
|
||||
5678901234567890123456789012345678901234567890123456789012345678901234567890123
|
||||
4567890123456789012345678901234567890123456789012345678901234567890123456789012
|
||||
3456789012345678901234567890123456789012345678901234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
123456789012345678901234567890123456789012345 this is the 106th line. 3456789
|
||||
0123456789012345678901234567890123456789012345678901234567890123456789012345678
|
||||
9012345678901234567890123456789012345678901234567890123456789012345678901234567
|
||||
8901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
789012345678901234 110th 4567890123456789012345678901234567890123456789012345
|
||||
6789012345678901234567890123456789012345678901234567890123456789012345678901234
|
||||
5678901234567890123456789012345678901234567890123456789012345678901234567890123
|
||||
4567890123456789012345678901234567890123456789012345678901234567890123456789012
|
||||
34567890123456789012345678 114th 9012345678901234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
0123456789012345678901234567890123456789012345678901234567890123456789012345678
|
||||
9012345678901234567890123456789012345678901234567890123456789012345678901234567
|
||||
8901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
7890123456789012345678901234567890123456789012345678901234567890123456789012345
|
||||
67890123 this is the 121st line. 12345678901234567890123456789012345678901234
|
||||
5678901234567890123456789012345678901234567890123456789012345678901234567890123
|
||||
4567890123456789012345678901234567890123456789012345678901234567890123456789012
|
||||
3456789012345678901234567890123456789012345678901234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
this is the last line. this is the end of the file. there is no more. good bye.
|
||||
50
libexec/httpd/testsuite/data/bigfile.partial4000
Normal file
50
libexec/httpd/testsuite/data/bigfile.partial4000
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
this is the big data file. it has to be over 1 page size in length. 0123456789
|
||||
these lines are all 80 long. this is the second line. 012345678901234567890123
|
||||
4567890123456789012345678901234567890123456789012345678901234567890123456789012
|
||||
3456789012345678901234567890123456789012345678901234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
012345678901 this is the seventh line. 12345678901234567890123456789012345678
|
||||
9012345678901234567890123456789012345678901234567890123456789012345678901234567
|
||||
8901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
7890123456789012345678901234567890123456789012345678901234567890123456789012345
|
||||
6789012345678901234567890123456789012345678901234567890123456789012345678901234
|
||||
5678901234567890123456789012345678901234567890123456789012345678901234567890123
|
||||
456789 this is the 13th line, and there 127 lines in total. 67890123456789012
|
||||
3456789012345678901234567890123456789012345678901234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
0123456789012345678901234567890123456789012345678901234567890123456789012345678
|
||||
901234567890123456789012345 this is the 18th line. 456789012345678901234567
|
||||
8901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
7890123456789012345678901234567890123456789012345678901234567890123456789012345
|
||||
6789012345678901234567890123456789012345678901234567890123456789012345678901234
|
||||
5678901234567890123456789012345678901234567890123456789012345678901234567890123
|
||||
4567890123456789012345678901234567890123456789012345678901234567890123456789012
|
||||
3456789012345678901234567890123456789012345678901234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
0123456789012345678901234567890123456789012345678901234567890123456789012345678
|
||||
9012345678901234567890123456789012345678901234567890123456789012345678901234567
|
||||
8901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
78901234567890123456 this is the 31st line. 345678901234567890123456789012345
|
||||
6789012345678901234567890123456789012345678901234567890123456789012345678901234
|
||||
5678901234567890123456789012345678901234567890123456789012345678901234567890123
|
||||
4567890123456789012345678901234567890123456789012345678901234567890123456789012
|
||||
3456789012345678901234567890123456789012345678901234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
0123456789012345678901234567890123456789012345678901234567890123456789012345678
|
||||
90123456789012345678901234567890123456789 this is the 38th line. 78901234567
|
||||
8901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
7890123456789012345678901234567890123456789012345678901234567890123456789012345
|
||||
6789012345678901234567890123456789012345678901234567890123456789012345678901234
|
||||
5678901234567890123456789012345678901234567890123456789012345678901234567890123
|
||||
4567890123456789012345678901234567890123456789012345678901234567890123456789012
|
||||
3456789012345678901234567890123456789012345678901234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
012345678901234567890123456 this is the 47th line. 4567890123456789012345678
|
||||
9012345678901234567890123456789012345678901234567890123456789012345678901234567
|
||||
8901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
789012345678901234567890123456789012345678901234567 50th 7890123456789012345
|
||||
100
libexec/httpd/testsuite/data/bigfile.partial8000
Normal file
100
libexec/httpd/testsuite/data/bigfile.partial8000
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
this is the big data file. it has to be over 1 page size in length. 0123456789
|
||||
these lines are all 80 long. this is the second line. 012345678901234567890123
|
||||
4567890123456789012345678901234567890123456789012345678901234567890123456789012
|
||||
3456789012345678901234567890123456789012345678901234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
012345678901 this is the seventh line. 12345678901234567890123456789012345678
|
||||
9012345678901234567890123456789012345678901234567890123456789012345678901234567
|
||||
8901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
7890123456789012345678901234567890123456789012345678901234567890123456789012345
|
||||
6789012345678901234567890123456789012345678901234567890123456789012345678901234
|
||||
5678901234567890123456789012345678901234567890123456789012345678901234567890123
|
||||
456789 this is the 13th line, and there 127 lines in total. 67890123456789012
|
||||
3456789012345678901234567890123456789012345678901234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
0123456789012345678901234567890123456789012345678901234567890123456789012345678
|
||||
901234567890123456789012345 this is the 18th line. 456789012345678901234567
|
||||
8901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
7890123456789012345678901234567890123456789012345678901234567890123456789012345
|
||||
6789012345678901234567890123456789012345678901234567890123456789012345678901234
|
||||
5678901234567890123456789012345678901234567890123456789012345678901234567890123
|
||||
4567890123456789012345678901234567890123456789012345678901234567890123456789012
|
||||
3456789012345678901234567890123456789012345678901234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
0123456789012345678901234567890123456789012345678901234567890123456789012345678
|
||||
9012345678901234567890123456789012345678901234567890123456789012345678901234567
|
||||
8901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
78901234567890123456 this is the 31st line. 345678901234567890123456789012345
|
||||
6789012345678901234567890123456789012345678901234567890123456789012345678901234
|
||||
5678901234567890123456789012345678901234567890123456789012345678901234567890123
|
||||
4567890123456789012345678901234567890123456789012345678901234567890123456789012
|
||||
3456789012345678901234567890123456789012345678901234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
0123456789012345678901234567890123456789012345678901234567890123456789012345678
|
||||
90123456789012345678901234567890123456789 this is the 38th line. 78901234567
|
||||
8901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
7890123456789012345678901234567890123456789012345678901234567890123456789012345
|
||||
6789012345678901234567890123456789012345678901234567890123456789012345678901234
|
||||
5678901234567890123456789012345678901234567890123456789012345678901234567890123
|
||||
4567890123456789012345678901234567890123456789012345678901234567890123456789012
|
||||
3456789012345678901234567890123456789012345678901234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
012345678901234567890123456 this is the 47th line. 4567890123456789012345678
|
||||
9012345678901234567890123456789012345678901234567890123456789012345678901234567
|
||||
8901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
789012345678901234567890123456789012345678901234567 50th 7890123456789012345
|
||||
6789012345678901234567890123456789012345678901234567890123456789012345678901234
|
||||
56789012 this is the 52nd line. 1234567890123456789012345678901234567890123
|
||||
4567890123456789012345678901234567890123456789012345678901234567890123456789012
|
||||
3456789012345678901234567890123456789012 54th 1234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
0123456789012345678901234567890123456789012345678901234567890123456789012345678
|
||||
9012345678901234567890123456789012345678901234567890123456789012345678901234567
|
||||
8901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
7890123456789012345 this is the 60th line. 2345678901234567890123456789012345
|
||||
6789012345678901234567890123456789012345678901234567890123456789012345678901234
|
||||
5678901234567890123456789012345678901234567890123456789012345678901234567890123
|
||||
4567890123456789012345678901234567890123456789012345678901234567890123456789012
|
||||
3456789012345678901234567890123456789012345678901234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
0123456789012345678901234567890123456789012345678901234567890123456789012345678
|
||||
9012345678901234567890123456789012345678901234567890123456789012345678901234567
|
||||
8901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
7890123456789012345678901234567890123456789012345678901234567890123456789012345
|
||||
678901234 this is the 71st line. 12345678901234567890123456789012345678901234
|
||||
5678901234567890123456789012345678901234567890123456789012345678901234567890123
|
||||
4567890123456789012345678901234567890123456789012345678901234567890123456789012
|
||||
3456789012345678901234567890123456789012345678901234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
0123456789012345678901234567890123456789012345678901234567890123456789012345678
|
||||
9012345678901234567890123456789012345678901234567890123456789012345678901234567
|
||||
8901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
7890123456789012345678901234567 this is the 80th line. 567890123456789012345
|
||||
6789012345678901234567890123456789012345678901234567890123456789012345678901234
|
||||
5678901234567890123456789012345678901234567890123456789012345678901234567890123
|
||||
4567890123456789012345678901234567890123456789012345678901234567890123456789012
|
||||
3456789012345678901234567890123456789012345678901234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
0123456789012345678901234567890123456789012345678901234567890123456789012345678
|
||||
9012345678901234567890123456789012345678901234567890123456789012345678901234567
|
||||
8901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
7890123456789012345678901234567890123456789012345678901234567890123456789012345
|
||||
6789012345678901234567890123456789012345678901234567890123456789012345678901234
|
||||
5678901234567890123456789012345678901234567890123456789012345678901234567890123
|
||||
4567890123456 this is the 93th line. 3456789012345678901234567890123456789012
|
||||
3456789012345678901234567890123456789012345678901234567890123456789012345678901
|
||||
2345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1234567890123456789012345678901234567890123456789012345678901234567890123456789
|
||||
0123456789012345678901234567890123456789012345678901234567890123456789012345678
|
||||
9012345678901234567890123456789012345678901234567890123456789012345678901234567
|
||||
8901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
7890123456789012345678901234567890123456789012345678901234567890123456789012345
|
||||
4
libexec/httpd/testsuite/data/file
Normal file
4
libexec/httpd/testsuite/data/file
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
123456781234567
|
||||
345678903456789
|
||||
234567892345678
|
||||
012345670123456
|
||||
1
libexec/httpd/testsuite/data/index.html
Normal file
1
libexec/httpd/testsuite/data/index.html
Normal file
|
|
@ -0,0 +1 @@
|
|||
this is the bozohttpd testsuite ./data/index.html file
|
||||
27
libexec/httpd/testsuite/html_cmp
Executable file
27
libexec/httpd/testsuite/html_cmp
Executable file
|
|
@ -0,0 +1,27 @@
|
|||
#! /bin/sh
|
||||
#
|
||||
# $eterna: html_cmp,v 1.9 2011/11/17 22:18:02 mrg Exp $
|
||||
#
|
||||
# like cmp(1) but compares to files after making their `Date: ' headers
|
||||
# the same, to allow `now' and `then' to work properly. it also tries
|
||||
# to find servername's that might be the local host and converts those
|
||||
# as well..
|
||||
#
|
||||
# it must be called like `cmp file1 file1' *only*.
|
||||
|
||||
h=`hostname || uname -n`
|
||||
|
||||
sedcmd="s/^Date: .*/Date: nowish/;
|
||||
s/^Last-Modified: .*/Last-Modified: nowish/;
|
||||
s/[a-zA-Z0-9-]*\.eterna\.com\.au/$h/g;
|
||||
s/^Server: .*/^Server: bozotic HTTP server version 5.08/;
|
||||
s/^Content-Length: .*/Content-Length: 223/;"
|
||||
|
||||
sed -e "$sedcmd" < "$1" > "f1.tmp.$$"
|
||||
sed -e "$sedcmd" < "$2" > "f2.tmp.$$"
|
||||
|
||||
cmp -s "f1.tmp.$$" "f2.tmp.$$"
|
||||
rv=$?
|
||||
rm -f "f1.tmp.$$" "f2.tmp.$$"
|
||||
|
||||
exit $rv
|
||||
1
libexec/httpd/testsuite/t1.in
Normal file
1
libexec/httpd/testsuite/t1.in
Normal file
|
|
@ -0,0 +1 @@
|
|||
get /
|
||||
2
libexec/httpd/testsuite/t1.out
Normal file
2
libexec/httpd/testsuite/t1.out
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
HTTP/0.9 200 OK
|
||||
this is the bozohttpd testsuite ./data/index.html file
|
||||
1
libexec/httpd/testsuite/t10.in
Normal file
1
libexec/httpd/testsuite/t10.in
Normal file
File diff suppressed because one or more lines are too long
8
libexec/httpd/testsuite/t10.out
Normal file
8
libexec/httpd/testsuite/t10.out
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
HTTP/1.0 404 Not Found
|
||||
Content-Type: text/html
|
||||
Content-Length: 1024
|
||||
Server: bozohttpd/20140708
|
||||
|
||||
<html><head><title>404 Not Found</title></head>
|
||||
<body><h1>404 Not Found</h1>
|
||||
/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
1
libexec/httpd/testsuite/t2.in
Normal file
1
libexec/httpd/testsuite/t2.in
Normal file
|
|
@ -0,0 +1 @@
|
|||
GET / HTTP/1.0
|
||||
9
libexec/httpd/testsuite/t2.out
Normal file
9
libexec/httpd/testsuite/t2.out
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
HTTP/1.0 200 OK
|
||||
Date: Tue, 10 Jul 2001 15:45:36 GMT
|
||||
Server: bozotic HTTP server version 5.08
|
||||
Accept-Ranges: bytes
|
||||
Last-Modified: Tue, 10 Jul 2001 15:50:43 GMT
|
||||
Content-Type: text/html
|
||||
Content-Length: 55
|
||||
|
||||
this is the bozohttpd testsuite ./data/index.html file
|
||||
1
libexec/httpd/testsuite/t3.in
Normal file
1
libexec/httpd/testsuite/t3.in
Normal file
|
|
@ -0,0 +1 @@
|
|||
GET / HTTP/1.1
|
||||
11
libexec/httpd/testsuite/t3.out
Normal file
11
libexec/httpd/testsuite/t3.out
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
HTTP/1.1 400 Bad Request
|
||||
Content-Type: text/html
|
||||
Content-Length: 229
|
||||
Server: bozotic HTTP server version 5.08
|
||||
Allow: GET, HEAD, POST
|
||||
|
||||
<html><head><title>400 Bad Request</title></head>
|
||||
<body><h1>400 Bad Request</h1>
|
||||
/: <pre>The request was not valid</pre>
|
||||
<hr><address><a href="http://madrugada.eterna.com.au/">madrugada.eterna.com.au</a></address>
|
||||
</body></html>
|
||||
2
libexec/httpd/testsuite/t4.in
Normal file
2
libexec/httpd/testsuite/t4.in
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
GET / HTTP/1.1
|
||||
Host:
|
||||
10
libexec/httpd/testsuite/t4.out
Normal file
10
libexec/httpd/testsuite/t4.out
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
HTTP/1.1 200 OK
|
||||
Date: Tue, 10 Jul 2001 15:49:21 GMT
|
||||
Server: bozotic HTTP server version 5.08
|
||||
Accept-Ranges: bytes
|
||||
Last-Modified: Tue, 10 Jul 2001 15:34:33 GMT
|
||||
Content-Type: text/html
|
||||
Content-Length: 55
|
||||
Connection: close
|
||||
|
||||
this is the bozohttpd testsuite ./data/index.html file
|
||||
2
libexec/httpd/testsuite/t5.in
Normal file
2
libexec/httpd/testsuite/t5.in
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
GET /cgi-bin/..M-@M-/..M-@M-/..M-@M-/..M-@M-/..M-@M-/../winnt/system32/cmd.exe?/c+dir+c:\\ HTTP/1.0
|
||||
|
||||
10
libexec/httpd/testsuite/t5.out
Normal file
10
libexec/httpd/testsuite/t5.out
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
HTTP/1.0 403 Forbidden
|
||||
Content-Type: text/html
|
||||
Content-Length: 336
|
||||
Server: bozohttpd/20030206
|
||||
|
||||
<html><head><title>403 Forbidden</title></head>
|
||||
<body><h1>403 Forbidden</h1>
|
||||
/cgi-bin/..M-@M-/..M-@M-/..M-@M-/..M-@M-/..M-@M-/../winnt/system32/cmd.exe: <pre>Access to this item has been denied</pre>
|
||||
<hr><address><a href="http://what-time-is-love.eterna.com.au/">what-time-is-love.eterna.com.au</a></address>
|
||||
</body></html>
|
||||
2
libexec/httpd/testsuite/t6.in
Normal file
2
libexec/httpd/testsuite/t6.in
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
GET /xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx HTTP/1.0
|
||||
|
||||
10
libexec/httpd/testsuite/t6.out
Normal file
10
libexec/httpd/testsuite/t6.out
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
HTTP/1.0 404 Not Found
|
||||
Content-Type: text/html
|
||||
Content-Length: 335
|
||||
Server: bozohttpd/5.15
|
||||
|
||||
<html><head><title>404 Not Found</title></head>
|
||||
<body><h1>404 Not Found</h1>
|
||||
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: <pre>This item has not been found</pre>
|
||||
<hr><address><a href="http://splode.eterna.com.au/">splode.eterna.com.au</a></address>
|
||||
</body></html>
|
||||
4
libexec/httpd/testsuite/t7.in
Normal file
4
libexec/httpd/testsuite/t7.in
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
GET /file HTTP/1.1
|
||||
Host:
|
||||
Range: bytes=0-63
|
||||
|
||||
14
libexec/httpd/testsuite/t7.out
Normal file
14
libexec/httpd/testsuite/t7.out
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
HTTP/1.1 206 Partial Content
|
||||
Date: Sun, 02 Mar 2008 08:52:03 GMT
|
||||
Server: bozohttpd/20060710
|
||||
Accept-Ranges: bytes
|
||||
Last-Modified: Sun, 02 Mar 2008 08:44:38 GMT
|
||||
Content-Type: text/plain
|
||||
Content-Range: bytes 0-63/64
|
||||
Content-Length: 64
|
||||
Connection: close
|
||||
|
||||
123456781234567
|
||||
345678903456789
|
||||
234567892345678
|
||||
012345670123456
|
||||
4
libexec/httpd/testsuite/t8.in
Normal file
4
libexec/httpd/testsuite/t8.in
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
GET /file HTTP/1.1
|
||||
Host:
|
||||
Range: bytes=0-31
|
||||
|
||||
12
libexec/httpd/testsuite/t8.out
Normal file
12
libexec/httpd/testsuite/t8.out
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
HTTP/1.1 206 Partial Content
|
||||
Date: Sun, 02 Mar 2008 08:52:03 GMT
|
||||
Server: bozohttpd/20060710
|
||||
Accept-Ranges: bytes
|
||||
Last-Modified: Sun, 02 Mar 2008 08:44:38 GMT
|
||||
Content-Type: text/plain
|
||||
Content-Range: bytes 0-31/64
|
||||
Content-Length: 32
|
||||
Connection: close
|
||||
|
||||
123456781234567
|
||||
345678903456789
|
||||
4
libexec/httpd/testsuite/t9.in
Normal file
4
libexec/httpd/testsuite/t9.in
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
GET /file HTTP/1.1
|
||||
Host:
|
||||
Range: bytes=32-63
|
||||
|
||||
12
libexec/httpd/testsuite/t9.out
Normal file
12
libexec/httpd/testsuite/t9.out
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
HTTP/1.1 206 Partial Content
|
||||
Date: Sun, 02 Mar 2008 08:52:03 GMT
|
||||
Server: bozohttpd/20060710
|
||||
Accept-Ranges: bytes
|
||||
Last-Modified: Sun, 02 Mar 2008 08:44:38 GMT
|
||||
Content-Type: text/plain
|
||||
Content-Range: bytes 32-63/64
|
||||
Content-Length: 32
|
||||
Connection: close
|
||||
|
||||
234567892345678
|
||||
012345670123456
|
||||
27
libexec/httpd/testsuite/test-bigfile
Executable file
27
libexec/httpd/testsuite/test-bigfile
Executable file
|
|
@ -0,0 +1,27 @@
|
|||
#! /bin/sh
|
||||
|
||||
test="$1" # partial4000 or partial8000
|
||||
bozohttpd="$2"
|
||||
wget="$3"
|
||||
datadir="$4"
|
||||
|
||||
bozotestport=11111
|
||||
|
||||
# copy beginning file
|
||||
cp ./data/bigfile.${test} ./bigfile
|
||||
|
||||
# fire up bozohttpd
|
||||
${bozohttpd} -b -b -I ${bozotestport} -n -s -f ${datadir} &
|
||||
bozopid=$!
|
||||
|
||||
${wget} -c http://localhost:${bozotestport}/bigfile
|
||||
|
||||
kill -9 $bozopid
|
||||
|
||||
if cmp ./bigfile ./data/bigfile; then
|
||||
rm -f ./bigfile
|
||||
exit 0
|
||||
else
|
||||
rm -f ./bigfile
|
||||
exit 1
|
||||
fi
|
||||
140
libexec/httpd/tilde-luzah-bozo.c
Normal file
140
libexec/httpd/tilde-luzah-bozo.c
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
/* $NetBSD: tilde-luzah-bozo.c,v 1.11 2015/07/16 12:19:23 shm Exp $ */
|
||||
|
||||
/* $eterna: tilde-luzah-bozo.c,v 1.16 2011/11/18 09:21:15 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997-2014 Matthew R. Green
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 and
|
||||
* dedication in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* this code implements ~user support for bozohttpd */
|
||||
|
||||
#ifndef NO_USER_SUPPORT
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "bozohttpd.h"
|
||||
|
||||
/*
|
||||
* bozo_user_transform does this:
|
||||
* - chdir's /~user/public_html
|
||||
* - returns the rest of the file, index.html appended if required
|
||||
* - returned malloced file to serve in request->hr_file,
|
||||
* ala transform_request().
|
||||
*
|
||||
* transform_request() is supposed to check that we have user support
|
||||
* enabled.
|
||||
*/
|
||||
int
|
||||
bozo_user_transform(bozo_httpreq_t *request, int *isindex)
|
||||
{
|
||||
bozohttpd_t *httpd = request->hr_httpd;
|
||||
char c, *s, *file = NULL, *user;
|
||||
struct passwd *pw;
|
||||
|
||||
*isindex = 0;
|
||||
|
||||
/* find username */
|
||||
user = strchr(request->hr_file + 2, '~');
|
||||
|
||||
/* this shouldn't happen, but "better paranoid than sorry" */
|
||||
assert(user != NULL);
|
||||
|
||||
user++;
|
||||
|
||||
if ((s = strchr(user, '/')) != NULL) {
|
||||
*s++ = '\0';
|
||||
c = s[strlen(s)-1];
|
||||
*isindex = (c == '/' || c == '\0');
|
||||
}
|
||||
|
||||
debug((httpd, DEBUG_OBESE, "looking for user %s",
|
||||
user));
|
||||
pw = getpwnam(user);
|
||||
/* fix this up immediately */
|
||||
if (s)
|
||||
s[-1] = '/';
|
||||
if (pw == NULL) {
|
||||
(void)bozo_http_error(httpd, 404, request, "no such user");
|
||||
return 0;
|
||||
}
|
||||
|
||||
debug((httpd, DEBUG_OBESE, "user %s dir %s/%s uid %d gid %d",
|
||||
pw->pw_name, pw->pw_dir, httpd->public_html,
|
||||
pw->pw_uid, pw->pw_gid));
|
||||
|
||||
if (chdir(pw->pw_dir) < 0) {
|
||||
bozo_warn(httpd, "chdir1 error: %s: %s", pw->pw_dir,
|
||||
strerror(errno));
|
||||
(void)bozo_http_error(httpd, 404, request,
|
||||
"can't chdir to homedir");
|
||||
return 0;
|
||||
}
|
||||
if (chdir(httpd->public_html) < 0) {
|
||||
bozo_warn(httpd, "chdir2 error: %s: %s", httpd->public_html,
|
||||
strerror(errno));
|
||||
(void)bozo_http_error(httpd, 404, request,
|
||||
"can't chdir to public_html");
|
||||
return 0;
|
||||
}
|
||||
if (s == NULL || *s == '\0') {
|
||||
file = bozostrdup(httpd, httpd->index_html);
|
||||
} else {
|
||||
file = bozomalloc(httpd, strlen(s) +
|
||||
(*isindex ? strlen(httpd->index_html) + 1 : 1));
|
||||
strcpy(file, s);
|
||||
if (*isindex)
|
||||
strcat(file, httpd->index_html);
|
||||
}
|
||||
|
||||
/* see transform_request() */
|
||||
if (*file == '/' || strcmp(file, "..") == 0 ||
|
||||
strstr(file, "/..") || strstr(file, "../")) {
|
||||
(void)bozo_http_error(httpd, 403, request, "illegal request");
|
||||
free(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bozo_auth_check(request, file)) {
|
||||
free(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
free(request->hr_file);
|
||||
request->hr_file = file;
|
||||
|
||||
debug((httpd, DEBUG_FAT, "transform_user returning %s under %s", file,
|
||||
pw->pw_dir));
|
||||
return 1;
|
||||
}
|
||||
#endif /* NO_USER_SUPPORT */
|
||||
Loading…
Reference in New Issue
Block a user