Refactor request()

Unite duplicate code in the getreqentry() function, making error-checking
much easier, and, more importantly, drastically increase the readability.
This commit is contained in:
FRIGN 2014-07-28 15:30:56 +02:00
parent c3d007756e
commit 6d5bedd72a

60
quark.c
View file

@ -58,6 +58,7 @@ static void responsedir(void);
static void responsedirdata(DIR *d); static void responsedirdata(DIR *d);
static void responsefile(void); static void responsefile(void);
static void responsefiledata(int fd, off_t size); static void responsefiledata(int fd, off_t size);
static int getreqentry(char *name, char *target, size_t targetlen, char *breakchars);
static int request(void); static int request(void);
static void serve(int fd); static void serve(int fd);
static void sighandler(int sig); static void sighandler(int sig);
@ -397,45 +398,49 @@ response(void) {
} }
} }
int
getreqentry(char *name, char *target, size_t targetlen, char *breakchars) {
char *p, *res;
if((res = strstr(reqbuf, name))) {
for(res = res + strlen(name); *res && (*res == ' ' || *res == '\t'); ++res);
if(!*res)
return 1;
for(p = res; *p && !strchr(breakchars, *p); ++p);
if(!*p)
return 1;
if((size_t)(p - res) > targetlen)
return 1;
memcpy(target, res, p - res);
target[p - res] = 0;
return 0;
}
return -1;
}
int int
request(void) { request(void) {
char *p, *res; char *p, *res;
int r; int r;
size_t offset = 0; size_t offset = 0;
do { /* MAXBUFLEN byte of reqbuf is emergency 0 terminator */ /* read request into reqbuf */
for( ; r > 0 && offset < MAXBUFLEN && (!strstr(reqbuf, "\r\n") || !strstr(reqbuf, "\n")); ) {
if((r = read(req.fd, reqbuf + offset, MAXBUFLEN - offset)) == -1) { if((r = read(req.fd, reqbuf + offset, MAXBUFLEN - offset)) == -1) {
logerrmsg("read: %s\n", strerror(errno)); logerrmsg("read: %s\n", strerror(errno));
return -1; return -1;
} }
offset += r; offset += r;
reqbuf[offset] = 0; reqbuf[offset] = 0; /* MAXBUFLEN byte of reqbuf is emergency 0 terminator */
} }
while(r > 0 && offset < MAXBUFLEN && (!strstr(reqbuf, "\r\n") || !strstr(reqbuf, "\n")));
if((res = strstr(reqbuf, "Host:"))) { /* extract host and mod */
for(res = res + 5; *res && (*res == ' ' || *res == '\t'); res++); if (getreqentry("Host:", reqhost, LENGTH(reqhost), " \t\r\n") != 0)
if(!*res)
goto invalid_request; goto invalid_request;
for(p = res; *p && *p != ' ' && *p != '\t' && *p != '\r' && *p != '\n'; p++); if (getreqentry("If-Modified-Since:", reqmod, LENGTH(reqmod), "\r\n") == 1)
if(!*p)
goto invalid_request; goto invalid_request;
if(p - res > sizeof reqhost)
goto invalid_request; /* extract method */
memcpy(reqhost, res, p - res);
reqhost[p - res] = 0;
}
if((res = strstr(reqbuf, "If-Modified-Since:"))) {
for(res = res + 19; *res && (*res == ' ' || *res == '\t'); res++);
if(!*res)
goto invalid_request;
for(p = res; *p && *p != '\r' && *p != '\n'; p++);
if(!*p)
goto invalid_request;
if(p - res > sizeof reqmod)
goto invalid_request;
memcpy(reqmod, res, p - res);
reqmod[p - res] = 0;
}
for(p = reqbuf; *p && *p != '\r' && *p != '\n'; p++); for(p = reqbuf; *p && *p != '\r' && *p != '\n'; p++);
if(*p == '\r' || *p == '\n') { if(*p == '\r' || *p == '\n') {
*p = 0; *p = 0;
@ -446,9 +451,10 @@ request(void) {
req.type = HEAD; req.type = HEAD;
else else
goto invalid_request; goto invalid_request;
} } else {
else
goto invalid_request; goto invalid_request;
}
/* determine path */ /* determine path */
for(res = reqbuf + req.type; *res && *(res + 1) == '/'; res++); /* strip '/' */ for(res = reqbuf + req.type; *res && *(res + 1) == '/'; res++); /* strip '/' */
if(!*res) if(!*res)