Commit f82c178b5bd15119bb67a393ce3d5637ab36d3bf

Authored by Georg Hopp
1 parent 9198f7e7

started a response handler and changed serverRun to use it for its response

  1 +2012-02-10 19:57:57 +0100 Georg Hopp
  2 +
  3 + * started a response handler and changed serverRun to use it for its response (HEAD, master)
  4 +
1 2012-02-10 12:42:04 +0100 Georg Hopp 5 2012-02-10 12:42:04 +0100 Georg Hopp
2 6
3 - * fixed bug at server destructor (HEAD, master) 7 + * fixed bug at server destructor (origin/master, origin/HEAD)
4 8
5 2012-02-10 09:59:41 +0100 Georg Hopp 9 2012-02-10 09:59:41 +0100 Georg Hopp
6 10
@@ -12,7 +16,7 @@ @@ -12,7 +16,7 @@
12 16
13 2012-02-10 08:14:31 +0100 Georg Hopp 17 2012-02-10 08:14:31 +0100 Georg Hopp
14 18
15 - * now only use keep-alive.... (origin/master, origin/HEAD) 19 + * now only use keep-alive....
16 20
17 2012-02-10 06:36:43 +0100 Georg Hopp 21 2012-02-10 06:36:43 +0100 Georg Hopp
18 22
  1 +VERY BIG TODO:
  2 +- give a contructor a way to fail, so that no object will be created at all
@@ -10,8 +10,11 @@ CLASS(HttpHeader) { @@ -10,8 +10,11 @@ CLASS(HttpHeader) {
10 }; 10 };
11 11
12 HttpHeader httpHeaderParse(char * line); // @INFO: destructive 12 HttpHeader httpHeaderParse(char * line); // @INFO: destructive
13 -void httpHeaderSort(const HttpHeader [], int);  
14 -char * httpHeaderGet(const HttpHeader [], int, const char *); 13 +
  14 +void httpHeaderSort(const HttpHeader [], int);
  15 +char * httpHeaderGet(const HttpHeader [], int, const char *);
  16 +size_t httpHeaderSizeGet(HttpHeader);
  17 +size_t httpHeaderToString(HttpHeader, char *);
15 18
16 #endif // __HTTP_HEADER_H__ 19 #endif // __HTTP_HEADER_H__
17 20
@@ -16,8 +16,8 @@ CLASS(HttpRequest) { @@ -16,8 +16,8 @@ CLASS(HttpRequest) {
16 int nbody; 16 int nbody;
17 }; 17 };
18 18
19 -char *  
20 -httpRequestHeaderGet(HttpRequest this, const char * name); 19 +char * httpRequestHeaderGet(HttpRequest, const char *);
  20 +char httpRequestHasKeepAlive(HttpRequest);
21 21
22 #endif /* __HTTP_REQUEST_H__ */ 22 #endif /* __HTTP_REQUEST_H__ */
23 23
1 #ifndef __HTTP_RESPONSE_H__ 1 #ifndef __HTTP_RESPONSE_H__
2 #define __HTTP_RESPONSE_H__ 2 #define __HTTP_RESPONSE_H__
3 3
  4 +#include <sys/types.h>
  5 +
4 #include "class.h" 6 #include "class.h"
  7 +#include "http/header.h"
  8 +
5 9
6 CLASS(HttpResponse) { 10 CLASS(HttpResponse) {
7 - char * http_version;  
8 - char * status;  
9 - char * reson; 11 + char * version;
  12 + unsigned int status;
  13 + char * reason;
10 14
11 - HttpHeader header[128];  
12 - int nheader; 15 + HttpHeader header[128];
  16 + int nheader;
13 17
14 - char * body;  
15 - int nbody; 18 + char * body;
  19 + int nbody;
16 }; 20 };
17 21
18 -char *  
19 -httpRequestHeaderGet(HttpRequest this, const char * name); 22 +HttpResponse httpResponse404();
  23 +
  24 +void httpResponseHeaderSet(HttpResponse, const char *, const char *);
  25 +size_t httpResponseSizeGet(HttpResponse);
  26 +size_t httpResponseToString(HttpResponse, char *);
