From f0cd1af781b4465c9c8fa2ec8d86ca6d03a63e6a Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Tue, 30 Oct 2012 17:45:19 -0600 Subject: [PATCH 1/7] Make it easier to Debianize --- CHANGES | 4 + Makefile | 3 +- cgi.c | 213 ------------------------------------- eris.c | 253 ++++++++++++++++++++++++++++++++++++++++---- mime.c | 6 +- mime.h | 6 ++ strings.c | 6 +- strings.h | 13 +++ time.c => timerfc.c | 7 +- timerfc.h | 9 ++ 10 files changed, 283 insertions(+), 237 deletions(-) delete mode 100644 cgi.c create mode 100644 mime.h create mode 100644 strings.h rename time.c => timerfc.c (98%) create mode 100644 timerfc.h diff --git a/CHANGES b/CHANGES index 1de7c2a..4efac8d 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +3.1.1: + Restructured code to make it easier to package for Debian. + I hate you so much right now, Ryan. + 3.1: Add -. flag to disable vhosting Support server push CGI diff --git a/Makefile b/Makefile index e648f37..8f904d8 100644 --- a/Makefile +++ b/Makefile @@ -4,8 +4,7 @@ CFLAGS = -DFNORD='"eris/$(VERSION)"' -Wall -Werror all: eris -eris: eris.c strings.c mime.c time.c cgi.c - $(CC) $(CFLAGS) -o $@ $< +eris: eris.o strings.o mime.o timerfc.o test: eris sh ./test.sh diff --git a/cgi.c b/cgi.c deleted file mode 100644 index 3a912bc..0000000 --- a/cgi.c +++ /dev/null @@ -1,213 +0,0 @@ -void -sigchld(int sig) -{ - while (waitpid(0, NULL, WNOHANG) > 0); -} - -void -sigalarm_cgi(int sig) -{ - /* send this out regardless of whether we've already sent a header, - * to maybe help with debugging */ - badrequest(504, "Gateway Timeout", "The CGI is being too slow."); -} - -static void -cgi_child(const char *relpath) -{ - env("GATEWAY_INTERFACE", "CGI/1.1"); - env("SERVER_SOFTWARE", FNORD); - env("REQUEST_URI", path); - env("SERVER_NAME", host); - env("SCRIPT_NAME", relpath); - env("REMOTE_ADDR", remote_addr); - env("REMOTE_IDENT", remote_ident); - if (content_length) { - char cl[20]; - - snprintf(cl, sizeof cl, "%llu", (unsigned long long) content_length); - env("CONTENT_LENGTH", cl); - env("CONTENT_TYPE", content_type); - } - - /* Change to CGI's directory */ - { - char *delim = strrchr(relpath, '/'); - - if (delim) { - *delim = '\0'; - chdir(relpath); - relpath = delim + 1; - } - } - - execl(relpath, relpath, NULL); - exit(1); -} - -void -cgi_parent(int cin, int cout, int passthru) -{ - char cgiheader[BUFFER_SIZE]; - size_t cgiheaderlen = 0; - FILE *cinf = fdopen(cin, "rb"); - size_t size = 0; - int header_sent = 0; - int code = 200; - - fcntl(cin, F_SETFL, O_NONBLOCK); - signal(SIGCHLD, sigchld); - signal(SIGPIPE, SIG_IGN); /* NO! no signal! */ - - while (1) { - int nfds; - fd_set rfds, wfds; - - FD_ZERO(&rfds); - FD_ZERO(&wfds); - FD_SET(cin, &rfds); - nfds = cin; - - if (content_length) { - /* have post data */ - FD_SET(cout, &wfds); - if (cout > nfds) { - nfds = cout; - } - } else if (cout >= 0) { - close(cout); /* no post data */ - cout = -1; - } - - if (-1 == select(nfds+1, &rfds, &wfds, NULL, NULL)) { - break; - } - - if (FD_ISSET(cin, &rfds)) { - if (passthru) { - /* Pass everything through verbatim */ - size_t len; - - /* Re-use this big buffer */ - len = fread(cgiheader, 1, sizeof cgiheader, cinf); - if (0 == len) { - /* CGI is done */ - break; - } - fwrite(cgiheader, 1, len, stdout); - - /* Naively assume the CGI knows best about sending stuff */ - fflush(stdout); - size += len; - } else { - /* Interpret header fields */ - size_t readlen = (sizeof cgiheader) - cgiheaderlen; - - if (NULL == fgets(cgiheader + cgiheaderlen, readlen, cinf)) { - /* EOF or error */ - badrequest(500, "CGI Error", "CGI output too weird"); - } - cgiheaderlen = strlen(cgiheader); - - if ('\n' == cgiheader[cgiheaderlen - 1]) { - /* We read a whole line */ - size_t len; - char *val; - - len = extract_header_field(cgiheader, &val, 0); - if (! len) { - /* We've read the entire header block */ - passthru = 1; - eoh(); - } else { - if (! header_sent) { - if (! strcasecmp(cgiheader, "Location")) { - header(302, "CGI Redirect"); - printf("%s: %s\r\n\r\n", cgiheader, val); - dolog(302, 0); - exit(0); - } else if (! strcasecmp(cgiheader, "Status")) { - char *txt = val + 4; - - code = atoi(val); - header(code, txt); - } else { - header(200, "OK"); - printf("Pragma: no-cache\r\n"); - } - header_sent = 1; - } - printf("%s: %s\r\n", cgiheader, val); - cgiheaderlen = 0; - } - } - } - } else if (FD_ISSET(cout, &wfds)) { - /* - * write to cgi the post data - */ - if (content_length) { - size_t len; - char buf[BUFFER_SIZE]; - size_t nmemb = min(BUFFER_SIZE, content_length); - - len = fread(buf, 1, nmemb, stdin); - if (len < 1) { - break; - } - content_length -= len; - write(cout, buf, len); - } else { - close(cout); - } - } - } - - fflush(stdout); - dolog(200, size); - cork(0); -} - -void -serve_cgi(char *relpath) -{ - int pid; - int cin[2]; - int cout[2]; - - if (pipe(cin) || pipe(cout)) { - badrequest(500, "Internal Server Error", "Server Resource problem."); - } - - pid = fork(); - if (-1 == pid) { - badrequest(500, "Internal Server Error", "Unable to fork."); - } - if (pid) { - close(cin[1]); - close(cout[0]); - - /* Eris is not this smart yet */ - keepalive = 0; - - alarm(CGI_TIMEOUT); - signal(SIGALRM, sigalarm_cgi); - cgi_parent(cin[0], cout[1], 0); - - exit(0); - } else { - close(cwd); - close(cout[1]); - close(cin[0]); - - dup2(cout[0], 0); - dup2(cin[1], 1); - - close(cout[0]); - close(cin[1]); - - cgi_child(relpath); - } -} - - diff --git a/eris.c b/eris.c index c05a9b1..e12ee78 100644 --- a/eris.c +++ b/eris.c @@ -22,6 +22,10 @@ #include #include +#include "strings.h" +#include "mime.h" +#include "timerfc.h" + #ifdef __linux__ # include #else @@ -69,6 +73,8 @@ /* Maximum number of header fields */ #define MAXHEADERFIELDS 60 +#define BUFFER_SIZE 8192 + /* * Options */ @@ -102,13 +108,6 @@ off_t range_start, range_end; time_t ims; -#define BUFFER_SIZE 8192 -char stdout_buf[BUFFER_SIZE]; - -#include "strings.c" -#include "mime.c" -#include "time.c" - /* * TCP_CORK is a Linux extension to work around a TCP problem. * http://www.baus.net/on-tcp_cork has a good description. @@ -129,7 +128,7 @@ cork(int enable) } /** Log a request */ -static void +void dolog(int code, off_t len) { /* write a log line to stderr */ sanitize(host); @@ -157,7 +156,7 @@ eoh() /* * output an error message and exit */ -static void +void badrequest(long code, const char *httpcomment, const char *message) { size_t msglen = 0; @@ -178,15 +177,7 @@ badrequest(long code, const char *httpcomment, const char *message) exit(0); } -void -env(const char *k, const char *v) -{ - if (v) { - setenv(k, v, 1); - } -} -#include "cgi.c" void not_found() @@ -202,6 +193,14 @@ not_found() fflush(stdout); } +void +env(const char *k, const char *v) +{ + if (v) { + setenv(k, v, 1); + } +} + char * proto_getenv(char *proto, char *name) { @@ -285,6 +284,224 @@ parse_options(int argc, char *argv[]) } } +/* + * CGI stuff + */ +static void +sigchld(int sig) +{ + while (waitpid(0, NULL, WNOHANG) > 0); +} + +static void +sigalarm_cgi(int sig) +{ + /* send this out regardless of whether we've already sent a header, + * to maybe help with debugging */ + badrequest(504, "Gateway Timeout", "The CGI is being too slow."); +} + +static void +cgi_child(const char *relpath) +{ + env("GATEWAY_INTERFACE", "CGI/1.1"); + env("SERVER_SOFTWARE", FNORD); + env("REQUEST_URI", path); + env("SERVER_NAME", host); + env("SCRIPT_NAME", relpath); + env("REMOTE_ADDR", remote_addr); + env("REMOTE_IDENT", remote_ident); + if (content_length) { + char cl[20]; + + snprintf(cl, sizeof cl, "%llu", (unsigned long long) content_length); + env("CONTENT_LENGTH", cl); + env("CONTENT_TYPE", content_type); + } + + /* Change to CGI's directory */ + { + char *delim = strrchr(relpath, '/'); + + if (delim) { + *delim = '\0'; + chdir(relpath); + relpath = delim + 1; + } + } + + execl(relpath, relpath, NULL); + exit(1); +} + +void +cgi_parent(int cin, int cout, int passthru) +{ + char cgiheader[BUFFER_SIZE]; + size_t cgiheaderlen = 0; + FILE *cinf = fdopen(cin, "rb"); + size_t size = 0; + int header_sent = 0; + int code = 200; + + fcntl(cin, F_SETFL, O_NONBLOCK); + signal(SIGCHLD, sigchld); + signal(SIGPIPE, SIG_IGN); /* NO! no signal! */ + + while (1) { + int nfds; + fd_set rfds, wfds; + + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_SET(cin, &rfds); + nfds = cin; + + if (content_length) { + /* have post data */ + FD_SET(cout, &wfds); + if (cout > nfds) { + nfds = cout; + } + } else if (cout >= 0) { + close(cout); /* no post data */ + cout = -1; + } + + if (-1 == select(nfds+1, &rfds, &wfds, NULL, NULL)) { + break; + } + + if (FD_ISSET(cin, &rfds)) { + if (passthru) { + /* Pass everything through verbatim */ + size_t len; + + /* Re-use this big buffer */ + len = fread(cgiheader, 1, sizeof cgiheader, cinf); + if (0 == len) { + /* CGI is done */ + break; + } + fwrite(cgiheader, 1, len, stdout); + + /* Naively assume the CGI knows best about sending stuff */ + fflush(stdout); + size += len; + } else { + /* Interpret header fields */ + size_t readlen = (sizeof cgiheader) - cgiheaderlen; + + if (NULL == fgets(cgiheader + cgiheaderlen, readlen, cinf)) { + /* EOF or error */ + badrequest(500, "CGI Error", "CGI output too weird"); + } + cgiheaderlen = strlen(cgiheader); + + if ('\n' == cgiheader[cgiheaderlen - 1]) { + /* We read a whole line */ + size_t len; + char *val; + + len = extract_header_field(cgiheader, &val, 0); + if (! len) { + /* We've read the entire header block */ + passthru = 1; + eoh(); + } else { + if (! header_sent) { + if (! strcasecmp(cgiheader, "Location")) { + header(302, "CGI Redirect"); + printf("%s: %s\r\n\r\n", cgiheader, val); + dolog(302, 0); + exit(0); + } else if (! strcasecmp(cgiheader, "Status")) { + char *txt = val + 4; + + code = atoi(val); + header(code, txt); + } else { + header(200, "OK"); + printf("Pragma: no-cache\r\n"); + } + header_sent = 1; + } + printf("%s: %s\r\n", cgiheader, val); + cgiheaderlen = 0; + } + } + } + } else if (FD_ISSET(cout, &wfds)) { + /* + * write to cgi the post data + */ + if (content_length) { + size_t len; + char buf[BUFFER_SIZE]; + size_t nmemb = min(BUFFER_SIZE, content_length); + + len = fread(buf, 1, nmemb, stdin); + if (len < 1) { + break; + } + content_length -= len; + write(cout, buf, len); + } else { + close(cout); + } + } + } + + fflush(stdout); + dolog(200, size); + cork(0); +} + +void +serve_cgi(char *relpath) +{ + int pid; + int cin[2]; + int cout[2]; + + if (pipe(cin) || pipe(cout)) { + badrequest(500, "Internal Server Error", "Server Resource problem."); + } + + pid = fork(); + if (-1 == pid) { + badrequest(500, "Internal Server Error", "Unable to fork."); + } + if (pid) { + close(cin[1]); + close(cout[0]); + + /* Eris is not this smart yet */ + keepalive = 0; + + alarm(CGI_TIMEOUT); + signal(SIGALRM, sigalarm_cgi); + cgi_parent(cin[0], cout[1], 0); + + exit(0); + } else { + close(cwd); + close(cout[1]); + close(cin[0]); + + dup2(cout[0], 0); + dup2(cin[1], 1); + + close(cout[0]); + close(cin[1]); + + cgi_child(relpath); + } +} + +/* + * Main HTTPd + */ void fake_sendfile(int out_fd, int in_fd, off_t *offset, size_t count) @@ -764,8 +981,6 @@ main(int argc, char *argv[], const char *const *envp) cwd = open(".", O_RDONLY); - setbuffer(stdout, stdout_buf, sizeof stdout_buf); - signal(SIGPIPE, SIG_IGN); get_ucspi_env(); diff --git a/mime.c b/mime.c index 869ca82..3ea848c 100644 --- a/mime.c +++ b/mime.c @@ -1,3 +1,7 @@ +#include +#include +#include "mime.h" + static struct mimeentry { const char *name, *type; @@ -44,7 +48,7 @@ static const char *default_mimetype = "application/octet-stream"; /* * Determine MIME type from file extension */ -static const char * +const char * getmimetype(char *url) { char *ext = strrchr(url, '.'); diff --git a/mime.h b/mime.h new file mode 100644 index 0000000..dffacc2 --- /dev/null +++ b/mime.h @@ -0,0 +1,6 @@ +#ifndef __MIME_H__ +#define __MIME_H__ + +const char *getmimetype(char *url); + +#endif diff --git a/strings.c b/strings.c index 0611456..f13670b 100644 --- a/strings.c +++ b/strings.c @@ -1,3 +1,7 @@ +#include +#include +#include "strings.h" + int endswith(char *haystack, char *needle) { @@ -20,7 +24,7 @@ endswith(char *haystack, char *needle) } /** Replace whitespace with underscores for logging */ -static void +void sanitize(char *s) { if (!s) { diff --git a/strings.h b/strings.h new file mode 100644 index 0000000..de2bfcb --- /dev/null +++ b/strings.h @@ -0,0 +1,13 @@ +#ifndef __STRINGS_H__ +#define __STRINGS_H__ + +#include + +int endswith(char *haystack, char *needle); +void sanitize(char *s); +size_t extract_header_field(char *buf, char **val, int cgi); +int fromhex(int c); +void html_esc(FILE *f, char *s); +void url_esc(FILE *f, char *s); + +#endif diff --git a/time.c b/timerfc.c similarity index 98% rename from time.c rename to timerfc.c index 2b7053a..1ac48ca 100644 --- a/time.c +++ b/timerfc.c @@ -35,10 +35,15 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ +#include +#include +#include +#include "timerfc.h" + static const char days[] = "SunMonTueWedThuFriSat"; static const char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec"; -static time_t +time_t timerfc(const char *s) { static const int daytab[2][12] = { diff --git a/timerfc.h b/timerfc.h new file mode 100644 index 0000000..5805d5f --- /dev/null +++ b/timerfc.h @@ -0,0 +1,9 @@ +#ifndef __TIMERFC_H__ +#define __TIMERFC_H__ + +#include + +time_t timerfc(const char *s); +char *rfctime(time_t t, char *buf); + +#endif From b9d6c8ce98689db2c6facc576b71f6d7f2643f17 Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Tue, 30 Oct 2012 19:10:55 -0600 Subject: [PATCH 2/7] Quit needing CFLAGS --- .gitignore | 2 ++ Makefile | 10 ++++++---- eris.c | 28 +++++++++++++++++++++------- 3 files changed, 29 insertions(+), 11 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1214681 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.o +version.h diff --git a/Makefile b/Makefile index 8f904d8..1ff388e 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,15 @@ -VERSION := $(shell head -n 1 CHANGES | tr -d :) - -CFLAGS = -DFNORD='"eris/$(VERSION)"' -Wall -Werror +CFLAGS = -Wall -Werror all: eris eris: eris.o strings.o mime.o timerfc.o +eris.o: version.h +version.h: CHANGES + awk -F : 'NR==1 {printf("const char *FNORD = \"eris/%s\";\n", $$1);}' $< > $@ + test: eris sh ./test.sh clean: - rm -f *.[oa] eris + rm -f *.[oa] version.h eris diff --git a/eris.c b/eris.c index e12ee78..1e6ef34 100644 --- a/eris.c +++ b/eris.c @@ -25,6 +25,7 @@ #include "strings.h" #include "mime.h" #include "timerfc.h" +#include "version.h" #ifdef __linux__ # include @@ -143,7 +144,7 @@ void header(unsigned int code, const char *httpcomment) { printf("HTTP/1.%d %u %s\r\n", http_version, code, httpcomment); - printf("Server: " FNORD "\r\n"); + printf("Server: %s\r\n", FNORD); printf("Connection: %s\r\n", keepalive?"keep-alive":"close"); } @@ -265,7 +266,7 @@ parse_options(int argc, char *argv[]) redirect = 1; break; case 'v': - printf(FNORD "\n"); + printf("%s\n", FNORD); exit(0); case 'h': default: @@ -319,14 +320,15 @@ cgi_child(const char *relpath) env("CONTENT_TYPE", content_type); } - /* Change to CGI's directory */ + /* Try to change to CGI's directory */ { char *delim = strrchr(relpath, '/'); if (delim) { *delim = '\0'; - chdir(relpath); - relpath = delim + 1; + if (0 == chdir(relpath)) { + relpath = delim + 1; + } } } @@ -439,13 +441,23 @@ cgi_parent(int cin, int cout, int passthru) size_t len; char buf[BUFFER_SIZE]; size_t nmemb = min(BUFFER_SIZE, content_length); + char *p = buf; len = fread(buf, 1, nmemb, stdin); if (len < 1) { break; } content_length -= len; - write(cout, buf, len); + + while (len > 0) { + size_t wlen = write(cout, p, len); + + if (wlen == -1) { + break; + } + len -= wlen; + p += wlen; + } } else { close(cout); } @@ -989,7 +1001,9 @@ main(int argc, char *argv[], const char *const *envp) if (! keepalive) { break; } - fchdir(cwd); + if (-1 == fchdir(cwd)) { + break; + } } return 0; From c73f0b6d0dd8f2a1acca94232b02b4770420a14b Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Tue, 30 Oct 2012 19:15:49 -0600 Subject: [PATCH 3/7] Version bump --- CHANGES | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES b/CHANGES index 4efac8d..0423086 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +3.1.2: + Change how version is extracted from CHANGES, to deal with + build systems that set CFLAGS. + 3.1.1: Restructured code to make it easier to package for Debian. I hate you so much right now, Ryan. From 747cd86e65c41a3ed13403205bf80da892e1f43f Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Wed, 7 Nov 2012 18:45:42 -0700 Subject: [PATCH 4/7] Remove -a option, add contrib directory There wasn't actually any authentication code in eris.c. I'll add it back in if anybody asks. --- contrib/README | 9 +++++++++ contrib/g.cgi.c | 31 +++++++++++++++++++++++++++++++ eris.c | 7 +------ 3 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 contrib/README create mode 100644 contrib/g.cgi.c diff --git a/contrib/README b/contrib/README new file mode 100644 index 0000000..bdcc8a1 --- /dev/null +++ b/contrib/README @@ -0,0 +1,9 @@ +This directory contains little wrappers to help make your life +running a full Internet-facing web server (such as woozle.org) +a little easier. + +Quite a lot of web software these days is written to work with +Apache and nothing else. PHP is a notable example: even PHP-CGI, +as shipped on Debian, requires special environment variables that +only Apache sets, and doesn't work with eg. mathopd, boa, busybox +httpd, or eris. diff --git a/contrib/g.cgi.c b/contrib/g.cgi.c new file mode 100644 index 0000000..0e885e0 --- /dev/null +++ b/contrib/g.cgi.c @@ -0,0 +1,31 @@ +/** g.cgi - CGI interface to cgit and git-http-backend + * + * This is a simple CGI to invoke cgit with a configuration + * file of your choice. It will also invoke git-http-backend + * if appropriate, which in my (very light) testing runs about + * twice as fast as plain HTTP with git-update-server-info. + */ +#include +#include +#include + +/* Set these to appropriate paths */ +#define CGIT_CONFIG "/home/neale/public_html/cgitrc" +#define GIT_PROJECT_ROOT "/home/neale/projects" + +int +main(int argc, char *argv[]) +{ + char *uri = getenv("REQUEST_URI"); + + if (uri && strstr(uri, "git-upload-pack")) { + /* Use git-http-backend for great speed! */ + setenv("GIT_PROJECT_ROOT", GIT_PROJECT_ROOT, 1); + execlp("git", "git", "http-backend", NULL); + } else { + setenv("CGIT_CONFIG", CGIT_CONFIG, 1); + execlp("cgit", "cgit", NULL); + } + + return 0; +} diff --git a/eris.c b/eris.c index 1e6ef34..3c77310 100644 --- a/eris.c +++ b/eris.c @@ -79,7 +79,6 @@ /* * Options */ -int doauth = 0; int docgi = 0; int doidx = 0; int nochdir = 0; @@ -245,11 +244,8 @@ parse_options(int argc, char *argv[]) { int opt; - while (-1 != (opt = getopt(argc, argv, "acdhkprv."))) { + while (-1 != (opt = getopt(argc, argv, "cdhkprv."))) { switch (opt) { - case 'a': - doauth = 1; - break; case 'c': docgi = 1; break; @@ -273,7 +269,6 @@ parse_options(int argc, char *argv[]) fprintf(stderr, "Usage: %s [OPTIONS]\n", argv[0]); fprintf(stderr, "\n"); - fprintf(stderr, "-a Enable authentication\n"); fprintf(stderr, "-c Enable CGI\n"); fprintf(stderr, "-d Enable directory listing\n"); fprintf(stderr, "-. Serve out of ./ (no vhosting)\n"); From 1edc4dff7748d31a78fb3d6ec5dac215befb3ace Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Wed, 7 Nov 2012 19:23:28 -0700 Subject: [PATCH 5/7] Log directory indexes, add webfs script --- contrib/webfs | 14 ++++++++++++++ eris.c | 6 ++++-- test.sh | 5 ++++- 3 files changed, 22 insertions(+), 3 deletions(-) create mode 100755 contrib/webfs diff --git a/contrib/webfs b/contrib/webfs new file mode 100755 index 0000000..9678e09 --- /dev/null +++ b/contrib/webfs @@ -0,0 +1,14 @@ +#! /bin/sh + +PORT=8888 + +if [ $# = 0 ]; then + ARGS=-d +fi + +addr=$(ifconfig | awk -F '[: ]+' '/inet addr/ {print $4;}' \ + | grep -Fv 127.0.0.1 | head -n 1) + +echo Listening on http://$addr:$PORT/ + +tcpsvd 0 $PORT eris -. $ARGS "$@" diff --git a/eris.c b/eris.c index 3c77310..d5cd6e0 100644 --- a/eris.c +++ b/eris.c @@ -616,7 +616,7 @@ serve_idx(int fd, char *path) html_esc(stdout, path); printf("

