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 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 9 2012-02-10 09:59:41 +0100 Georg Hopp
6 10
... ... @@ -12,7 +16,7 @@
12 16
13 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 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 10 };
11 11
12 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 19 #endif // __HTTP_HEADER_H__
17 20
... ...
... ... @@ -16,8 +16,8 @@ CLASS(HttpRequest) {
16 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 22 #endif /* __HTTP_REQUEST_H__ */
23 23
... ...
1 1 #ifndef __HTTP_RESPONSE_H__
2 2 #define __HTTP_RESPONSE_H__
3 3
  4 +#include <sys/types.h>
  5 +
4 6 #include "class.h"
  7 +#include "http/header.h"
  8 +
5 9
6 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 28 #endif /* __HTTP_RESPONSE_H__ */
22 29
... ...
... ... @@ -43,7 +43,7 @@ CLASS(Server) {
43 43
44 44 char keep_alive;
45 45
46   - char wbuf[2048];
  46 + char * wbuf;
47 47 char * rbuf;
48 48 unsigned int rpos;
49 49 unsigned int wpos;
... ...
1 1 ACLOCAL_AMFLAGS = -I m4
2 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 6 SOCKET = socket.c socket/accept.c socket/connect.c socket/listen.c
6 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 16 http/request/parser/parse.c http/request/parser/get_request_line.c
12 17
  18 +
13 19 AM_CFLAGS = -Wall -I ../include/
14 20
15 21 bin_PROGRAMS = testserver
16 22
17 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 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 36 Server this = _this;
37 37 int i;
38 38
39   - printf("nfds: %d\n", this->nfds);
40   -
41 39 for (i=1; i<this->nfds; i++) {
42 40 /*
43 41 * @TODO do some finalization...buffer handling...etc.
44 42 */
45 43 delete(&(this->conns[(this->fds)[i].fd]).sock);
46 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 49 delete(&this->sock);
... ...
... ... @@ -18,7 +18,7 @@
18 18 #include "http/request.h"
19 19 #include "http/request/parser.h"
20 20 #include "http/request/queue.h"
21   -#include "http/header.h"
  21 +#include "http/response.h"
22 22 //* until here
23 23
24 24 #undef MAX
... ... @@ -81,73 +81,36 @@ serverRun(Server this)
81 81 ((HttpRequestParser)(this->conns)[fd].reader)->request_queue;
82 82
83 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 88 * @TODO: for now simply remove request and send not found.
111 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 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 114 (this->fds)[i].events |= POLLOUT;
152 115 }
153 116
... ... @@ -180,6 +143,8 @@ serverRun(Server this)
180 143 else {
181 144 serverCloseConn(this, i);
182 145 }
  146 + free((this->conns)[fd].wbuf);
  147 + (this->conns)[fd].wbuf = NULL;
183 148 }
184 149 else {
185 150 memmove((this->conns)[fd].wbuf,
... ...
Please register or login to post a comment