Commit e67667881fd1026ccbc5960dc96feb20a3bd988b

Authored by Georg Hopp
1 parent bf6a341b

change response to tree based header storage and make everything work.

  1 +2012-02-12 04:05:38 +0100 Georg Hopp
  2 +
  3 + * change response to tree based header storage and make everything work. (HEAD, master)
  4 +
1 2012-02-12 00:05:13 +0100 Georg Hopp 5 2012-02-12 00:05:13 +0100 Georg Hopp
2 6
3 - * changed header hashing to use btree (GNU only). @TODO: make this conditional for other systems. Removed the qsort calls on server->fds making O(2nlogn) to O(n) (HEAD, master) 7 + * changed header hashing to use btree (GNU only). @TODO: make this conditional for other systems. Removed the qsort calls on server->fds making O(2nlogn) to O(n) (origin/master, origin/HEAD)
4 8
5 2012-02-11 13:52:32 +0100 Georg Hopp 9 2012-02-11 13:52:32 +0100 Georg Hopp
6 10
7 - * daemonize testserver now (origin/master, origin/HEAD) 11 + * daemonize testserver now
8 12
9 2012-02-11 12:47:01 +0100 Georg Hopp 13 2012-02-11 12:47:01 +0100 Georg Hopp
10 14
@@ -11,8 +11,8 @@ CLASS(HttpHeader) { @@ -11,8 +11,8 @@ CLASS(HttpHeader) {
11 11
12 HttpHeader httpHeaderParse(char * line); // @INFO: destructive 12 HttpHeader httpHeaderParse(char * line); // @INFO: destructive
13 13
14 -void httpHeaderSort(const HttpHeader [], int);  
15 -char * httpHeaderGet(const HttpHeader [], int, const char *); 14 +void httpHeaderAdd(const HttpHeader *, HttpHeader);
  15 +char * httpHeaderGet(const HttpHeader *, const char *);
16 size_t httpHeaderSizeGet(HttpHeader); 16 size_t httpHeaderSizeGet(HttpHeader);
17 size_t httpHeaderToString(HttpHeader, char *); 17 size_t httpHeaderToString(HttpHeader, char *);
18 18
@@ -15,9 +15,6 @@ CLASS(HttpRequest) { @@ -15,9 +15,6 @@ CLASS(HttpRequest) {
15 int nbody; 15 int nbody;
16 }; 16 };
17 17
18 -void httpHeaderAdd(HttpHeader *, HttpHeader);  
19 -char * XhttpHeaderGet(HttpHeader *, const char *);  
20 -char * httpRequestHeaderGet(HttpRequest, const char *);  
21 char httpRequestHasKeepAlive(HttpRequest); 18 char httpRequestHasKeepAlive(HttpRequest);
22 19
23 #endif /* __HTTP_REQUEST_H__ */ 20 #endif /* __HTTP_REQUEST_H__ */
@@ -7,6 +7,7 @@ @@ -7,6 +7,7 @@
7 7
8 #define HTTP_REQUEST_PARSER_READ_CHUNK 1024 8 #define HTTP_REQUEST_PARSER_READ_CHUNK 1024
9 9
  10 +
10 typedef enum e_HttpRequestState { 11 typedef enum e_HttpRequestState {
11 HTTP_REQUEST_GARBAGE=0, 12 HTTP_REQUEST_GARBAGE=0,
12 HTTP_REQUEST_START, 13 HTTP_REQUEST_START,
@@ -29,6 +30,11 @@ CLASS(HttpRequestParser) { @@ -29,6 +30,11 @@ CLASS(HttpRequestParser) {
29 HttpRequestState state; 30 HttpRequestState state;
30 }; 31 };
31 32
  33 +size_t httpRequestParserRead(HttpRequestParser, int);
  34 +void httpRequestParserParse(HttpRequestParser);
  35 +void httpRequestParserGetRequestLine(HttpRequest, char *);
  36 +void httpRequestParserGetHeader(HttpRequest, char *);
  37 +
32 #endif /* __HTTP_REQUEST_PARSER_H__ */ 38 #endif /* __HTTP_REQUEST_PARSER_H__ */
33 39
34 // vim: set ts=4 sw=4: 40 // vim: set ts=4 sw=4:
@@ -12,8 +12,7 @@ CLASS(HttpResponse) { @@ -12,8 +12,7 @@ CLASS(HttpResponse) {
12 unsigned int status; 12 unsigned int status;
13 char * reason; 13 char * reason;
14 14
15 - HttpHeader header[128];  
16 - int nheader; 15 + HttpHeader header;
17 16
18 char * body; 17 char * body;
19 int nbody; 18 int nbody;
@@ -23,7 +22,7 @@ HttpResponse httpResponse404(); @@ -23,7 +22,7 @@ HttpResponse httpResponse404();
23 22
24 void httpResponseHeaderSet(HttpResponse, const char *, const char *); 23 void httpResponseHeaderSet(HttpResponse, const char *, const char *);
25 size_t httpResponseSizeGet(HttpResponse); 24 size_t httpResponseSizeGet(HttpResponse);
26 -size_t httpResponseToString(HttpResponse, char *); 25 +char * httpResponseToString(HttpResponse, char *);
27 26
28 #endif /* __HTTP_RESPONSE_H__ */ 27 #endif /* __HTTP_RESPONSE_H__ */
29 28
@@ -6,17 +6,11 @@ @@ -6,17 +6,11 @@
6 #define MAX_IFACE 32 // ATTENTION: every iface_impl will use MAX_IFACE * sizeof(void*) 6 #define MAX_IFACE 32 // ATTENTION: every iface_impl will use MAX_IFACE * sizeof(void*)
7 7
8 #define IFACE(name) ((const struct i_##name const*)&i_##name##_impl) 8 #define IFACE(name) ((const struct i_##name const*)&i_##name##_impl)
9 -  
10 #define INIT_IFACE(name,...) \ 9 #define INIT_IFACE(name,...) \
11 static const struct i_##name i_##name##_impl = {&i_##name,__VA_ARGS__} 10 static const struct i_##name i_##name##_impl = {&i_##name,__VA_ARGS__}
12 11
13 #define NUMARGS(...) (sizeof((const void*[]){__VA_ARGS__})/sizeof(void*)) 12 #define NUMARGS(...) (sizeof((const void*[]){__VA_ARGS__})/sizeof(void*))
14 -  
15 #define INIT_IMPL(...) {NUMARGS(__VA_ARGS__), 0, {__VA_ARGS__}} 13 #define INIT_IMPL(...) {NUMARGS(__VA_ARGS__), 0, {__VA_ARGS__}}
16 -#define CREATE_IMPL(...) \  
17 - static struct iface_impl iface_impl = INIT_IMPL(__VA_ARGS__)  
18 -  
19 -#define METHOD_GET(iface,method) (iface->method)  
20 14
21 15
22 struct interface { 16 struct interface {
@@ -7,13 +7,13 @@ SOCKET = socket.c socket/accept.c socket/connect.c socket/listen.c @@ -7,13 +7,13 @@ SOCKET = socket.c socket/accept.c socket/connect.c socket/listen.c
7 SERVER = server.c server/run.c server/close_conn.c 7 SERVER = server.c server/run.c server/close_conn.c
8 LOGGER = logger.c logger/stderr.c logger/syslog.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 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 \ 10 +RESP = http/response.c http/response/404.c http/response/size_get.c \
12 http/response/to_string.c 11 http/response/to_string.c
13 -HEADER = http/header.c http/header/get.c http/header/sort.c \ 12 +HEADER = http/header.c http/header/get.c http/header/add.c http/header/sort.c \
14 http/header/size_get.c http/header/to_string.c 13 http/header/size_get.c http/header/to_string.c
15 PARSER = http/request/parser.c http/request/parser/get_header.c \ 14 PARSER = http/request/parser.c http/request/parser/get_header.c \
16 - http/request/parser/parse.c http/request/parser/get_request_line.c 15 + http/request/parser/parse.c http/request/parser/get_request_line.c \
  16 + http/request/parser/read.c
17 17
18 18
19 AM_CFLAGS = -Wall -I ../include/ 19 AM_CFLAGS = -Wall -I ../include/
  1 +#include <search.h>
1 #include <stdlib.h> 2 #include <stdlib.h>
2 #include <ctype.h> 3 #include <ctype.h>
3 4
@@ -20,20 +21,18 @@ sdbm(const unsigned char * str) @@ -20,20 +21,18 @@ sdbm(const unsigned char * str)
20 static 21 static
21 inline 22 inline
22 int 23 int
23 -comp (const void * _a, const void * _b) 24 +comp(const void * _a, const void * _b)
24 { 25 {
25 - unsigned long a = *(unsigned long *)_a;  
26 - const HttpHeader b = *(const HttpHeader *)_b;  
27 - return (a < b->hash)? -1 : (a > b->hash)? 1 : 0; 26 + HttpHeader a = (HttpHeader)_a;
  27 + HttpHeader b = (HttpHeader)_b;
  28 + return (a->hash < b->hash)? -1 : (a->hash > b->hash)? 1 : 0;
28 } 29 }
29 30
30 char * 31 char *
31 -httpHeaderGet(const HttpHeader header[], int nheader, const char * name) 32 +httpHeaderGet(const HttpHeader * root, const char * name)
32 { 33 {
33 - unsigned long hash = sdbm((unsigned char *)name);  
34 - HttpHeader * found;  
35 -  
36 - found = bsearch(&hash, header, nheader, sizeof(HttpHeader), comp); 34 + struct c_HttpHeader search = {sdbm((const unsigned char*)name), NULL, NULL};
  35 + HttpHeader * found = tfind(&search, (void**)root, comp);
37 36
38 return (NULL != found)? (*found)->value : NULL; 37 return (NULL != found)? (*found)->value : NULL;
39 } 38 }
@@ -11,7 +11,7 @@ httpRequestHasKeepAlive(HttpRequest request) @@ -11,7 +11,7 @@ httpRequestHasKeepAlive(HttpRequest request)
11 char * header; 11 char * header;
12 char * header_ptr; 12 char * header_ptr;
13 13
14 - header = XhttpHeaderGet(&(request->header), "connection"); 14 + header = httpHeaderGet(&(request->header), "connection");
15 15
16 if (NULL == header) { 16 if (NULL == header) {
17 return 0; 17 return 0;
1 -#include <stdlib.h>  
2 -#include <ctype.h>  
3 -  
4 -#include "http/request.h"  
5 -  
6 -char *  
7 -httpRequestHeaderGet(HttpRequest this, const char * name)  
8 -{  
9 - return XhttpHeaderGet(&(this->header), name);  
10 -}  
11 -  
12 -// vim: set ts=4 sw=4:  
@@ -56,47 +56,9 @@ _clone(void * _this, void * _base) @@ -56,47 +56,9 @@ _clone(void * _this, void * _base)
56 memcpy(this->buffer, base->buffer, this->buffer_used); 56 memcpy(this->buffer, base->buffer, this->buffer_used);
57 } 57 }
58 58
59 -static  
60 -size_t  
61 -get_data(void * _this, int fd)  
62 -{  
63 - HttpRequestParser this = _this;  
64 - size_t remaining, chunks;  
65 - char buffer[1024];  
66 -  
67 - ssize_t size = read(fd, buffer, 1024);  
68 -  
69 - if (0 < size) {  
70 - remaining = this->buffer_used % HTTP_REQUEST_PARSER_READ_CHUNK;  
71 - chunks = this->buffer_used / HTTP_REQUEST_PARSER_READ_CHUNK;  
72 -  
73 - /**  
74 - * because a division always rounds down  
75 - * chunks holds exactly the currently allocated chunks if  
76 - * remaining equals 0 but there is no space left.  
77 - * Else chunks holds the actually allocated amount of chunks  
78 - * minus 1.  
79 - * For this reason chunks always has to be increased by 1.  
80 - */  
81 - chunks++;  
82 -  
83 - if (size >= remaining) {  
84 - this->buffer =  
85 - realloc(this->buffer, chunks * HTTP_REQUEST_PARSER_READ_CHUNK);  
86 - }  
87 -  
88 - memcpy(this->buffer + this->buffer_used, buffer, size);  
89 - this->buffer_used += size;  
90 - this->buffer[this->buffer_used] = 0;  
91 -  
92 - httpRequestParserParse(this);  
93 - }  
94 -  
95 - return size;  
96 -}  
97 -  
98 INIT_IFACE(Class, ctor, dtor, _clone); 59 INIT_IFACE(Class, ctor, dtor, _clone);
99 -INIT_IFACE(StreamReader, get_data); 60 +INIT_IFACE(StreamReader,
  61 + (fptr_streamReaderRead)httpRequestParserRead);
100 CREATE_CLASS(HttpRequestParser, NULL, IFACE(Class), IFACE(StreamReader)); 62 CREATE_CLASS(HttpRequestParser, NULL, IFACE(Class), IFACE(StreamReader));
101 63
102 // vim: set ts=4 sw=4: 64 // vim: set ts=4 sw=4:
@@ -7,30 +7,6 @@ @@ -7,30 +7,6 @@
7 #include "http/header.h" 7 #include "http/header.h"
8 #include "http/request.h" 8 #include "http/request.h"
9 9
10 -static  
11 -inline  
12 -unsigned long  
13 -sdbm(const unsigned char * str)  
14 -{  
15 - unsigned long hash = 0;  
16 - int c;  
17 -  
18 - while ((c = tolower(*str++)))  
19 - hash = c + (hash << 6) + (hash << 16) - hash;  
20 -  
21 - return hash;  
22 -}  
23 -  
24 -static  
25 -inline  
26 -int  
27 -comp(const void * _a, const void * _b)  
28 -{  
29 - HttpHeader a = (HttpHeader)_a;  
30 - HttpHeader b = (HttpHeader)_b;  
31 - return (a->hash < b->hash)? -1 : (a->hash > b->hash)? 1 : 0;  
32 -}  
33 -  
34 void 10 void
35 httpRequestParserGetHeader(HttpRequest request, char * line) 11 httpRequestParserGetHeader(HttpRequest request, char * line)
36 { 12 {
@@ -43,26 +19,4 @@ httpRequestParserGetHeader(HttpRequest request, char * line) @@ -43,26 +19,4 @@ httpRequestParserGetHeader(HttpRequest request, char * line)
43 httpHeaderAdd(&(request->header), new(HttpHeader, name, value)); 19 httpHeaderAdd(&(request->header), new(HttpHeader, name, value));
44 } 20 }
45 21
46 -void  
47 -httpHeaderAdd(HttpHeader * root, HttpHeader header)  
48 -{  
49 - HttpHeader * found = tsearch(header, (void **)root, comp);  
50 -  
51 - if (*found != header) {  
52 - puts("uhh, duplicate header set. "  
53 - "This is not implemented right now. "  
54 - "Keep the first one found.");  
55 - delete(&header);  
56 - }  
57 -}  
58 -  
59 -char *  
60 -XhttpHeaderGet(HttpHeader * root, const char * name)  
61 -{  
62 - struct c_HttpHeader search = {sdbm((const unsigned char*)name), NULL, NULL};  
63 - HttpHeader * found = tfind(&search, (void **)root, comp);  
64 -  
65 - return (NULL != found)? (*found)->value : NULL;  
66 -}  
67 -  
68 // vim: set ts=4 sw=4: 22 // vim: set ts=4 sw=4:
@@ -37,9 +37,6 @@ httpRequestSkip(char ** data) @@ -37,9 +37,6 @@ httpRequestSkip(char ** data)
37 for (; 0 != **data && ! isalpha(**data); (*data)++); 37 for (; 0 != **data && ! isalpha(**data); (*data)++);
38 } 38 }
39 39
40 -void httpRequestParserGetRequestLine(HttpRequest, char *);  
41 -void httpRequestParserGetHeader(HttpRequest, char *);  
42 -  
43 void 40 void
44 httpRequestParserParse(HttpRequestParser this) 41 httpRequestParserParse(HttpRequestParser this)
45 { 42 {
@@ -86,7 +83,7 @@ httpRequestParserParse(HttpRequestParser this) @@ -86,7 +83,7 @@ httpRequestParserParse(HttpRequestParser this)
86 char * nbody; 83 char * nbody;
87 84
88 if (0 == this->cur_request->nbody) { 85 if (0 == this->cur_request->nbody) {
89 - nbody = XhttpHeaderGet( 86 + nbody = httpHeaderGet(
90 &(this->cur_request->header), 87 &(this->cur_request->header),
91 "Content-Length"); 88 "Content-Length");
92 89
  1 +#ifndef _GNU_SOURCE
  2 +#define _GNU_SOURCE
  3 +#endif
  4 +
  5 +#include <search.h>
1 #include <stdlib.h> 6 #include <stdlib.h>
2 #include <stdarg.h> 7 #include <stdarg.h>
3 8
@@ -37,19 +42,23 @@ ctor(void * _this, va_list * params) @@ -37,19 +42,23 @@ ctor(void * _this, va_list * params)
37 } 42 }
38 43
39 static 44 static
  45 +inline
  46 +void
  47 +tDelete(void * node)
  48 +{
  49 + delete(&node);
  50 +}
  51 +
  52 +static
40 void 53 void
41 dtor(void * _this) 54 dtor(void * _this)
42 { 55 {
43 HttpResponse this = _this; 56 HttpResponse this = _this;
44 - int i;  
45 57
46 _free((void **)&(this->version)); 58 _free((void **)&(this->version));
47 _free((void **)&(this->reason)); 59 _free((void **)&(this->reason));
48 60
49 - for (i=0; i<128; i++) {  
50 - if (NULL == (this->header)[i]) break;  
51 - delete(&(this->header)[i]);  
52 - } 61 + tdestroy(this->header, tDelete);
53 62
54 _free((void **)&(this->body)); 63 _free((void **)&(this->body));
55 } 64 }
@@ -7,6 +7,7 @@ @@ -7,6 +7,7 @@
7 #include "interface/class.h" 7 #include "interface/class.h"
8 8
9 #include "http/response.h" 9 #include "http/response.h"
  10 +#include "http/header.h"
10 11
11 12
12 #define RESP_DATA "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" \ 13 #define RESP_DATA "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" \
@@ -28,20 +29,24 @@ httpResponse404() @@ -28,20 +29,24 @@ httpResponse404()
28 29
29 response = new(HttpResponse, "HTTP/1.1", 404, "Not Found"); 30 response = new(HttpResponse, "HTTP/1.1", 404, "Not Found");
30 31
31 - httpResponseHeaderSet(response, "Content-Type", "text/html");  
32 - httpResponseHeaderSet(response, "Server", "testserver"); 32 + httpHeaderAdd(&(response->header),
  33 + new(HttpHeader, "Content-Type", "text/html"));
  34 + httpHeaderAdd(&(response->header),
  35 + new(HttpHeader, "Server", "testserver"));
33 36
34 response->nbody = sizeof(RESP_DATA) - 1; 37 response->nbody = sizeof(RESP_DATA) - 1;
35 response->body = calloc(1, sizeof(RESP_DATA)); 38 response->body = calloc(1, sizeof(RESP_DATA));
36 strcpy(response->body, RESP_DATA); 39 strcpy(response->body, RESP_DATA);
37 40
38 sprintf(buffer, "%d", response->nbody); 41 sprintf(buffer, "%d", response->nbody);
39 - httpResponseHeaderSet(response, "Content-Length", buffer); 42 + httpHeaderAdd(&(response->header),
  43 + new(HttpHeader, "Content-Length", buffer));
40 44
41 t = time(NULL); 45 t = time(NULL);
42 tmp = localtime(&t); 46 tmp = localtime(&t);
43 strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp); 47 strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp);
44 - httpResponseHeaderSet(response, "Date", buffer); 48 + httpHeaderAdd(&(response->header),
  49 + new(HttpHeader, "Date", buffer));
45 50
46 return response; 51 return response;
47 } 52 }
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 <search.h>
1 #include <string.h> 2 #include <string.h>
2 #include <sys/types.h> 3 #include <sys/types.h>
3 4
4 #include "http/response.h" 5 #include "http/response.h"
5 #include "http/header.h" 6 #include "http/header.h"
6 7
  8 +static size_t size;
  9 +
  10 +static
  11 +inline
  12 +void
  13 +addHeaderSize(const void * node, const VISIT which, const int depth)
  14 +{
  15 + if (endorder == which || leaf == which) {
  16 + size += httpHeaderSizeGet(*(HttpHeader *)node) + 2;
  17 + }
  18 +}
  19 +
7 size_t 20 size_t
8 httpResponseSizeGet(HttpResponse response) 21 httpResponseSizeGet(HttpResponse response)
9 { 22 {
10 - int i;  
11 - size_t size = 0; 23 + size = 0;
12 24
13 size += strlen(response->version) + 1; 25 size += strlen(response->version) + 1;
14 size += 4; // for status 26 size += 4; // for status
15 size += strlen(response->reason) + 2; 27 size += strlen(response->reason) + 2;
16 28
17 - for (i=0; i<response->nheader; i++) {  
18 - size += httpHeaderSizeGet(response->header[i]) + 2;  
19 - } 29 + twalk(response->header, addHeaderSize);
20 30
21 size += 2; 31 size += 2;
22 size += response->nbody; 32 size += response->nbody;
  1 +#include <search.h>
1 #include <string.h> 2 #include <string.h>
2 #include <stdio.h> 3 #include <stdio.h>
3 4
4 #include "http/response.h" 5 #include "http/response.h"
5 #include "http/header.h" 6 #include "http/header.h"
6 7
7 -size_t  
8 -httpResponseToString(HttpResponse response, char * string) 8 +static char * string;
  9 +
  10 +void
  11 +addHeaderString(const void * node, const VISIT which, const int depth)
  12 +{
  13 + if (endorder == which || leaf == which) {
  14 + string += httpHeaderToString(*(HttpHeader *)node, string);
  15 + *string++ = '\r';
  16 + *string++ = '\n';
  17 + }
  18 +}
  19 +
  20 +char *
  21 +httpResponseToString(HttpResponse response, char * _string)
9 { 22 {
10 - int i;  
11 - size_t size = httpResponseSizeGet(response);  
12 char status[4]; 23 char status[4];
13 24
  25 + string = _string;
  26 +
14 snprintf(status, 4, "%d", response->status); 27 snprintf(status, 4, "%d", response->status);
15 28
16 strcpy(string, response->version); 29 strcpy(string, response->version);
@@ -29,18 +42,14 @@ httpResponseToString(HttpResponse response, char * string) @@ -29,18 +42,14 @@ httpResponseToString(HttpResponse response, char * string)
29 *string++ = '\r'; 42 *string++ = '\r';
30 *string++ = '\n'; 43 *string++ = '\n';
31 44
32 - for (i=0; i<response->nheader; i++) {  
33 - string += httpHeaderToString(response->header[i], string);  
34 - *string++ = '\r';  
35 - *string++ = '\n';  
36 - } 45 + twalk(response->header, addHeaderString);
37 46
38 *string++ = '\r'; 47 *string++ = '\r';
39 *string++ = '\n'; 48 *string++ = '\n';
40 49
41 memcpy(string, response->body, response->nbody); 50 memcpy(string, response->body, response->nbody);
42 51
43 - return size; 52 + return string;
44 } 53 }
45 54
46 // vim: set ts=4 sw=4: 55 // vim: set ts=4 sw=4:
@@ -116,17 +116,15 @@ serverRun(Server this) @@ -116,17 +116,15 @@ serverRun(Server this)
116 116
117 if (httpRequestHasKeepAlive(queue->requests[j])) { 117 if (httpRequestHasKeepAlive(queue->requests[j])) {
118 (this->conns)[fd].keep_alive = 1; 118 (this->conns)[fd].keep_alive = 1;
119 - httpResponseHeaderSet(  
120 - response,  
121 - "Connection",  
122 - "Keep-Alive"); 119 + httpHeaderAdd(
  120 + &(response->header),
  121 + new(HttpHeader, "Connection", "Keep-Alive"));
123 } 122 }
124 else { 123 else {
125 (this->conns)[fd].keep_alive = 0; 124 (this->conns)[fd].keep_alive = 0;
126 - httpResponseHeaderSet(  
127 - response,  
128 - "Connection",  
129 - "Close"); 125 + httpHeaderAdd(
  126 + &(response->header),
  127 + new(HttpHeader, "Connection", "Close"));
130 } 128 }
131 129
132 delete(&(queue->requests[j])); 130 delete(&(queue->requests[j]));
Please register or login to post a comment