[hackers] [quark] added basic HEAD support, some bug fixes || Anselm R Garbe

From: <hg_AT_suckless.org>
Date: Sun, 28 Mar 2010 02:14:34 +0000 (UTC)

changeset: 10:a248f92acca2
user: Anselm R Garbe <anselm_AT_garbe.us>
date: Sun Mar 28 01:57:44 2010 +0000
files: config.def.h quark.c
description:
added basic HEAD support, some bug fixes

diff -r e6663aa4978c -r a248f92acca2 config.def.h
--- a/config.def.h Sun Mar 28 01:09:14 2010 +0000
+++ b/config.def.h Sun Mar 28 01:57:44 2010 +0000
@@ -6,7 +6,8 @@
 static const char docindex[] = "index.html";
 static const char user[] = "nobody";
 static const char group[] = "nobody";
-static const char cgi_script[] = "/var/www/werc-dev/bin/werc.rc";
+static const char cgi_dir[] = "/var/www/werc-dev/bin";
+static const char cgi_script[] = "./werc.rc";
 static const int cgi_mode = 0;
 
 static const MimeType servermimes[] = {
diff -r e6663aa4978c -r a248f92acca2 quark.c
--- a/quark.c Sun Mar 28 01:09:14 2010 +0000
+++ b/quark.c Sun Mar 28 01:57:44 2010 +0000
@@ -20,6 +20,11 @@
 #define LENGTH(x) (sizeof x / sizeof x[0])
 #define MAXREQLEN 255
 
+enum {
+ GET = 4,
+ HEAD = 5,
+};
+
 typedef struct {
         const char *extension;
         const char *mimetype;
@@ -31,7 +36,8 @@
 static const char HttpNotFound[] = "404 Not Found";
 static const char texthtml[] = "text/html";
 
-static ssize_t writedata(const char *buf);
+static ssize_t writetext(const char *buf);
+static ssize_t writedata(const char *buf, size_t buflen);
 static void die(const char *errstr, ...);
 static void response(void);
 static void responsecgi(void);
@@ -51,15 +57,14 @@
 static char name[128];
 static char reqbuf[MAXREQLEN+1];
 static char respbuf[1024];
-static int fd, cfd;
+static int fd, cfd, reqtype;
 
 ssize_t
-writedata(const char *buf) {
+writedata(const char *buf, size_t buf_len) {
         ssize_t r, offset = 0;
- size_t len = strlen(buf);
 
- while(offset < len) {
- if((r = write(cfd, buf + offset, len - offset)) == -1) {
+ while(offset < buf_len) {
+ if((r = write(cfd, buf + offset, buf_len - offset)) == -1) {
                         fprintf(stderr, "%s: client %s closed connection\n", tstamp(), name);
                         return -1;
                 }
@@ -68,6 +73,11 @@
         return offset;
 }
 
+ssize_t
+writetext(const char *buf) {
+ return writedata(buf, strlen(buf));
+}
+
 void
 logmsg(const char *errstr, ...) {
         va_list ap;
@@ -111,7 +121,7 @@
                 logerrmsg("snprintf failed, buffer size exceeded");
                 return -1;
         }
- return writedata(respbuf);
+ return writetext(respbuf);
 }
 
 int
@@ -123,7 +133,7 @@
                 logerrmsg("snprintf failed, buffer sizeof exceeded");
                 return -1;
         }
- return writedata(respbuf);
+ return writetext(respbuf);
 }
 
 int
@@ -135,7 +145,7 @@
                 logerrmsg("snprintf failed, buffer sizeof exceeded");
                 return -1;
         }
- return writedata(respbuf);
+ return writetext(respbuf);
 }
 
 int
@@ -147,7 +157,7 @@
                 logerrmsg("snprintf failed, buffer sizeof exceeded");
                 return -1;
         }
- return writedata(respbuf);
+ return writetext(respbuf);
 }
 
 void
@@ -172,8 +182,12 @@
         if((ffd = open(reqbuf, O_RDONLY)) == -1) {
                 fprintf(stderr, "%s: %s requests unknown path %s\n", tstamp(), name, reqbuf);
                 if(responsehdr(HttpNotFound) != -1
- && responsecontenttype(texthtml) != -1
- && writedata("\r\n<html><body>404 Not Found</body></html>\r\n") != -1);
+ && responsecontenttype(texthtml) != -1)
+ ;
+ else
+ return;
+ if(reqtype == GET)
+ writetext("\r\n<html><body>404 Not Found</body></html>\r\n");
         }
         else {
                 if((p = strrchr(reqbuf, '.'))) {
@@ -186,8 +200,11 @@
                 }
                 if(responsehdr(HttpOk) != -1
                 && responsecontentlen(st.st_size) != -1
- && responsecontenttype(mimetype) != -1
- && writedata("\r\n") != -1)
+ && responsecontenttype(mimetype) != -1)
+ ;
+ else
+ return;
+ if(reqtype == GET && writetext("\r\n") != -1)
                         responsefiledata(ffd, st.st_size);
                 close(ffd);
         }
@@ -198,23 +215,27 @@
         struct dirent *e;
 
         if(responsehdr(HttpOk) != -1
- && responsecontenttype(texthtml) != -1
- && writedata("\r\n<html><body><a href='..'>..</a><br>\r\n") != -1);
+ && responsecontenttype(texthtml) != -1)
+ ;
         else
                 return;
