From d422fdfd62d851b345562ad4d093465d2bec604b Mon Sep 17 00:00:00 2001 From: Fredrik Tolf Date: Sun, 21 Dec 2008 20:53:50 +0100 Subject: [PATCH] Send error reports from dirplex. --- lib/Makefile.am | 2 +- lib/resp.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/resp.h | 6 +++++ lib/utils.c | 26 ++++++++++++++++++ lib/utils.h | 2 ++ src/dirplex.c | 16 ++++++++--- 6 files changed, 130 insertions(+), 4 deletions(-) create mode 100644 lib/resp.c create mode 100644 lib/resp.h diff --git a/lib/Makefile.am b/lib/Makefile.am index b5cc5f6..c5471a8 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -1,4 +1,4 @@ noinst_LIBRARIES = libht.a -libht_a_SOURCES = utils.c mt.c log.c req.c proc.c mtio.c +libht_a_SOURCES = utils.c mt.c log.c req.c proc.c mtio.c resp.c libht_a_CFLAGS = -fPIC diff --git a/lib/resp.c b/lib/resp.c new file mode 100644 index 0000000..1271d2c --- /dev/null +++ b/lib/resp.c @@ -0,0 +1,82 @@ +/* + ashd - A Sane HTTP Daemon + Copyright (C) 2008 Fredrik Tolf + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include + +char *htmlquote(char *text) +{ + struct charbuf buf; + + bufinit(buf); + for(; *text; text++) { + if(*text == '<') + bufcatstr(buf, "<"); + else if(*text == '>') + bufcatstr(buf, ">"); + else if(*text == '&') + bufcatstr(buf, "&"); + else + bufadd(buf, *text); + } + bufadd(buf, 0); + return(buf.b); +} + +void simpleerror(int fd, int code, char *msg, char *fmt, ...) +{ + struct charbuf buf; + char *tmp1, *tmp2; + va_list args; + FILE *out; + + va_start(args, fmt); + tmp1 = vsprintf2(fmt, args); + va_end(args); + tmp2 = htmlquote(tmp1); + free(tmp1); + bufinit(buf); + bufcatstr(buf, "\r\n"); + bufcatstr(buf, "\r\n"); + bufcatstr(buf, "\r\n"); + bufcatstr(buf, "\r\n"); + bprintf(&buf, "%s\r\n", msg); + bufcatstr(buf, "\r\n"); + bufcatstr(buf, "\r\n"); + bprintf(&buf, "

%s

\r\n", msg); + bprintf(&buf, "

%s

\r\n", tmp2); + bufcatstr(buf, "\r\n"); + bufcatstr(buf, "\r\n"); + free(tmp2); + out = fdopen(fd, "w"); + fprintf(out, "HTTP/1.1 %i %s\r\n", code, msg); + fprintf(out, "Content-Type: text/html\r\n"); + fprintf(out, "Content-Length: %i\r\n", buf.d); + fprintf(out, "\r\n"); + fwrite(buf.b, 1, buf.d, out); + fclose(out); + buffree(buf); +} diff --git a/lib/resp.h b/lib/resp.h new file mode 100644 index 0000000..a1f01f3 --- /dev/null +++ b/lib/resp.h @@ -0,0 +1,6 @@ +#ifndef _LIB_HTRESP_H +#define _LIB_HTRESP_H + +void simpleerror(int fd, int code, char *msg, char *fmt, ...); + +#endif diff --git a/lib/utils.c b/lib/utils.c index e0dc22c..2734410 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -175,3 +175,29 @@ int calen(char **a) for(i = 0; *a; a++, i++); return(i); } + +void bvprintf(struct charbuf *buf, char *format, va_list al) +{ + va_list al2; + int ret; + + while(1) { + va_copy(al2, al); + ret = vsnprintf(buf->b + buf->d, buf->s - buf->d, format, al2); + va_end(al2); + if(ret < buf->s - buf->d) { + buf->d += ret; + return; + } + sizebuf(*buf, buf->d + ret + 1); + } +} + +void bprintf(struct charbuf *buf, char *format, ...) +{ + va_list args; + + va_start(args, format); + bvprintf(buf, format, args); + va_end(args); +} diff --git a/lib/utils.h b/lib/utils.h index e359d6c..78241b3 100644 --- a/lib/utils.h +++ b/lib/utils.h @@ -68,5 +68,7 @@ off_t atoo(char *n); char **tokenize(char *src); void freeca(char **ca); int calen(char **a); +void bvprintf(struct charbuf *buf, char *format, va_list al); +void bprintf(struct charbuf *buf, char *format, ...); #endif diff --git a/src/dirplex.c b/src/dirplex.c index 45d8a11..ef001cf 100644 --- a/src/dirplex.c +++ b/src/dirplex.c @@ -34,6 +34,7 @@ #include #include #include +#include #define CH_SOCKET 0 #define CH_FORK 1 @@ -453,8 +454,8 @@ static void handlefile(struct hthead *req, int fd, char *path) return; } if((ch = findchild(path, pat->childnm)) == NULL) { - /* XXX: Send a 500 error. */ flog(LOG_ERR, "child %s requested, but was not declared", pat->childnm); + simpleerror(fd, 500, "Configuration Error", "The server is erroneously configured. Handler %s was requested, but not declared.", pat->childnm); return; } @@ -467,6 +468,8 @@ static void handlefile(struct hthead *req, int fd, char *path) static void handledir(struct hthead *req, int fd, char *path) { + /* XXX: Todo */ + simpleerror(fd, 403, "Not Authorized", "Will not send directory listings or indices yet"); } static int checkdir(struct hthead *req, int fd, char *path) @@ -494,15 +497,19 @@ static void serve(struct hthead *req, int fd) if(p2 == NULL) { if(stat(path, &sb)) { flog(LOG_WARNING, "failed to stat previously stated directory %s: %s", path, strerror(errno)); + simpleerror(fd, 500, "Internal Server Error", "The server encountered an unexpected condition."); goto fail; } break; } else { + simpleerror(fd, 404, "Not Found", "The requested URL has no corresponding resource."); goto fail; } } - if(*p == '.') + if(*p == '.') { + simpleerror(fd, 404, "Not Found", "The requested URL has no corresponding resource."); goto fail; + } getconfig(path); @@ -528,6 +535,7 @@ static void serve(struct hthead *req, int fd) free(tmp); break; } + simpleerror(fd, 404, "Not Found", "The requested URL has no corresponding resource."); goto fail; } @@ -555,6 +563,7 @@ static void serve(struct hthead *req, int fd) break; } + simpleerror(fd, 404, "Not Found", "The requested URL has no corresponding resource."); goto fail; next: @@ -573,12 +582,13 @@ static void serve(struct hthead *req, int fd) } else if(S_ISREG(sb.st_mode)) { handlefile(req, fd, path); } else { + simpleerror(fd, 404, "Not Found", "The requested URL has no corresponding resource."); goto fail; } goto out; fail: - /* XXX: Send error report. */ + /* No special handling, for now at least. */ out: free(path); } -- 2.11.0