preparing Request abstraction, ongoing
This commit is contained in:
parent
a61a51b91d
commit
d6cbb5b9d9
2 changed files with 44 additions and 21 deletions
|
@ -16,6 +16,7 @@ static const MimeType servermimes[] = {
|
||||||
{ "css", "text/css" },
|
{ "css", "text/css" },
|
||||||
{ "txt", "text/plain" },
|
{ "txt", "text/plain" },
|
||||||
{ "text", "text/plain" },
|
{ "text", "text/plain" },
|
||||||
|
{ "md", "text/plain" },
|
||||||
{ "png", "image/png" },
|
{ "png", "image/png" },
|
||||||
{ "gif", "image/gif" },
|
{ "gif", "image/gif" },
|
||||||
{ "jpg", "image/jpg" },
|
{ "jpg", "image/jpg" },
|
||||||
|
|
64
quark.c
64
quark.c
|
@ -31,6 +31,27 @@ typedef struct {
|
||||||
const char *mimetype;
|
const char *mimetype;
|
||||||
} MimeType;
|
} MimeType;
|
||||||
|
|
||||||
|
typedef struct _Param Param;
|
||||||
|
struct _Param {
|
||||||
|
const char *key;
|
||||||
|
const char *value;
|
||||||
|
Param *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int type;
|
||||||
|
int fd;
|
||||||
|
const char *hostname;
|
||||||
|
const char *resource;
|
||||||
|
Param *params;
|
||||||
|
} Request;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *hostname;
|
||||||
|
const char *resource;
|
||||||
|
void (*handle)(const Request *r);
|
||||||
|
} RequestHandler;
|
||||||
|
|
||||||
static const char HttpOk[] = "200 OK";
|
static const char HttpOk[] = "200 OK";
|
||||||
static const char HttpMoved[] = "302 Moved Permanently";
|
static const char HttpMoved[] = "302 Moved Permanently";
|
||||||
static const char HttpUnauthorized[] = "401 Unauthorized";
|
static const char HttpUnauthorized[] = "401 Unauthorized";
|
||||||
|
@ -62,14 +83,15 @@ static char host[NI_MAXHOST];
|
||||||
static char reqbuf[MAXBUFLEN+1];
|
static char reqbuf[MAXBUFLEN+1];
|
||||||
static char resbuf[MAXBUFLEN+1];
|
static char resbuf[MAXBUFLEN+1];
|
||||||
static char reqhost[256];
|
static char reqhost[256];
|
||||||
static int fd, cfd, reqtype;
|
static int fd;
|
||||||
|
static Request req;
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
writedata(const char *buf, size_t buf_len) {
|
writedata(const char *buf, size_t buf_len) {
|
||||||
ssize_t r, offset = 0;
|
ssize_t r, offset = 0;
|
||||||
|
|
||||||
while(offset < buf_len) {
|
while(offset < buf_len) {
|
||||||
if((r = write(cfd, buf + offset, buf_len - offset)) == -1) {
|
if((r = write(req.fd, buf + offset, buf_len - offset)) == -1) {
|
||||||
logerrmsg("client %s closed connection\n", host);
|
logerrmsg("client %s closed connection\n", host);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -183,7 +205,7 @@ responsefiledata(int fd, off_t size) {
|
||||||
off_t offset = 0;
|
off_t offset = 0;
|
||||||
|
|
||||||
while(offset < size)
|
while(offset < size)
|
||||||
if(sendfile(cfd, fd, &offset, size - offset) == -1) {
|
if(sendfile(req.fd, fd, &offset, size - offset) == -1) {
|
||||||
logerrmsg("sendfile failed on client %s: %s\n", host, strerror(errno));
|
logerrmsg("sendfile failed on client %s: %s\n", host, strerror(errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -203,7 +225,7 @@ responsefile(void) {
|
||||||
;
|
;
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
if(reqtype == GET)
|
if(req.type == GET)
|
||||||
writetext("\r\n<html><body>404 Not Found</body></html>\r\n");
|
writetext("\r\n<html><body>404 Not Found</body></html>\r\n");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -221,7 +243,7 @@ responsefile(void) {
|
||||||
;
|
;
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
if(reqtype == GET && writetext("\r\n") != -1)
|
if(req.type == GET && writetext("\r\n") != -1)
|
||||||
responsefiledata(ffd, st.st_size);
|
responsefiledata(ffd, st.st_size);
|
||||||
close(ffd);
|
close(ffd);
|
||||||
}
|
}
|
||||||
|
@ -236,7 +258,7 @@ responsedirdata(DIR *d) {
|
||||||
;
|
;
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
if(reqtype == GET) {
|
if(req.type == GET) {
|
||||||
if(writetext("\r\n<html><body><a href='..'>..</a><br>\r\n") == -1)
|
if(writetext("\r\n<html><body><a href='..'>..</a><br>\r\n") == -1)
|
||||||
return;
|
return;
|
||||||
while((e = readdir(d))) {
|
while((e = readdir(d))) {
|
||||||
|
@ -271,7 +293,7 @@ responsedir(void) {
|
||||||
;
|
;
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
if(reqtype == GET)
|
if(req.type == GET)
|
||||||
writetext("\r\n<html><body>301 Moved Permanently</a></body></html>\r\n");
|
writetext("\r\n<html><body>301 Moved Permanently</a></body></html>\r\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -295,9 +317,9 @@ responsecgi(void) {
|
||||||
FILE *cgi;
|
FILE *cgi;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if(reqtype == GET)
|
if(req.type == GET)
|
||||||
setenv("REQUEST_METHOD", "GET", 1);
|
setenv("REQUEST_METHOD", "GET", 1);
|
||||||
else if(reqtype == HEAD)
|
else if(req.type == HEAD)
|
||||||
setenv("REQUEST_METHOD", "HEAD", 1);
|
setenv("REQUEST_METHOD", "HEAD", 1);
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
@ -326,7 +348,7 @@ responsecgi(void) {
|
||||||
;
|
;
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
if(reqtype == GET)
|
if(req.type == GET)
|
||||||
writetext("\r\n<html><body>404 Not Found</body></html>\r\n");
|
writetext("\r\n<html><body>404 Not Found</body></html>\r\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -344,7 +366,7 @@ response(void) {
|
||||||
;
|
;
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
if(reqtype == GET)
|
if(req.type == GET)
|
||||||
writetext("\r\n<html><body>401 Unauthorized</body></html>\r\n");
|
writetext("\r\n<html><body>401 Unauthorized</body></html>\r\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -366,7 +388,7 @@ request(void) {
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
|
|
||||||
do { /* MAXBUFLEN byte of reqbuf is emergency 0 terminator */
|
do { /* MAXBUFLEN byte of reqbuf is emergency 0 terminator */
|
||||||
if((r = read(cfd, 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;
|
||||||
}
|
}
|
||||||
|
@ -392,16 +414,16 @@ request(void) {
|
||||||
*p = 0;
|
*p = 0;
|
||||||
/* check command */
|
/* check command */
|
||||||
if(!strncmp(reqbuf, "GET ", 4) && reqbuf[4] == '/')
|
if(!strncmp(reqbuf, "GET ", 4) && reqbuf[4] == '/')
|
||||||
reqtype = GET;
|
req.type = GET;
|
||||||
else if(!strncmp(reqbuf, "HEAD ", 5) && reqbuf[5] == '/')
|
else if(!strncmp(reqbuf, "HEAD ", 5) && reqbuf[5] == '/')
|
||||||
reqtype = 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 + reqtype; *res && *(res + 1) == '/'; res++); /* strip '/' */
|
for(res = reqbuf + req.type; *res && *(res + 1) == '/'; res++); /* strip '/' */
|
||||||
if(!*res)
|
if(!*res)
|
||||||
goto invalid_request;
|
goto invalid_request;
|
||||||
for(p = res; *p && *p != ' ' && *p != '\t'; p++);
|
for(p = res; *p && *p != ' ' && *p != '\t'; p++);
|
||||||
|
@ -423,7 +445,7 @@ serve(int fd) {
|
||||||
|
|
||||||
while(running) {
|
while(running) {
|
||||||
salen = sizeof sa;
|
salen = sizeof sa;
|
||||||
if((cfd = accept(fd, &sa, &salen)) == -1) {
|
if((req.fd = accept(fd, &sa, &salen)) == -1) {
|
||||||
/* el cheapo socket release */
|
/* el cheapo socket release */
|
||||||
logerrmsg("cannot accept: %s, sleep a second...\n", strerror(errno));
|
logerrmsg("cannot accept: %s, sleep a second...\n", strerror(errno));
|
||||||
sleep(1);
|
sleep(1);
|
||||||
|
@ -435,15 +457,15 @@ serve(int fd) {
|
||||||
host[0] = 0;
|
host[0] = 0;
|
||||||
getnameinfo(&sa, salen, host, sizeof host, NULL, 0, NI_NOFQDN);
|
getnameinfo(&sa, salen, host, sizeof host, NULL, 0, NI_NOFQDN);
|
||||||
result = request();
|
result = request();
|
||||||
shutdown(cfd, SHUT_RD);
|
shutdown(req.fd, SHUT_RD);
|
||||||
if(result == 0)
|
if(result == 0)
|
||||||
response();
|
response();
|
||||||
shutdown(cfd, SHUT_WR);
|
shutdown(req.fd, SHUT_WR);
|
||||||
close(cfd);
|
close(req.fd);
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
} else if (result == -1)
|
} else if (result == -1)
|
||||||
logerrmsg("fork failed: %s\n", strerror(errno));
|
logerrmsg("fork failed: %s\n", strerror(errno));
|
||||||
close(cfd);
|
close(req.fd);
|
||||||
}
|
}
|
||||||
logmsg("shutting down\n");
|
logmsg("shutting down\n");
|
||||||
}
|
}
|
||||||
|
@ -495,7 +517,7 @@ main(int argc, char *argv[]) {
|
||||||
/* arguments */
|
/* arguments */
|
||||||
for(i = 1; i < argc; i++)
|
for(i = 1; i < argc; i++)
|
||||||
if(!strcmp(argv[i], "-v"))
|
if(!strcmp(argv[i], "-v"))
|
||||||
die("quark-"VERSION", © 2009-2010 Anselm R Garbe\n");
|
die("quark-"VERSION", © 2009-2011 Anselm R Garbe\n");
|
||||||
else
|
else
|
||||||
die("usage: quark [-v]\n");
|
die("usage: quark [-v]\n");
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue