diff --git a/ChangeLog b/ChangeLog index 466b416..97ea95f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,10 +1,14 @@ +2012-02-20 10:10:29 +0100 Georg Hopp + + * first very crude, not complete, experimental 304 test implementation (HEAD, master) + 2012-02-20 07:55:06 +0100 Georg Hopp - * disconnect on invalid request line (HEAD, master) + * disconnect on invalid request line (origin/master, origin/HEAD) 2012-02-19 20:12:40 +0100 Georg Hopp - * now incomplete requests should no longer block the complete server. Tested with \'echo -en "GET / HTTP\r\nConn" | nc -w 600 localhost 11212\' and then doing requests from my browser. @TODO: cleanup those stuff, check if a not correctly response reading would block the server. (origin/master, origin/HEAD) + * now incomplete requests should no longer block the complete server. Tested with \'echo -en "GET / HTTP\r\nConn" | nc -w 600 localhost 11212\' and then doing requests from my browser. @TODO: cleanup those stuff, check if a not correctly response reading would block the server. 2012-02-19 18:28:30 +0100 Georg Hopp diff --git a/include/http/response.h b/include/http/response.h index 422a124..eab4194 100644 --- a/include/http/response.h +++ b/include/http/response.h @@ -1,6 +1,7 @@ #ifndef __HTTP_RESPONSE_H__ #define __HTTP_RESPONSE_H__ +#include #include #include "class.h" @@ -14,9 +15,10 @@ CLASS(HttpResponse) { char * reason; }; +HttpResponse httpResponse304(int, const char *); HttpResponse httpResponse404(); HttpResponse httpResponseMe(); -HttpResponse httpResponseImage(); +HttpResponse httpResponseImage(int); //void httpResponseHeaderSet(HttpResponse, const char *, const char *); diff --git a/src/Makefile.am b/src/Makefile.am index 0c3791b..af1873c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -20,6 +20,7 @@ MSG = http/message.c http/message/queue.c http/message/has_keep_alive.c \ http/message/get_version.c http/message/has_valid_version.c REQ = http/request.c http/request/has_valid_method.c RESP = http/response.c \ + http/response/304.c \ http/response/404.c \ http/response/image.c \ http/response/me.c diff --git a/src/http/response/304.c b/src/http/response/304.c new file mode 100644 index 0000000..9188e3d --- /dev/null +++ b/src/http/response/304.c @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include +#include + +#include "class.h" +#include "interface/class.h" + +#include "http/response.h" +#include "http/message.h" +#include "http/header.h" + + +HttpResponse +httpResponse304(int handle, const char * content_type) +{ + time_t t; + struct tm * tmp; + char buffer[200]; + struct stat st; + HttpResponse response; + HttpMessage message; + + fstat(handle, &st); + + response = new(HttpResponse, "HTTP/1.1", 304, "Not Modified"); + message = (HttpMessage)response; + + httpHeaderAdd(&(message->header), + new(HttpHeader, "Content-Type", content_type)); + httpHeaderAdd(&(message->header), + new(HttpHeader, "Server", "testserver")); + + message->type = HTTP_MESSAGE_BUFFERED; + message->nbody = 0; + message->body = NULL; + + tmp = localtime(&(st.st_mtime)); + strftime(buffer, sizeof(buffer), "%s", tmp); + httpHeaderAdd(&(message->header), + new(HttpHeader, "ETag", buffer)); + + tmp = localtime(&(st.st_mtime)); + strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp); + httpHeaderAdd(&(message->header), + new(HttpHeader, "Last-Modified", buffer)); + + t = time(NULL); + tmp = localtime(&t); + strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp); + httpHeaderAdd(&(message->header), + new(HttpHeader, "Date", buffer)); + + return response; +} + +// vim: set ts=4 sw=4: diff --git a/src/http/response/image.c b/src/http/response/image.c index 0400202..8261281 100644 --- a/src/http/response/image.c +++ b/src/http/response/image.c @@ -13,13 +13,15 @@ HttpResponse -httpResponseImage() +httpResponseImage(int handle) { char buffer[200]; struct stat st; HttpResponse response; HttpMessage message; + fstat(handle, &st); + response = new(HttpResponse, "HTTP/1.1", 200, "OK"); message = (HttpMessage)response; @@ -29,14 +31,24 @@ httpResponseImage() new(HttpHeader, "Server", "testserver")); message->type = HTTP_MESSAGE_PIPED; - message->handle = open("./assets/waldschrat.jpg", O_RDONLY); - fstat(message->handle, &st); + message->handle = handle; message->nbody = st.st_size; sprintf(buffer, "%d", message->nbody); httpHeaderAdd(&(message->header), new(HttpHeader, "Content-Length", buffer)); + tmp = localtime(&(st.st_mtime)); + strftime(buffer, sizeof(buffer), "%s", tmp); + httpHeaderAdd(&(message->header), + new(HttpHeader, "ETag", buffer)); + + t = time(NULL); + tmp = localtime(&t); + strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp); + httpHeaderAdd(&(message->header), + new(HttpHeader, "Date", buffer)); + return response; } diff --git a/src/http/worker/process.c b/src/http/worker/process.c index ebc4bcc..518b697 100644 --- a/src/http/worker/process.c +++ b/src/http/worker/process.c @@ -1,4 +1,6 @@ -#include +#include +#include +#include #include "class.h" #include "interface/class.h" @@ -36,7 +38,16 @@ httpWorkerProcess(HttpWorker this, int fd) } else if (0 == strcmp("GET", request->method) && 0 == strcmp("/image/", request->uri)) { - response = (HttpMessage)httpResponseImage(); + int handle = open("./assets/waldschrat.jpg", O_RDONLY); + + if (NULL != httpHeaderGet( + &(((HttpMessage)request)->header), + "If-None-Match")) { + response = httpResponse304(handle, "image/jpeg"); + } + else { + response = (HttpMessage)httpResponseImage(handle); + } } else { response = (HttpMessage)httpResponse404();