diff options
author | dzwdz | 2023-09-02 17:45:35 +0200 |
---|---|---|
committer | dzwdz | 2023-09-02 17:45:35 +0200 |
commit | 48d6aa11451f6e4ee0c3716b1c4be3c11287dd3b (patch) | |
tree | 775219a4501957ed8bf52d76291817eb9dfa11ef /src/cmd/httpd | |
parent | fd7be968dd3bce84e31d62e1faecef9cf5ea14c1 (diff) |
libc: opendir_f; make httpd use it
Diffstat (limited to 'src/cmd/httpd')
-rw-r--r-- | src/cmd/httpd/httpd.c | 53 |
1 files changed, 29 insertions, 24 deletions
diff --git a/src/cmd/httpd/httpd.c b/src/cmd/httpd/httpd.c index 668e534..8826dcb 100644 --- a/src/cmd/httpd/httpd.c +++ b/src/cmd/httpd/httpd.c @@ -2,6 +2,7 @@ * easily DoSable (like the rest of the network stack), vulnerable to path traversal, etc */ #include <camellia/flags.h> #include <camellia/syscalls.h> +#include <dirent.h> #include <err.h> #include <stdio.h> #include <string.h> @@ -25,42 +26,46 @@ static void handle(FILE *c) { 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] != '/') { + FILE *f = fdopen(h, "r"); + if (!f) { + fprintf(c, "HTTP/1.1 500 Internal Server Error\r\n\r\n"); + return; + } + /* regular file */ - fprintf(c, "HTTP/1.1 200 OK\r\n"); - fprintf(c, "\r\n"); + fprintf(c, "HTTP/1.1 200 OK\r\n\r\n"); for (;;) { int len = fread(buf, 1, sizeof buf, f); if (len <= 0) break; fwrite(buf, 1, len, c); } + + fclose(f); } 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, "<h1>directory listing for %s</h1><hr><ul><li><a href=..>..</a></li>", 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, "<li><a href=\"%s\">%s</a></li>", buf + pos, buf + pos); - pos += end - (buf + pos) + 1; - } + DIR *dir = opendir_f(fdopen(h, "r")); + if (!dir) { + fprintf(c, "HTTP/1.1 500 Internal Server Error\r\n\r\n"); + return; + } + + fprintf(c, + "HTTP/1.1 200 OK\r\n" + "Content-Type: text/html; charset=UTF-8\r\n" + "\r\n" + "<h1>directory listing for %s</h1><hr>" + "<ul><li><a href=..>..</a></li>", + path + ); + + struct dirent *d; + while ((d = readdir(dir))) { + fprintf(c, "<li><a href=\"%s\">%s</a></li>", d->d_name, d->d_name); } + closedir(dir); } - fclose(f); } int main(int argc, char **argv) { |