- while((e = readdir(d))) {
- if(e->d_name[0] == '.') /* ignore hidden files, ., .. */
- continue;
- if(snprintf(respbuf, sizeof respbuf, "<a href='%s%s'>%s</a><br>\r\n",
- reqbuf, e->d_name, e->d_name) >= sizeof respbuf)
- {
- logerrmsg("snprintf failed, buffer sizeof exceeded");
+ if(reqtype == GET) {
+ if(writetext("\r\n<html><body><a href='..'>..</a><br>\r\n") == -1)
                         return;
+ while((e = readdir(d))) {
+ if(e->d_name[0] == '.') /* ignore hidden files, ., .. */
+ continue;
+ if(snprintf(respbuf, sizeof respbuf, "<a href='%s%s'>%s</a><br>\r\n",
+ reqbuf, e->d_name, e->d_name) >= sizeof respbuf)
+ {
+ logerrmsg("snprintf failed, buffer sizeof exceeded");
+ return;
+ }
+ if(writetext(respbuf) == -1)
+ return;
                 }
- if(writedata(respbuf) == -1)
- return;
+ writetext("</body></html>\r\n");
         }
- writedata("</body></html>\r\n");
 }
 
 void
@@ -229,8 +250,12 @@
                 fprintf(stdout, "%s: redirecting %s to %s%s\n", tstamp(), name, location, reqbuf);
                 if(responsehdr(HttpMoved) != -1
                 && responselocation(location, reqbuf) != -1
- && responsecontenttype(texthtml) != -1
- && writedata("\r\n<html><body>301 Moved Permanently</a></body></html>\r\n") != -1);
+ && responsecontenttype(texthtml) != -1)
+ ;
+ else
+ return;
+ if(reqtype == GET)
+ writetext("\r\n<html><body>301 Moved Permanently</a></body></html>\r\n");
                 return;
         }
         if(len + strlen(docindex) + 1 < MAXREQLEN)
@@ -251,15 +276,21 @@
         FILE *cgi;
         int r;
 
- setenv("REQUEST_METHOD", "GET", 1);
+ if(reqtype == GET)
+ setenv("REQUEST_METHOD", "GET", 1);
+ else if(reqtype == HEAD)
+ setenv("REQUEST_METHOD", "HEAD", 1);
+ else
+ return;
         setenv("SERVER_NAME", servername, 1);
         setenv("SCRIPT_NAME", cgi_script, 1);
+ setenv("REQUEST_URI", reqbuf, 1);
+ chdir(cgi_dir);
         if((cgi = popen(cgi_script, "r"))) {
                 if(responsehdr(HttpOk) == -1)
                         return;
- while((r = fread(respbuf, 1, sizeof respbuf - 1, cgi) > 0)) {
- respbuf[r] = 0;
- if(writedata(respbuf) == -1) {
+ while((r = fread(respbuf, 1, sizeof respbuf - 1, cgi)) > 0) {
+ if(writedata(respbuf, r) == -1) {
                                 pclose(cgi);
                                 return;
                         }
@@ -269,8 +300,12 @@
         else {
                 fprintf(stderr, "%s: %s requests %s, but cannot run cgi script %s\n", tstamp(), name, cgi_script, reqbuf);
                 if(responsehdr(HttpNotFound) != -1
- && responsecontenttype(texthtml) != -1
- && writedata("\r\n<html><body>404 Not Found</body></html>\r\n") != -1);
+ && responsecontenttype(texthtml) != -1)
+ ;
+ else
+ return;
+ if(reqtype == GET)
+ writetext("\r\n<html><body>404 Not Found</body></html>\r\n");
         }
 }
 
@@ -283,8 +318,12 @@
                 if(*p == '\\' || *p == '?' || *p == '%' || *p == '&' || (*p == '/' && *(p + 1) == '.')) { /* don't serve bogus or hidden files */
                         fprintf(stderr, "%s: %s requests bogus or hidden file %s\n", tstamp(), name, reqbuf);
                         if(responsehdr(HttpUnauthorized) != -1
- && responsecontenttype(texthtml) != -1
- && writedata("\r\n<html><body>401 Unauthorized</body></html>\r\n") != -1);
+ && responsecontenttype(texthtml) != -1)
+ ;
+ else
+ return;
+ if(reqtype == GET)
+ writetext("\r\n<html><body>401 Unauthorized</body></html>\r\n");
                         return;
                 }
         fprintf(stdout, "%s: %s requests: %s\n", tstamp(), name, reqbuf);
@@ -313,20 +352,24 @@
                 offset += r;
                 reqbuf[offset] = 0;
         }
- while(offset < MAXREQLEN && (!strstr(reqbuf, "\r\n\r\n") || !strstr(reqbuf, "\n\n")));
+ while(offset < MAXREQLEN && !strstr(reqbuf, "\r\n\r\n") && !strstr(reqbuf, "\n\n"));
         for(p = reqbuf; *p && *p != '\r' && *p != '\n'; p++);
         if(p >= reqbuf + MAXREQLEN)
                 goto invalid_request;
         if(*p == '\r' || *p == '\n') {
                 *p = 0;
                 /* check command */
- if(strncmp(reqbuf, "GET ", 4) || reqbuf[4] != '/')
+ if(!strncmp(reqbuf, "GET ", 4) && reqbuf[4] == '/')
+ reqtype = GET;
+ else if(!strncmp(reqbuf, "HEAD ", 5) && reqbuf[5] != '/')
+ reqtype = HEAD;
+ else
                         goto invalid_request;
         }
         else
                 goto invalid_request;
         /* determine path */
- for(res = reqbuf + 4; *res && *(res + 1) == '/'; res++); /* strip '/' */
+ for(res = reqbuf + reqtype; *res && *(res + 1) == '/'; res++); /* strip '/' */
         if(res >= reqbuf + MAXREQLEN)
                 goto invalid_request;
         for(p = res; *p && *p != ' ' && *p != '\t'; p++);
Received on Sun Mar 28 2010 - 02:14:34 UTC

This archive was generated by hypermail 2.2.0 : Sun Mar 28 2010 - 02:24:08 UTC