about summary refs log tree commit diff
path: root/scooper.c
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2020-07-09 14:42:40 -0400
committerJune McEnroe <june@causal.agency>2020-07-09 14:42:40 -0400
commite716cd8032b9679641cb283e73542848453e24ae (patch)
tree3c49e0b12a1817185ece5128f37424388adc55f1 /scooper.c
parentImplement empty CGI/FastCGI server (diff)
downloadscooper-e716cd8032b9679641cb283e73542848453e24ae.tar.gz
scooper-e716cd8032b9679641cb283e73542848453e24ae.zip
Return basic 404 and 405
Diffstat (limited to 'scooper.c')
-rw-r--r--scooper.c38
1 files changed, 29 insertions, 9 deletions
diff --git a/scooper.c b/scooper.c
index 130ea15..291abb0 100644
--- a/scooper.c
+++ b/scooper.c
@@ -58,10 +58,10 @@ static const char *Pages[PagesLen] = {
 };
 
 #define ENUM_KEYS \
-	X(Network, "network", kvalid_string) \
-	X(Context, "context", kvalid_string) \
-	X(After, "after", kvalid_string) \
-	X(Query, "query", kvalid_string)
+	X(Network, "network", kvalid_stringne) \
+	X(Context, "context", kvalid_stringne) \
+	X(After, "after", kvalid_stringne) \
+	X(Query, "query", kvalid_stringne)
 
 enum {
 #define X(key, name, valid) key,
@@ -76,7 +76,25 @@ static const struct kvalid Keys[KeysLen] = {
 #undef X
 };
 
-static void request(struct kreq *req) {
+static enum kcgi_err fail(struct kreq *req, enum khttp status) {
+	return khttp_head(req, kresps[KRESP_STATUS], "%s", khttps[status])
+		|| khttp_head(
+			req, kresps[KRESP_CONTENT_TYPE], "%s", kmimetypes[KMIME_TEXT_PLAIN]
+		)
+		|| khttp_body(req)
+		|| khttp_puts(req, khttps[status])
+		|| khttp_putc(req, '\n');
+}
+
+static enum kcgi_err request(struct kreq *req) {
+	if (req->method != KMETHOD_HEAD && req->method != KMETHOD_GET) {
+		return fail(req, KHTTP_405);
+	}
+	if (req->mime != KMIME_TEXT_HTML || req->page == PagesLen) {
+		return fail(req, KHTTP_404);
+	}
+
+	return KCGI_OK;
 }
 
 int main(int argc, char *argv[]) {
@@ -126,16 +144,18 @@ int main(int argc, char *argv[]) {
 			KCGI_OK == (error = khttp_fcgi_parse(fcgi, &req));
 			khttp_free(&req)
 		) {
-			request(&req);
+			error = request(&req);
+			if (error && error != KCGI_HUP) break;
 		}
-		errx(EX_DATAERR, "khttp_fcgi_parse: %s", kcgi_strerror(error));
+		errx(EX_PROTOCOL, "khttp_fcgi_parse: %s", kcgi_strerror(error));
 	} else {
 		struct kreq req;
 		enum kcgi_err error = khttp_parse(
 			&req, Keys, KeysLen, Pages, PagesLen, Networks
 		);
-		if (error) errx(EX_DATAERR, "khttp_parse: %s", kcgi_strerror(error));
-		request(&req);
+		if (error) errx(EX_PROTOCOL, "khttp_parse: %s", kcgi_strerror(error));
+		error = request(&req);
+		if (error) errx(EX_PROTOCOL, "%s", kcgi_strerror(error));
 		khttp_free(&req);
 	}
 }