20 27
21 #endif /* __HTTP_RESPONSE_H__ */ 28 #endif /* __HTTP_RESPONSE_H__ */
22 29
@@ -43,7 +43,7 @@ CLASS(Server) { @@ -43,7 +43,7 @@ CLASS(Server) {
43 43
44 char keep_alive; 44 char keep_alive;
45 45
46 - char wbuf[2048]; 46 + char * wbuf;
47 char * rbuf; 47 char * rbuf;
48 unsigned int rpos; 48 unsigned int rpos;
49 unsigned int wpos; 49 unsigned int wpos;
1 ACLOCAL_AMFLAGS = -I m4 1 ACLOCAL_AMFLAGS = -I m4
2 AUTOMAKE_OPTIONS = subdir-objects 2 AUTOMAKE_OPTIONS = subdir-objects
3 3
4 -CLASS = class.c interface.c interface/class.c 4 +IFACE = interface/class.c interface/stream_reader.c interface/logger.c
  5 +CLASS = class.c interface.c
5 SOCKET = socket.c socket/accept.c socket/connect.c socket/listen.c 6 SOCKET = socket.c socket/accept.c socket/connect.c socket/listen.c
6 SERVER = server.c server/run.c server/close_conn.c 7 SERVER = server.c server/run.c server/close_conn.c
7 -LOGGER = logger.c logger/stderr.c logger/syslog.c interface/logger.c  
8 -HTTP = interface/stream_reader.c http/request/parser.c http/request.c \  
9 - http/request/queue.c http/header.c http/header/get.c \  
10 - http/header/sort.c http/request/parser/get_header.c \ 8 +LOGGER = logger.c logger/stderr.c logger/syslog.c
  9 +REQ = http/request.c http/request/queue.c http/request/has_keep_alive.c
  10 +RESP = http/response.c http/response/header_set.c \
  11 + http/response/404.c http/response/size_get.c \
  12 + http/response/to_string.c
  13 +HEADER = http/header.c http/header/get.c http/header/sort.c \
  14 + http/header/size_get.c http/header/to_string.c
  15 +PARSER = http/request/parser.c http/request/parser/get_header.c \
11 http/request/parser/parse.c http/request/parser/get_request_line.c 16 http/request/parser/parse.c http/request/parser/get_request_line.c
12 17
  18 +
13 AM_CFLAGS = -Wall -I ../include/ 19 AM_CFLAGS = -Wall -I ../include/
14 20
15 bin_PROGRAMS = testserver 21 bin_PROGRAMS = testserver
16 22
17 testserver_SOURCES = testserver.c \ 23 testserver_SOURCES = testserver.c \
18 - $(CLASS) $(SOCKET) $(SERVER) $(LOGGER) $(HTTP) \  
19 - signalHandling.c daemonize.c 24 + $(IFACE) $(CLASS) $(SOCKET) $(SERVER) $(LOGGER) $(REQ) \
  25 + $(RESP) $(HEADER) $(PARSER) signalHandling.c daemonize.c
20 testserver_CFLAGS = -Wall -I ../include/ 26 testserver_CFLAGS = -Wall -I ../include/
  1 +#include <sys/types.h>
  2 +
  3 +#include "http/header.h"
  4 +
  5 +size_t
  6 +httpHeaderSizeGet(HttpHeader header)
  7 +{
  8 + size_t size = 0;
  9 +
  10 + size += strlen(header->name) + 2;
  11 + size += strlen(header->value);
  12 +
  13 + return size;
  14 +}
  15 +
  16 +// vim: set ts=4 sw=4:
  1 +#include <string.h>
  2 +
  3 +#include "http/header.h"
  4 +
  5 +size_t
  6 +httpHeaderToString(HttpHeader header, char * string)
  7 +{
  8 + size_t size = httpHeaderSizeGet(header);
  9 +
  10 + strcpy(string, header->name);
  11 + string += strlen(string);
  12 +
  13 + *string++ = ':';
  14 + *string++ = ' ';
  15 +
  16 + strcpy(string, header->value);
  17 +
  18 + return size;
  19 +}
  20 +
  21 +// vim: set ts=4 sw=4:
  1 +#include <string.h>
  2 +#include <ctype.h>
  3 +
  4 +#include "http/request.h"
  5 +#include "http/header.h"
  6 +
  7 +
  8 +char
  9 +httpRequestHasKeepAlive(HttpRequest request)
  10 +{
  11 + char * header;
  12 + char * header_ptr;
  13 +
  14 + header = httpHeaderGet(request->header, request->nheader, "connection");
  15 +
  16 + if (NULL == header) {
  17 + return 0;
  18 + }
  19 +
  20 + for (header_ptr = header; 0 != *header_ptr; header_ptr++) {
  21 + *header_ptr = tolower(*header_ptr);
  22 + }
  23 +
  24 + if (0 == strcmp(header, "keep-alive")) {
  25 + return 1;
  26 + }
  27 +
  28 + return 0;
  29 +}
  30 +
  31 +// vim: set ts=4 sw=4:
  1 +#include <stdlib.h>
  2 +#include <stdarg.h>
  3 +
  4 +#include "class.h"
  5 +#include "interface/class.h"
  6 +
  7 +#include "http/response.h"
  8 +
  9 +
  10 +static
  11 +void
  12 +_free(void ** data)
  13 +{
  14 + if (NULL != *data) {
  15 + free(*data);
  16 + }
  17 +}
  18 +
  19 +static
  20 +void
  21 +ctor(void * _this, va_list * params)
  22 +{
  23 + char * version;
  24 + char * reason;
  25 +
  26 + HttpResponse this = _this;
  27 +
  28 + version = va_arg(* params, char *);
  29 + this->status = va_arg(* params, unsigned int);
  30 + reason = va_arg(* params, char *);
  31 +
  32 + this->version = calloc(1, strlen(version)+1);
  33 + strcpy(this->version, version);
  34 +
  35 + this->reason = calloc(1, strlen(reason)+1);
  36 + strcpy(this->reason, reason);
  37 +}
  38 +
  39 +static
  40 +void
  41 +dtor(void * _this)
  42 +{
  43 + HttpResponse this = _this;
  44 + int i;
  45 +
  46 + _free((void **)&(this->version));
  47 + _free((void **)&(this->reason));
  48 +
  49 + for (i=0; i<128; i++) {
  50 + if (NULL == (this->header)[i]) break;
  51 + delete(&(this->header)[i]);
  52 + }
  53 +
  54 + _free((void **)&(this->body));
  55 +}
  56 +
  57 +INIT_IFACE(Class, ctor, dtor, NULL);
  58 +CREATE_CLASS(HttpResponse, NULL, IFACE(Class));
  59 +
  60 +// vim: set ts=4 sw=4:
  1 +#include <stdlib.h>
  2 +#include <string.h>
  3 +#include <stdio.h>
  4 +#include <time.h>
  5 +
  6 +#include "class.h"
  7 +#include "interface/class.h"
  8 +
  9 +#include "http/response.h"
  10 +
  11 +
  12 +#define RESP_DATA "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" \
  13 + "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" \
  14 + " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" \
  15 + "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n" \
  16 + "<head><title>404 - Not Found</title></head>" \
  17 + "<body><h1>404 - Not Found</h1></body>" \
  18 + "</html>"
  19 +
  20 +
  21 +HttpResponse
  22 +httpResponse404()
  23 +{
  24 + time_t t;
  25 + struct tm * tmp;
  26 + char buffer[200];
  27 + HttpResponse response;
  28 +
  29 + response = new(HttpResponse, "HTTP/1.1", 404, "Not Found");
  30 +
  31 + httpResponseHeaderSet(response, "Content-Type", "text/html");
  32 + httpResponseHeaderSet(response, "Server", "testserver");
  33 +
  34 + response->nbody = sizeof(RESP_DATA) - 1;
  35 + response->body = calloc(1, sizeof(RESP_DATA));
  36 + strcpy(response->body, RESP_DATA);
  37 +
  38 + sprintf(buffer, "%d", response->nbody);
  39 + httpResponseHeaderSet(response, "Content-Length", buffer);
  40 +
  41 + t = time(NULL);
  42 + tmp = localtime(&t);
  43 + strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp);
  44 + httpResponseHeaderSet(response, "Date", buffer);
  45 +
  46 + return response;
  47 +}
  48 +
  49 +// vim: set ts=4 sw=4:
  1 +#include "class.h"
  2 +#include "interface/class.h"
  3 +
  4 +#include "http/response.h"
  5 +#include "http/header.h"
  6 +
  7 +void
  8 +httpResponseHeaderSet(HttpResponse this, const char * name, const char * value)
  9 +{
  10 + (this->header)[this->nheader++] = new(HttpHeader, name, value);
  11 +}
  12 +
  13 +// vim: set ts=4 sw=4:
  1 +#include <string.h>
  2 +#include <sys/types.h>
  3 +
  4 +#include "http/response.h"
  5 +#include "http/header.h"
  6 +
  7 +size_t
  8 +httpResponseSizeGet(HttpResponse response)
  9 +{
  10 + int i;
  11 + size_t size = 0;
  12 +
  13 + size += strlen(response->version) + 1;
  14 + size += 4; // for status
  15 + size += strlen(response->reason) + 2;
  16 +
  17 + for (i=0; i<response->nheader; i++) {
  18 + size += httpHeaderSizeGet(response->header[i]) + 2;
  19 + }
  20 +
  21 + size += 2;
  22 + size += response->nbody;
  23 +
  24 + return size;
  25 +}
  26 +
  27 +// vim: set ts=4 sw=4:
  1 +#include <string.h>
  2 +#include <stdio.h>
  3 +
  4 +#include "http/response.h"
  5 +#include "http/header.h"
  6 +
  7 +size_t
  8 +httpResponseToString(HttpResponse response, char * string)
  9 +{
  10 + int i;
  11 + size_t size = httpResponseSizeGet(response);
  12 + char status[4];
  13 +
  14 + snprintf(status, 4, "%d", response->status);
  15 +
  16 + strcpy(string, response->version);
  17 + string += strlen(string);
  18 +
  19 + *string++ = ' ';
  20 +
  21 + strcpy(string, status);
  22 + string += strlen(string);
  23 +
  24 + *string++ = ' ';
  25 +
  26 + strcpy(string, response->reason);
  27 + string += strlen(string);
  28 +
  29 + *string++ = '\r';
  30 + *string++ = '\n';
  31 +
  32 + for (i=0; i<response->nheader; i++) {
  33 + string += httpHeaderToString(response->header[i], string);
  34 + *string++ = '\r';
  35 + *string++ = '\n';
  36 + }
  37 +
  38 + *string++ = '\r';
  39 + *string++ = '\n';
  40 +
  41 + memcpy(string, response->body, response->nbody);
  42 +
  43 + return size;
  44 +}
  45 +
  46 +// vim: set ts=4 sw=4:
@@ -36,14 +36,14 @@ dtor(void * _this) @@ -36,14 +36,14 @@ dtor(void * _this)
36 Server this = _this; 36 Server this = _this;
37 int i; 37 int i;
38 38
39 - printf("nfds: %d\n", this->nfds);  
40 -  
41 for (i=1; i<this->nfds; i++) { 39 for (i=1; i<this->nfds; i++) {
42 /* 40 /*
43 * @TODO do some finalization...buffer handling...etc. 41 * @TODO do some finalization...buffer handling...etc.
44 */ 42 */
45 delete(&(this->conns[(this->fds)[i].fd]).sock); 43 delete(&(this->conns[(this->fds)[i].fd]).sock);
46 delete(&(this->conns[(this->fds)[i].fd]).reader); 44 delete(&(this->conns[(this->fds)[i].fd]).reader);
  45 + if (this->conns[(this->fds)[i].fd].wbuf)
  46 + free(this->conns[(this->fds)[i].fd].wbuf);
47 } 47 }
48 48
49 delete(&this->sock); 49 delete(&this->sock);
@@ -18,7 +18,7 @@ @@ -18,7 +18,7 @@
18 #include "http/request.h" 18 #include "http/request.h"
19 #include "http/request/parser.h" 19 #include "http/request/parser.h"
20 #include "http/request/queue.h" 20 #include "http/request/queue.h"
21 -#include "http/header.h" 21 +#include "http/response.h"
22 //* until here 22 //* until here
23 23
24 #undef MAX 24 #undef MAX
@@ -81,73 +81,36 @@ serverRun(Server this) @@ -81,73 +81,36 @@ serverRun(Server this)
81 ((HttpRequestParser)(this->conns)[fd].reader)->request_queue; 81 ((HttpRequestParser)(this->conns)[fd].reader)->request_queue;
82 82
83 for (j=0; j<queue->nrequests; j++) { 83 for (j=0; j<queue->nrequests; j++) {
84 - HttpRequest request = queue->requests[j];  
85 - char * header;  
86 - char * header_ptr;  
87 -  
88 - //if (NULL != request->body) {  
89 - // puts("==REQUEST BODY==");  
90 - // puts(request->body);  
91 - //}  
92 -  
93 - header = httpHeaderGet(  
94 - request->header,  
95 - request->nheader,  
96 - "connection");  
97 -  
98 - if (NULL != header) {  
99 - for (header_ptr = header;  
100 - 0 != *header_ptr;  
101 - header_ptr++) {  
102 - *header_ptr = tolower(*header_ptr);  
103 - }  
104 -  
105 - if (0 == strcmp(header, "keep-alive")) {  
106 - (this->conns)[fd].keep_alive = 1;  
107 - }  
108 - } 84 + HttpRequest request = queue->requests[j];
  85 + HttpResponse response;
  86 +
109 /** 87 /**
110 * @TODO: for now simply remove request and send not found. 88 * @TODO: for now simply remove request and send not found.
111 * Make this sane. 89 * Make this sane.
112 */ 90 */
  91 + response = httpResponse404();
113 92
114 - delete(&request);  
115 -  
116 - /**  
117 - * @TODO: the complete response stuff have to be removed here.  
118 - */  
119 - time_t t;  
120 - struct tm * tmp;  
121 - char timestr[200];  
122 -  
123 -#define RESP_HEAD "HTTP/1.1 404 Not Found\r\n" \  
124 - "Content-Type: text/html\r\n" \  
125 - "Content-Length: %lu\r\n" \  
126 - "Date: %s\r\n" \  
127 - "Server: testserver\r\n"  
128 -  
129 -#define RESP_DATA "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" \  
130 - "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" \  
131 - " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" \  
132 - "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n" \  
133 - "<head><title>404 - Not Found</title></head>" \  
134 - "<body><h1>404 - Not Found</h1></body>" \  
135 - "</html>"  
136 -  
137 - t = time(NULL);  
138 - tmp = localtime(&t);  
139 - strftime(timestr, sizeof(timestr), "%a, %d %b %Y %T %Z", tmp);  
140 -  
141 - /**  
142 - * @TODO: just to send an answer and be able to make some  
143 - * apache benchs i do it here...this definetly MUST BE moved  
144 - */  
145 - if ((this->conns)[fd].keep_alive) {  
146 - sprintf((this->conns)[fd].wbuf, RESP_HEAD "Connection: Keep-Alive\r\n\r\n" RESP_DATA, sizeof(RESP_DATA) - 1, timestr); 93 + if (httpRequestHasKeepAlive(request)) {
  94 + httpResponseHeaderSet(
  95 + response,
  96 + "Connection",
  97 + "Keep-Alive");
147 } 98 }
148 else { 99 else {
149 - sprintf((this->conns)[fd].wbuf, RESP_HEAD "Connection: close\r\n\r\n" RESP_DATA, sizeof(RESP_DATA) - 1, timestr); 100 + httpResponseHeaderSet(
  101 + response,
  102 + "Connection",
  103 + "Close");
150 } 104 }
  105 +
  106 + delete(&request);
  107 +
  108 + (this->conns)[fd].wbuf = calloc(
  109 + 1, httpResponseSizeGet(response) + 1);
  110 + httpResponseToString(response, (this->conns)[fd].wbuf);
  111 +
  112 + delete(&response);
  113 +
151 (this->fds)[i].events |= POLLOUT; 114 (this->fds)[i].events |= POLLOUT;
152 } 115 }
153 116
@@ -180,6 +143,8 @@ serverRun(Server this) @@ -180,6 +143,8 @@ serverRun(Server this)
180 else { 143 else {
181 serverCloseConn(this, i); 144 serverCloseConn(this, i);
182 } 145 }
  146 + free((this->conns)[fd].wbuf);
  147 + (this->conns)[fd].wbuf = NULL;
183 } 148 }
184 else { 149 else {
185 memmove((this->conns)[fd].wbuf, 150 memmove((this->conns)[fd].wbuf,
Please register or login to post a comment