summaryrefslogtreecommitdiff
path: root/src/cmd/httpd/httpd.c
diff options
context:
space:
mode:
authordzwdz2023-08-14 18:51:07 +0200
committerdzwdz2023-08-14 18:51:07 +0200
commit642b5fb0007b64c77d186fcb018d571152ee1d47 (patch)
tree1c466461f3602d306be309a053edae558ef2568e /src/cmd/httpd/httpd.c
parent8050069c57b729c18c19b1a03ab6e4bf63b4735e (diff)
reorganization: first steps
Diffstat (limited to 'src/cmd/httpd/httpd.c')
-rw-r--r--src/cmd/httpd/httpd.c77
1 files changed, 77 insertions, 0 deletions
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 <camellia/flags.h>
+#include <camellia/syscalls.h>
+#include <err.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+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, "<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;
+ }
+ }
+ }
+ 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);
+ }
+}