Directory Listing: "); html_esc(stdout, path); - printf("

");
+    printf("
\n");
     if (path[1]) {
         printf("Parent Directory\n");
     }
@@ -661,7 +661,9 @@ serve_idx(int fd, char *path)
         url_esc(stdout, name);
         printf("\n");
     }
-    printf("
"); + printf("
\n"); + + dolog(200, 0); } void diff --git a/test.sh b/test.sh index e7ca56d..c1b8d7d 100755 --- a/test.sh +++ b/test.sh @@ -180,11 +180,14 @@ printf 'GET / HTTP/1.1\r\nIf-Modified-Since: %s\r\n\r\nGET / HTTP/1.0\r\n\r\n' " H "Directory indexing" title "Basic index" -printf 'GET /empty/ HTTP/1.0\r\n\r\n' | $HTTPD_IDX 2>/dev/null | d | grep -Fq '

Directory Listing: /empty/

Parent Directory%
' && pass || fail +printf 'GET /empty/ HTTP/1.0\r\n\r\n' | $HTTPD_IDX 2>/dev/null | d | grep -Fq '

Directory Listing: /empty/

%Parent Directory%
' && pass || fail title "Hidden file" printf 'GET /subdir/ HTTP/1.0\r\n\r\n' | $HTTPD_IDX 2>/dev/null | grep -q 'hidden' && fail || pass +title "Logging" +(printf 'GET /empty/ HTTP/1.0\r\n\r\n' | + PROTO=TCP TCPREMOTEPORT=1234 TCPREMOTEIP=10.0.0.2 $HTTPD_IDX >/dev/null) 2>&1 | grep -q '^10.0.0.2:1234 200 0 (null) (null) (null) /empty/$' && pass || fail H "CGI" From 47ab2f0833da7b7bdcd92196b5bd012c73fabd4f Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Wed, 7 Nov 2012 19:30:33 -0700 Subject: [PATCH 6/7] Update changelog --- CHANGES | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGES b/CHANGES index 0423086..5e57871 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ +3.1.3: + Have directory indexes generate a log entry + Remove nop -a option + Add some accessories in contrib/ + 3.1.2: Change how version is extracted from CHANGES, to deal with build systems that set CFLAGS. From 78dec35acd3e12a01a037244ce64d0d1b7de4cc4 Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Sun, 9 Dec 2012 15:12:14 -0700 Subject: [PATCH 7/7] Log on 304 --- CHANGES | 3 +++ README.SSL | 26 ++++++++++++++++++++++++++ eris.c | 1 + test.sh | 3 +++ 4 files changed, 33 insertions(+) create mode 100644 README.SSL diff --git a/CHANGES b/CHANGES index 5e57871..0900fe5 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +3.1.4: + Have 304 (Not Modified) responses generate a log entry + 3.1.3: Have directory indexes generate a log entry Remove nop -a option diff --git a/README.SSL b/README.SSL new file mode 100644 index 0000000..8a087c9 --- /dev/null +++ b/README.SSL @@ -0,0 +1,26 @@ +SSL with eris +============= + +Eris does not care what transport is in use: that job is left to the invoking +program (eg. tcpserver). + +Gerrit Pape's `ipsvd` package comes with two programs for running SSL daemons: +`sslsvd` and `sslio`. At the time of this writing, however, Gerrit's `ipsvd` +has no support for IPv6. Busybox `ipsvd`, and `ucspi-tcp-ipv6`, both do +support IPv6. + +Here is how you can support SSL *and* IPv6: + + cd /srv/www + HTTPS=enabled; export HTTPS + exec tcpserver -H -R 0 443 \ + /usr/bin/sslio -u nobody:ssl-cert -U www-data \ + -C /path/to/mydomain.crt -K /path/to/mydomain.key \ + /service/httpd/eris -c + +This uses `tcpserver` to listen for and accept TCP4 and TCP6 connections. +These connections are then handed to `sslio`, which drops permissions to +`nobody:ssl-cert` and starts speaking SSL to `eris` running as `www-data`. + +I like to set the `HTTPS` environment variable also, so CGI can tell whether or +not its connection is secure. diff --git a/eris.c b/eris.c index d5cd6e0..fbd24ac 100644 --- a/eris.c +++ b/eris.c @@ -553,6 +553,7 @@ serve_file(int fd, char *filename, struct stat *st) if (st->st_mtime <= ims) { header(304, "Not Changed"); eoh(); + dolog(304, 0); return; } diff --git a/test.sh b/test.sh index c1b8d7d..f67f80b 100755 --- a/test.sh +++ b/test.sh @@ -175,6 +175,9 @@ printf 'GET / HTTP/1.0\r\nIf-Modified-Since: Sun Feb 27 12:12:12 2030\r\n\r\n' | title "ims persist" printf 'GET / HTTP/1.1\r\nIf-Modified-Since: %s\r\n\r\nGET / HTTP/1.0\r\n\r\n' "$ims" | $HTTPD 2>/dev/null | d | grep -q 'HTTP/1.. 304.*HTTP/1.. 200' && pass || fail +title "Logging" +(printf 'GET / HTTP/1.0\r\nIf-Modified-Since: %s\r\n\r\n' "$ims" | $HTTPD > /dev/null) 2>&1 | grep -q '304' && pass || fail + H "Directory indexing"