summaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
authordzwdz2024-04-14 19:35:29 +0200
committerdzwdz2024-04-14 19:35:29 +0200
commit32d7e504169351ce6a5542b4f559c7e4d3834b45 (patch)
treee8d009c4a2336ac29394c5c824b2ba87f73399e2 /src/cmd
parent72f55421fb61b750512f324d284b30e3e67e36e0 (diff)
httpd: serve files out of /usr/www
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/httpd.c56
1 files changed, 44 insertions, 12 deletions
diff --git a/src/cmd/httpd.c b/src/cmd/httpd.c
index 8826dcb..2e0b6d0 100644
--- a/src/cmd/httpd.c
+++ b/src/cmd/httpd.c
@@ -1,41 +1,57 @@
/* garbage httpd, just to see if it works
* easily DoSable (like the rest of the network stack), vulnerable to path traversal, etc */
+#include <camellia.h>
#include <camellia/flags.h>
#include <camellia/syscalls.h>
#include <dirent.h>
#include <err.h>
+#include <getopt.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
+const char *sockpath = "/net/listen/0.0.0.0/tcp/80";
+const char *webroot = "/usr/www";
+size_t webrootl;
+
+static void status(FILE *c, const char *code) {
+ fprintf(c, "HTTP/1.1 %s\r\n\r\n", code);
+}
+
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");
+ status(c, "400 Bad Request");
return;
}
char *path = buf + 4;
char *end = strchr(path, ' ');
if (end) *end = '\0';
- hid_t h = _sys_open(path, strlen(path), OPEN_READ);
+ if (strlen(webroot) + strlen(path) + 1 <= sizeof(buf)) {
+ memmove(buf + strlen(webroot), path, strlen(path) + 1);
+ memcpy(buf, webroot, strlen(webroot));
+ }
+
+ hid_t h = camellia_open(buf, OPEN_READ);
+ printf("%s, %d\n", buf, h);
if (h < 0) {
- fprintf(c, "HTTP/1.1 404 Not Found\r\n\r\n");
+ status(c, "404 Not Found");
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");
+ status(c, "500 Internal Server Error");
return;
}
/* regular file */
- fprintf(c, "HTTP/1.1 200 OK\r\n\r\n");
+ status(c, "200 OK");
for (;;) {
int len = fread(buf, 1, sizeof buf, f);
if (len <= 0) break;
@@ -47,7 +63,7 @@ static void handle(FILE *c) {
/* directory listing */
DIR *dir = opendir_f(fdopen(h, "r"));
if (!dir) {
- fprintf(c, "HTTP/1.1 500 Internal Server Error\r\n\r\n");
+ status(c, "500 Internal Server Error");
return;
}
@@ -57,7 +73,7 @@ static void handle(FILE *c) {
"\r\n"
"<h1>directory listing for %s</h1><hr>"
"<ul><li><a href=..>..</a></li>",
- path
+ buf
);
struct dirent *d;
@@ -69,12 +85,28 @@ static void handle(FILE *c) {
}
int main(int argc, char **argv) {
- const char *path = (argc > 1) ? argv[1] : "/net/listen/0.0.0.0/tcp/80";
- hid_t conn;
+ int c;
+ optind = 0;
+
+ while ((c = getopt(argc, argv, "a:r:")) != -1) {
+ switch (c) {
+ case 'a':
+ sockpath = optarg;
+ break;
+ case 'r':
+ webroot = optarg;
+ break;
+ default:
+ fprintf(stderr, "usage: httpd [-a /net/listen/IP/tcp/PORT] [-r path]\n");
+ return 1;
+ }
+ }
+
for (;;) {
- conn = _sys_open(path, strlen(path), OPEN_RW);
- if (conn < 0)
- errx(1, "open('%s') failed, errno %d", path, -conn);
+ hid_t conn = camellia_open(sockpath, OPEN_RW);
+ if (conn < 0) {
+ errx(1, "open('%s') failed, errno %d", sockpath, -conn);
+ }
FILE *f = fdopen(conn, "a+");
handle(f);
fclose(f);