From 642b5fb0007b64c77d186fcb018d571152ee1d47 Mon Sep 17 00:00:00 2001 From: dzwdz Date: Mon, 14 Aug 2023 18:51:07 +0200 Subject: reorganization: first steps --- src/cmd/httpd/httpd.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 src/cmd/httpd/httpd.c (limited to 'src/cmd/httpd/httpd.c') diff --git a/src/cmd/httpd/httpd.c b/src/cmd/httpd/httpd.c new file mode 100644 index 0000000..668e534 --- /dev/null +++ b/src/cmd/httpd/httpd.c @@ -0,0 +1,77 @@ +/* garbage httpd, just to see if it works + * easily DoSable (like the rest of the network stack), vulnerable to path traversal, etc */ +#include +#include +#include +#include +#include +#include + +static void handle(FILE *c) { + char buf[2048]; + fgets(buf, sizeof buf, c); + printf("%s", buf); + + if (memcmp(buf, "GET /", 5) != 0) { + fprintf(c, "HTTP/1.1 400 Bad Request\r\n\r\n"); + return; + } + char *path = buf + 4; + char *end = strchr(path, ' '); + if (end) *end = '\0'; + + hid_t h = _sys_open(path, strlen(path), OPEN_READ); + if (h < 0) { + fprintf(c, "HTTP/1.1 404 Not Found\r\n\r\n"); + return; + } + FILE *f = fdopen(h, "r"); + if (!f) { + fprintf(c, "HTTP/1.1 500 Internal Server Error\r\n\r\n"); + return; + } + + if (path[strlen(path) - 1] != '/') { + /* regular file */ + fprintf(c, "HTTP/1.1 200 OK\r\n"); + fprintf(c, "\r\n"); + for (;;) { + int len = fread(buf, 1, sizeof buf, f); + if (len <= 0) break; + fwrite(buf, 1, len, c); + } + } else { + /* directory listing */ + fprintf(c, "HTTP/1.1 200 OK\r\n"); + fprintf(c, "Content-Type: text/html; charset=UTF-8\r\n"); + fprintf(c, "\r\n"); + fprintf(c, "

directory listing for %s


  • ..
  • ", path); + for (;;) { + int len = fread(buf, 1, sizeof buf, f); + if (len <= 0) break; + // TODO directory library + // based on find.c + for (int pos = 0; pos < len; ) { + if (buf[pos] == '\0') break; + const char *end = memchr(buf + pos, 0, len - pos); + if (!end) break; + fprintf(c, "
  • %s
  • ", buf + pos, buf + pos); + pos += end - (buf + pos) + 1; + } + } + } + fclose(f); +} + +int main(int argc, char **argv) { + const char *path = (argc > 1) ? argv[1] : "/net/listen/0.0.0.0/tcp/80"; + hid_t conn; + for (;;) { + conn = _sys_open(path, strlen(path), OPEN_RW); + if (conn < 0) + errx(1, "open('%s') failed, errno %d", path, -conn); + FILE *f = fdopen(conn, "a+"); + handle(f); + fclose(f); + } +} -- cgit v1.2.3