shithub: tcp80

Download patch

ref: 4fe69df34fd70c42b380bcd50b0cd425c60122d0
parent: 8ea5ce6871290c67f3d44bf94b7bf3ec35a15200
author: grobe0ba <grobe0ba@tcp80.org>
date: Mon Aug 1 16:10:12 EDT 2022

clean up status response

--- a/tcp80.c
+++ b/tcp80.c
@@ -7,6 +7,7 @@
 
 typedef struct Pair Pair;
 typedef struct Ctype Ctype;
+typedef struct HResponse HResponse;
 
 struct Pair {
 	Pair *next;
@@ -112,6 +113,71 @@
     ".7z",     "application/x-7z-compressed",
 };
 
+struct HResponse {
+	int code;
+	const char *message;
+};
+
+// RFC 2616 responses
+HResponse responsemap[] = {
+    100, "Continue",
+    101, "Switching Protocols",
+    200, "OK",
+    201, "Created",
+    202, "Accepted",
+    203, "Non-Authoritative Information",
+    204, "No Content",
+    205, "Reset Content",
+    206, "Partial Content",
+    300, "Multiple Choices",
+    301, "Moved Permanently",
+    302, "Found",
+    303, "See Other",
+    304, "Not Modified",
+    305, "Use Proxy",
+    307, "Temporary Request",
+    400, "Bad Request",
+    401, "Unauthorized",
+    402, "Payment Required",
+    403, "Forbidden",
+    404, "Not Found",
+    405, "Method Not Allowed",
+    406, "Not Acceptable",
+    407, "Proxy Authentication Required",
+    408, "Request Time-out",
+    409, "Conflict",
+    410, "Gone",
+    411, "Length Required",
+    412, "Precondition Failed",
+    413, "Request Entity Too Large",
+    414, "Request-URI Too Large",
+    415, "Unsupported Media Type",
+    416, "Requested range not satisfiable",
+    417, "Expectation Failed",
+    500, "Internal Server Error",
+    501, "Not Implemented",
+    502, "Bad Gateway",
+    503, "Service Unavailable",
+    504, "Gateway Time-out",
+    505, "HTTP Version not supported",
+};
+
+void
+getresponse(char *dst, int bufsz, int code)
+{
+	int i;
+
+	for(i = 0; i < nelem(responsemap); i++){
+		if(responsemap[i].code == code){
+			seprint(dst, dst + bufsz, "%d %s", responsemap[i].code,
+				responsemap[i].message);
+			return;
+		}
+	}
+
+	getresponse(dst, bufsz, 500);
+}
+
 char *
 findrule(char *rulesfile, char *path)
 {
@@ -399,20 +465,20 @@
 }
 
 int
-redirerr(char *status, int istatus, Dir *d)
+redirerr(int status, Dir *d)
 {
-	static char buf[8192], tmp[1024];
+	static char buf[8192], tmp[1024], statbuf[32];
 	char *p, *s;
 	int i;
 	Pair *h;
 
 	for(i = 0; i < nelem(redir_errno); i++){
-		if(istatus == redir_errno[i]){
-			status = "301 Moved Permanently";
-			respond(status);
+		if(status == redir_errno[i]){
+			getresponse(statbuf, 32, 301);
+			respond(statbuf);
 			headers(buf, d);
 
-			snprint(buf, sizeof(buf), "/%d%s", istatus, location);
+			snprint(buf, sizeof(buf), "/%d%s", status, location);
 
 			h = findhdr(nil, "Host");
 			p = strchr(location, '?');
@@ -428,10 +494,10 @@
 int
 dispatch(void)
 {
-	static char buf[8192], tmp[1024];
-	char *p, *s, *status;
+	static char buf[8192], tmp[1024], statbuf[32];
+	char *p, *s;
 	int i, n, fd, badmeth, nobody, noindex, noslash;
-	int istatus = 0;
+	int status = 0;
 	Pair *h;
 	Dir *d;
 
@@ -439,19 +505,19 @@
 	badmeth = !nobody && cistrcmp(method, "GET");
 	if(badmeth){
 		werrstr("%s method unsupported", method);
-		istatus = 405;
-		status	= "405 Method Not Allowed";
+		status = 405;
 	Error:
-		if(redirerr(status, istatus, d))
+		if(redirerr(status, d))
 			goto Out;
+		getresponse(statbuf, 32, status);
 		if(!nobody)
 			n = snprint(buf, sizeof(buf),
 				    "<html><head><title>%s</title></head>\n"
 				    "<body><h1>%s</h1><pre>%r</pre></body></html>\n",
-				    status, status);
+				    statbuf, statbuf);
 		else
 			n = 0;
-		respond(status);
+		respond(statbuf);
 		headers(".html", nil);
 		print("Content-Length: %d\r\n\r\n%*s", n, n, buf);
 		return -badmeth;
@@ -485,19 +551,16 @@
 	if((fd = open(buf, OREAD)) < 0){
 		rerrstr(buf, sizeof(buf));
 		if(strstr(buf, "permission denied")){
-			istatus = 403;
-			status	= "403 Forbidden";
+			status = 403;
 			goto Error;
 		}
-		istatus = 404;
-		status	= "404 Not found";
+		status = 404;
 		goto Error;
 	}
 
 	if((d = dirfstat(fd)) == nil){
 		close(fd);
-		istatus = 500;
-		status	= "500 Internal Server Error";
+		status = 500;
 		goto Error;
 	}
 
@@ -506,8 +569,8 @@
 		Dir *d2;
 
 		if(noslash){
-			status = "301 Moved Permanently";
-			respond(status);
+			getresponse(statbuf, 32, 301);
+			respond(statbuf);
 			headers(buf, d);
 
 			h = findhdr(nil, "Host");
@@ -519,7 +582,7 @@
 					    "<html><head><title>%s</title></head>\n"
 					    "<body><h1>%s</h1><pre>Moved to <a "
 					    "href=\"%s\">%s</a></pre></body></html>\n",
-					    status, status, s, s);
+					    statbuf, statbuf, s, s);
 			else
 				n = 0;
 			print("Location: %s\r\nContent-Length: %d\r\n\r\n%*s", s, n, n, buf);
@@ -545,7 +608,8 @@
 			}
 		}
 
-		respond("200 OK");
+		getresponse(statbuf, 32, 200);
+		respond(statbuf);
 		headers(buf, d);
 		print("\r\n");
 		if(nobody)
@@ -589,7 +653,8 @@
 
 			if((t = hdate(h->val)) != -1){
 				if(d->mtime <= t){
-					respond("304 Not Modified");
+					getresponse(statbuf, 32, 304);
+					respond(statbuf);
 					headers(buf, d);
 					print("\r\n");
 					goto Out;
@@ -614,13 +679,15 @@
 				end = strtoll(s, &s, 10) + 1;
 			if(*s != 0 || (end <= start))
 				break;
-			respond("206 Partial content");
+			getresponse(statbuf, 32, 206);
+			respond(statbuf);
 			print("Content-Range: bytes %lld-%lld/%lld\r\n", start, end - 1, d->length);
 			goto Content;
 		}
 		start = 0;
 		end   = d->length;
-		respond("200 OK");
+		getresponse(statbuf, 32, 200);
+		respond(statbuf);
 	Content:
 		headers(buf, d);
 		if(end > start){
@@ -748,7 +815,7 @@
 void
 main(int argc, char **argv)
 {
-	static char buf[1024], line[1024];
+	static char buf[1024], line[1024], statbuf[32];
 	Pair *host;
 	char *hosts;
 	char *r, *c;
@@ -783,7 +850,8 @@
 	if(remote[0] == 0)
 		strcpy(remote, "-");
 	if(parsequery() < 0){
-		respond("400 Bad Request");
+		getresponse(statbuf, 32, 400);
+		respond(statbuf);
 		return;
 	}
 
@@ -816,9 +884,10 @@
 			fakedir.gid  = "none";
 			fakedir.muid = "none";
 			if(cistrcmp(method, "GET") != 0)
-				if(redirerr("405 Method Not Allowed", 405, &fakedir))
+				if(redirerr(405, &fakedir))
 					goto rOut;
-			respond("200 OK");
+			getresponse(statbuf, 32, 200);
+			respond(statbuf);
 			headers(loc, &fakedir);
 			dispatchrule(c);
 		rOut: