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: