[hackers] [quark] Use enum for HTTP stati and improve data structures || FRIGN

From: <git_AT_suckless.org>
Date: Sun, 4 Sep 2016 23:58:57 +0200 (CEST)

commit 6996e702e84770d2963961e703eea9be5a461126
Author: FRIGN <dev_AT_frign.de>
AuthorDate: Sun Sep 4 23:58:20 2016 +0200
Commit: FRIGN <dev_AT_frign.de>
CommitDate: Sun Sep 4 23:58:20 2016 +0200

    Use enum for HTTP stati and improve data structures

diff --git a/quark.c b/quark.c
index 9d22df1..b42bba6 100644
--- a/quark.c
+++ b/quark.c
_AT_@ -30,18 +30,32 @@ char *argv0;
 
 #include "config.h"
 
-static char *status[] = {
- [200] = "OK",
- [206] = "Partial Content",
- [301] = "Moved Permanently",
- [400] = "Bad Request",
- [403] = "Forbidden",
- [404] = "Not Found",
- [405] = "Method Not Allowed",
- [408] = "Request Time-out",
- [431] = "Request Header Fields Too Large",
- [500] = "Internal Server Error",
- [505] = "HTTP Version not supported",
+enum stati {
+ S_OK = 200,
+ S_PARTIAL_CONTENT = 206,
+ S_MOVED_PERMANENTLY = 301,
+ S_BAD_REQUEST = 400,
+ S_FORBIDDEN = 403,
+ S_NOT_FOUND = 404,
+ S_METHOD_NOT_ALLOWED = 405,
+ S_REQUEST_TIMEOUT = 408,
+ S_REQUEST_TOO_LARGE = 431,
+ S_INTERNAL_SERVER_ERROR = 500,
+ S_VERSION_NOT_SUPPORTED = 505,
+};
+
+static char *statistr[] = {
+ [S_OK] = "OK",
+ [S_PARTIAL_CONTENT] = "Partial Content",
+ [S_MOVED_PERMANENTLY] = "Moved Permanently",
+ [S_BAD_REQUEST] = "Bad Request",
+ [S_FORBIDDEN] = "Forbidden",
+ [S_NOT_FOUND] = "Not Found",
+ [S_METHOD_NOT_ALLOWED] = "Method Not Allowed",
+ [S_REQUEST_TIMEOUT] = "Request Time-out",
+ [S_REQUEST_TOO_LARGE] = "Request Header Fields Too Large",
+ [S_INTERNAL_SERVER_ERROR] = "Internal Server Error",
+ [S_VERSION_NOT_SUPPORTED] = "HTTP Version not supported",
 
 };
 
_AT_@ -61,7 +75,7 @@ timestamp(time_t t)
 }
 
 static int
-sendstatus(int code, int fd, ...)
+sendstatus(enum stati code, int fd, ...)
 {
         va_list ap;
         char buf[4096];
_AT_@ -70,13 +84,13 @@ sendstatus(int code, int fd, ...)
         long lower, upper, size;
 
         buflen = snprintf(buf, 4096, "HTTP/1.1 %d %s\r\n", code,
- status[code]);
+ statistr[code]);
 
         buflen += snprintf(buf + buflen, 4096 - buflen, "Date: %s\r\n",
                            timestamp(0));
         va_start(ap, fd);
         switch (code) {
- case 200: /* arg-list: mime, size */
+ case S_OK: /* arg-list: mime, size */
                 buflen += snprintf(buf + buflen, 4096 - buflen,
                                    "Content-Type: %s\r\n",
                                    va_arg(ap, char *));
_AT_@ -86,7 +100,7 @@ sendstatus(int code, int fd, ...)
                                            size);
                 }
                 break;
- case 206: /* arg-list: mime, lower, upper, size */
+ case S_PARTIAL_CONTENT: /* arg-list: mime, lower, upper, size */
                 buflen += snprintf(buf + buflen, 4096 - buflen,
                                    "Content-Type: %s\r\n",
                                    va_arg(ap, char *));
_AT_@ -100,7 +114,7 @@ sendstatus(int code, int fd, ...)
                                    "Content-Length: %ld\r\n",
                                    (upper - lower) + 1);
                 break;
- case 301: /* arg-list: host, url */
+ case S_MOVED_PERMANENTLY: /* arg-list: host, url */
                 if (!strcmp(port, "80")) {
                         buflen += snprintf(buf + buflen, 4096 - buflen,
                                            "Location: http://%s%s\r\n",
_AT_@ -113,32 +127,34 @@ sendstatus(int code, int fd, ...)
                                            va_arg(ap, char *));
                 }
                 break;
- case 405: /* arg-list: none */
+ case S_METHOD_NOT_ALLOWED: /* arg-list: none */
                 buflen += snprintf(buf + buflen, 4096 - buflen,
                                    "Allow: GET\r\n");
                 break;
+ default:
+ break;
         }
         va_end(ap);
 
         buflen += snprintf(buf + buflen, 4096 - buflen,
                            "Connection: close\r\n");
 
- if (code != 200 && code != 206) {
+ if (code != S_OK && code != S_PARTIAL_CONTENT) {
                 buflen += snprintf(buf + buflen, 4096 - buflen,
                                    "Content-Type: text/html\r\n");
                 buflen += snprintf(buf + buflen, 4096 - buflen,
                                    "\r\n<!DOCTYPE html>\r\n<html>\r\n"
                                    "\t<head><title>%d %s</title></head>"
                                    "\r\n\t<body><h1>%d %s</h1></body>\r\n"
- "</html>\r\n", code, status[code],
- code, status[code]);
+ "</html>\r\n", code, statistr[code],
+ code, statistr[code]);
         } else {
                 buflen += snprintf(buf + buflen, 4096 - buflen, "\r\n");
         }
 
         for (written = 0; buflen > 0; written += ret, buflen -= ret) {
                 if ((ret = write(fd, buf + written, buflen)) < 0) {
- code = 408;
+ code = S_REQUEST_TIMEOUT;
                         break;
                 }
         }
_AT_@ -197,9 +213,9 @@ listdir(char *dir, int fd)
         int dirlen, ret, i;
 
         if ((dirlen = scandir(dir, &e, NULL, alphasort)) < 0) {
- return sendstatus(403, fd);
+ return sendstatus(S_FORBIDDEN, fd);
         }
- if ((ret = sendstatus(200, fd, "text/html", (long)-1)) != 200) {
+ if ((ret = sendstatus(S_OK, fd, "text/html", (long)-1)) != S_OK) {
                 return ret;
         }
         if ((buflen = snprintf(buf, sizeof(buf), "<!DOCTYPE html>\r\n"
_AT_@ -207,12 +223,12 @@ listdir(char *dir, int fd)
                                "</title></head>\r\n<body>\r\n"
                                "<a href=\"..\">..</a><br />\r\n",
                                dir)) >= sizeof(buf)) {
- return 500;
+ return S_INTERNAL_SERVER_ERROR;
         }
         written = 0;
         while (buflen > 0) {
                 if ((bread = write(fd, buf + written, buflen)) < 0) {
- return 408;
+ return S_REQUEST_TIMEOUT;
                 }
                 written += bread;
                 buflen -= bread;
_AT_@ -225,12 +241,12 @@ listdir(char *dir, int fd)
                 if ((buflen = snprintf(buf, sizeof(buf), "<a href=\"%s"
                                        "\">%s</a><br />\r\n", e[i]->d_name,
                                        e[i]->d_name)) >= sizeof(buf)) {
- return 500;
+ return S_INTERNAL_SERVER_ERROR;
                 }
                 written = 0;
                 while (buflen > 0) {
                         if ((bread = write(fd, buf + written, buflen)) < 0) {
- return 408;
+ return S_REQUEST_TIMEOUT;
                         }
                         written += bread;
                         buflen -= bread;
_AT_@ -239,18 +255,18 @@ listdir(char *dir, int fd)
 
         if ((buflen = snprintf(buf, sizeof(buf), "\r\n</body></html>\r\n"))
>= sizeof(buf)) {
- return 500;
+ return S_INTERNAL_SERVER_ERROR;
         }
         written = 0;
         while (buflen > 0) {
                 if ((bread = write(fd, buf + written, buflen)) < 0) {
- return 408;
+ return S_REQUEST_TIMEOUT;
                 }
                 written += bread;
                 buflen -= bread;
         }
 
- return 200;
+ return S_OK;
 }
 
 static int
_AT_@ -271,7 +287,7 @@ handle(int infd, char **url)
         /* get request header */
         for (reqlen = 0; ;) {
                 if ((off = read(infd, req + reqlen, MAXREQLEN - reqlen)) < 0) {
- return sendstatus(408, infd);
+ return sendstatus(S_REQUEST_TIMEOUT, infd);
                 } else if (off == 0) {
                         break;
                 }
_AT_@ -280,49 +296,49 @@ handle(int infd, char **url)
                         break;
                 }
                 if (reqlen == MAXREQLEN) {
- return sendstatus(431, infd);
+ return sendstatus(S_REQUEST_TOO_LARGE, infd);
                 }
         }
         if (reqlen < 2) {
- return sendstatus(400, infd);
+ return sendstatus(S_BAD_REQUEST, infd);
         }
         reqlen -= 2; /* remove last \r\n */
         req[reqlen] = '\0'; /* make it safe */
 
         /* parse request line */
         if (reqlen < 3) {
- return sendstatus(400, infd);
+ return sendstatus(S_BAD_REQUEST, infd);
         } else if (strncmp(req, "GET", sizeof("GET") - 1)) {
- return sendstatus(405, infd);
+ return sendstatus(S_METHOD_NOT_ALLOWED, infd);
         } else if (req[3] != ' ') {
- return sendstatus(400, infd);
+ return sendstatus(S_BAD_REQUEST, infd);
         }
         for (p = req + sizeof("GET ") - 1; *p && *p != ' '; p++)
                 ;
         if (!*p) {
- return sendstatus(400, infd);
+ return sendstatus(S_BAD_REQUEST, infd);
         }
         *p = '\0';
         if (snprintf(urlenc, sizeof(urlenc), "%s",
             req + sizeof("GET ") - 1) >= sizeof(urlenc)) {
- return sendstatus(400, infd);
+ return sendstatus(S_BAD_REQUEST, infd);
         }
         *url = urldecnorm;
         if (!strlen(urlenc)) {
- return sendstatus(400, infd);
+ return sendstatus(S_BAD_REQUEST, infd);
         }
         p += sizeof(" ") - 1;
         if (strncmp(p, "HTTP/", sizeof("HTTP/") - 1)) {
- return sendstatus(400, infd);
+ return sendstatus(S_BAD_REQUEST, infd);
         }
         p += sizeof("HTTP/") - 1;
         if (strncmp(p, "1.0", sizeof("1.0") - 1) &&
             strncmp(p, "1.1", sizeof("1.1") - 1)) {
- return sendstatus(505, infd);
+ return sendstatus(S_VERSION_NOT_SUPPORTED, infd);
         }
         p += sizeof("1.*") - 1;
         if (strncmp(p, "\r\n", sizeof("\r\n") - 1)) {
- return sendstatus(400, infd);
+ return sendstatus(S_BAD_REQUEST, infd);
         }
         p += sizeof("\r\n") - 1;
 
_AT_@ -336,7 +352,8 @@ handle(int infd, char **url)
                         }
                         if (snprintf(reqhost, sizeof(reqhost), "%s", p) >=
                             sizeof(reqhost)) {
- return sendstatus(500, infd);
+ return sendstatus(S_INTERNAL_SERVER_ERROR,
+ infd);
                         }
                 } else if (!strncmp(p, "Range:", sizeof("Range:") - 1)) {
                         p += sizeof("Range:") - 1;
_AT_@ -345,7 +362,8 @@ handle(int infd, char **url)
                         }
                         if (snprintf(range, sizeof(range), "%s", p) >=
                             sizeof(range)) {
- return sendstatus(500, infd);
+ return sendstatus(S_INTERNAL_SERVER_ERROR,
+ infd);
                         }
                 } else if (!strncmp(p, "If-Modified-Since:",
                            sizeof("If-Modified-Since:") - 1)) {
_AT_@ -355,7 +373,8 @@ handle(int infd, char **url)
                         }
                         if (snprintf(modsince, sizeof(modsince), "%s", p) >=
                             sizeof(modsince)) {
- return sendstatus(500, infd);
+ return sendstatus(S_INTERNAL_SERVER_ERROR,
+ infd);
                         }
                 }
         }
_AT_@ -365,17 +384,18 @@ handle(int infd, char **url)
         decode(urlenc, urldec);
         if (!realpath(urldec, urldecnorm)) {
                 /* todo: break up the cases */
- return sendstatus((errno == EACCES) ? 403 : 404, infd);
+ return sendstatus((errno == EACCES) ? S_FORBIDDEN :
+ S_NOT_FOUND, infd);
         }
 
         /* hidden path? */
         if (urldecnorm[0] == '.' || strstr(urldecnorm, "/.")) {
- return sendstatus(403, infd);
+ return sendstatus(S_FORBIDDEN, infd);
         }
         /* check if file or directory */
         if (stat(urldecnorm, &st) < 0) {
                 /* todo: break up the cases */
- return sendstatus(404, infd);
+ return sendstatus(S_NOT_FOUND, infd);
         }
         if (S_ISDIR(st.st_mode)) {
                 /* add / at the end, was removed by realpath */
_AT_@ -394,12 +414,12 @@ handle(int infd, char **url)
                         if (snprintf(urldecnormind, sizeof(urldecnormind),
                                      "%s/%s", urldecnorm, docindex) >=
                                      sizeof(urldecnorm)) {
- return sendstatus(400, infd);
+ return sendstatus(S_BAD_REQUEST, infd);
                         }
                         if (stat(urldecnormind, &st) < 0) {
                                 /* no index, serve dir */
                                 if (!listdirs) {
- return sendstatus(403, infd);
+ return sendstatus(S_FORBIDDEN, infd);
                                 }
                                 return listdir(urldecnorm, infd);
                         }
_AT_@ -410,7 +430,7 @@ handle(int infd, char **url)
         }
         if (needredirect) {
                 encode(urldecnorm, urlenc);
- return sendstatus(301, infd, urlenc,
+ return sendstatus(S_MOVED_PERMANENTLY, infd, urlenc,
                                   reqhost[0] ? reqhost : host);
         }
 
_AT_@ -419,11 +439,11 @@ handle(int infd, char **url)
         upper = LONG_MAX;
         if (range[0]) {
                 if (strncmp(range, "bytes=", sizeof("bytes=") - 1)) {
- return sendstatus(400, infd);
+ return sendstatus(S_BAD_REQUEST, infd);
                 }
                 p = range + sizeof("bytes=") - 1;
                 if (!(q = strchr(p, '-'))) {
- return sendstatus(400, infd);
+ return sendstatus(S_BAD_REQUEST, infd);
                 }
                 *(q++) = '\0';
                 if (p[0]) {
_AT_@ -436,7 +456,7 @@ handle(int infd, char **url)
 
         /* serve file */
         if (!(fp = fopen(urldecnorm, "r"))) {
- return sendstatus(403, infd);
+ return sendstatus(S_FORBIDDEN, infd);
         }
         mime = "text/plain";
         if ((p = strrchr(urldecnorm, '.'))) {
_AT_@ -448,22 +468,22 @@ handle(int infd, char **url)
                 }
         }
         if (fseek(fp, 0, SEEK_END) || (fsize = ftell(fp)) < 0) {
- return sendstatus(500, infd);
+ return sendstatus(S_INTERNAL_SERVER_ERROR, infd);
         }
         rewind(fp);
         if (fsize && upper > fsize) {
                 upper = fsize - 1;
         }
         if (fseek(fp, lower, SEEK_SET)) {
- return sendstatus(500, infd);
+ return sendstatus(S_INTERNAL_SERVER_ERROR, infd);
         }
         if (!range[0]) {
- if ((ret = sendstatus(200, infd, mime, (long)fsize)) != 200) {
+ if ((ret = sendstatus(S_OK, infd, mime, (long)fsize)) != S_OK) {
                         return ret;
                 }
         } else {
- if ((ret = sendstatus(206, infd, mime, lower,
- upper, fsize)) != 206) {
+ if ((ret = sendstatus(S_PARTIAL_CONTENT, infd, mime, lower,
+ upper, fsize)) != S_PARTIAL_CONTENT) {
                         return ret;
                 }
         }
_AT_@ -472,20 +492,20 @@ handle(int infd, char **url)
                              fp))) {
                 remaining -= buflen;
                 if (buflen < 0) {
- return 500;
+ return S_INTERNAL_SERVER_ERROR;
                 }
                 p = buf;
                 while (buflen > 0) {
                         written = write(infd, p, buflen);
                         if (written <= 0) {
- return 408;
+ return S_REQUEST_TIMEOUT;
                         }
                         buflen -= written;
                         p += written;
                 }
         }
 
- return 200;
+ return S_OK;
 }
 
 static void
_AT_@ -496,11 +516,13 @@ serve(int insock)
         pid_t p;
         socklen_t in_sa_len;
         time_t t;
- int infd, status;
+ enum stati status;
+ int infd;
         char inip4[INET_ADDRSTRLEN], inip6[INET6_ADDRSTRLEN], *url = "",
              tstmp[25];
 
         while (1) {
+ /* accept incoming connections */
                 in_sa_len = sizeof(in_sa);
                 if ((infd = accept(insock, (struct sockaddr *)&in_sa,
                                    &in_sa_len)) < 0) {
_AT_@ -517,7 +539,7 @@ serve(int insock)
                 case 0:
                         close(insock);
 
- /* timeouts */
+ /* set connection timeout */
                         tv.tv_sec = 30;
                         tv.tv_usec = 0;
                         if (setsockopt(infd, SOL_SOCKET, SO_RCVTIMEO, &tv,
_AT_@ -531,7 +553,7 @@ serve(int insock)
 
                         status = handle(infd, &url);
 
- /* log */
+ /* write output to log */
                         t = time(NULL);
                         strftime(tstmp, sizeof(tstmp), "%Y-%m-%dT%H:%M:%S",
                                  gmtime(&t));
_AT_@ -548,10 +570,11 @@ serve(int insock)
                                 printf("%s\t%s\t%d\t%s\n", tstmp, inip6, status, url);
                         }
 
+ /* clean up and finish */
                         shutdown(infd, SHUT_RD);
                         shutdown(infd, SHUT_WR);
                         close(infd);
- _exit(EXIT_SUCCESS);
+ _exit(0);
                 default:
                         close(infd);
                 }
Received on Sun Sep 04 2016 - 23:58:57 CEST

This archive was generated by hypermail 2.3.0 : Mon Sep 05 2016 - 00:00:40 CEST