Commit 1b7ef5030d9170bb1541f4e1f5ae30dde13c943f
1 parent
c8461176
better response handling but still buggy with stream piping
Showing
13 changed files
with
353 additions
and
185 deletions
@@ -21,7 +21,9 @@ CLASS(HttpMessage) { | @@ -21,7 +21,9 @@ CLASS(HttpMessage) { | ||
21 | int nbody; | 21 | int nbody; |
22 | }; | 22 | }; |
23 | 23 | ||
24 | -char httpMessageHasKeepAlive(HttpMessage); | 24 | +char httpMessageHasKeepAlive(HttpMessage); |
25 | +size_t httpMessageHeaderSizeGet(HttpMessage); | ||
26 | +char * httpMessageHeaderToString(HttpMessage, char *); | ||
25 | 27 | ||
26 | #endif // __HTTP_MESSAGE__ | 28 | #endif // __HTTP_MESSAGE__ |
27 | 29 |
@@ -15,10 +15,10 @@ CLASS(HttpResponse) { | @@ -15,10 +15,10 @@ CLASS(HttpResponse) { | ||
15 | }; | 15 | }; |
16 | 16 | ||
17 | HttpResponse httpResponse404(); | 17 | HttpResponse httpResponse404(); |
18 | +HttpResponse httpResponseMe(); | ||
19 | +HttpResponse httpResponseImage(); | ||
18 | 20 | ||
19 | -void httpResponseHeaderSet(HttpResponse, const char *, const char *); | ||
20 | -size_t httpResponseSizeGet(HttpResponse); | ||
21 | -char * httpResponseToString(HttpResponse, char *); | 21 | +//void httpResponseHeaderSet(HttpResponse, const char *, const char *); |
22 | 22 | ||
23 | #endif /* __HTTP_RESPONSE_H__ */ | 23 | #endif /* __HTTP_RESPONSE_H__ */ |
24 | 24 |
@@ -6,8 +6,8 @@ | @@ -6,8 +6,8 @@ | ||
6 | #include "http/message/queue.h" | 6 | #include "http/message/queue.h" |
7 | 7 | ||
8 | typedef enum e_HttpResponseState { | 8 | typedef enum e_HttpResponseState { |
9 | - HTTP_RESPONSE_NO=0, | ||
10 | - HTTP_RESPONSE_START, | 9 | + HTTP_RESPONSE_GET=0, |
10 | + HTTP_RESPONSE_HEADER, | ||
11 | HTTP_RESPONSE_PIPE, | 11 | HTTP_RESPONSE_PIPE, |
12 | HTTP_RESPONSE_DONE | 12 | HTTP_RESPONSE_DONE |
13 | } HttpResponseState; | 13 | } HttpResponseState; |
@@ -17,9 +17,9 @@ CLASS(HttpResponseWriter) { | @@ -17,9 +17,9 @@ CLASS(HttpResponseWriter) { | ||
17 | char pipe[1024]; | 17 | char pipe[1024]; |
18 | 18 | ||
19 | size_t nbuffer; | 19 | size_t nbuffer; |
20 | - size_t rpipe; | ||
21 | - size_t wpipe; | ||
22 | - char pipe_flip; | 20 | + size_t written; |
21 | + size_t pstart; | ||
22 | + size_t pend; | ||
23 | 23 | ||
24 | HttpMessageQueue response_queue; | 24 | HttpMessageQueue response_queue; |
25 | HttpResponse cur_response; | 25 | HttpResponse cur_response; |
@@ -2,15 +2,18 @@ ACLOCAL_AMFLAGS = -I m4 | @@ -2,15 +2,18 @@ ACLOCAL_AMFLAGS = -I m4 | ||
2 | AUTOMAKE_OPTIONS = subdir-objects | 2 | AUTOMAKE_OPTIONS = subdir-objects |
3 | 3 | ||
4 | IFACE = interface/class.c interface/stream_reader.c interface/logger.c \ | 4 | IFACE = interface/class.c interface/stream_reader.c interface/logger.c \ |
5 | - interface/stream_writer.c | 5 | + interface/stream_writer.c interface/http_intro.c |
6 | CLASS = class.c interface.c | 6 | CLASS = class.c interface.c |
7 | SOCKET = socket.c socket/accept.c socket/connect.c socket/listen.c | 7 | SOCKET = socket.c socket/accept.c socket/connect.c socket/listen.c |
8 | SERVER = server.c server/run.c server/close_conn.c | 8 | SERVER = server.c server/run.c server/close_conn.c |
9 | LOGGER = logger.c logger/stderr.c logger/syslog.c | 9 | LOGGER = logger.c logger/stderr.c logger/syslog.c |
10 | -MSG = http/message.c http/message/queue.c http/message/has_keep_alive.c | 10 | +MSG = http/message.c http/message/queue.c http/message/has_keep_alive.c \ |
11 | + http/message/header_size_get.c http/message/header_to_string.c | ||
11 | REQ = http/request.c | 12 | REQ = http/request.c |
12 | -RESP = http/response.c http/response/404.c http/response/size_get.c \ | ||
13 | - http/response/to_string.c | 13 | +RESP = http/response.c \ |
14 | + http/response/404.c \ | ||
15 | + http/response/image.c \ | ||
16 | + http/response/me.c | ||
14 | WRITER = http/response/writer.c http/response/writer/write.c | 17 | WRITER = http/response/writer.c http/response/writer/write.c |
15 | HEADER = http/header.c http/header/get.c http/header/add.c \ | 18 | HEADER = http/header.c http/header/get.c http/header/add.c \ |
16 | http/header/size_get.c http/header/to_string.c | 19 | http/header/size_get.c http/header/to_string.c |
@@ -5,6 +5,7 @@ | @@ -5,6 +5,7 @@ | ||
5 | #include "http/message.h" | 5 | #include "http/message.h" |
6 | #include "http/response.h" | 6 | #include "http/response.h" |
7 | #include "http/header.h" | 7 | #include "http/header.h" |
8 | +#include "interface/http_intro.h" | ||
8 | 9 | ||
9 | static size_t size; | 10 | static size_t size; |
10 | 11 | ||
@@ -19,24 +20,13 @@ addHeaderSize(const void * node, const VISIT which, const int depth) | @@ -19,24 +20,13 @@ addHeaderSize(const void * node, const VISIT which, const int depth) | ||
19 | } | 20 | } |
20 | 21 | ||
21 | size_t | 22 | size_t |
22 | -httpResponseSizeGet(HttpResponse response) | 23 | +httpMessageHeaderSizeGet(HttpMessage message) |
23 | { | 24 | { |
24 | - HttpMessage message = (HttpMessage)response; | ||
25 | - | ||
26 | - size = 0; | ||
27 | - | ||
28 | - size += strlen(message->version) + 1; | ||
29 | - size += 4; // for status | ||
30 | - size += strlen(response->reason) + 2; | 25 | + size = httpIntroSizeGet(message); |
31 | 26 | ||
32 | twalk(message->header, addHeaderSize); | 27 | twalk(message->header, addHeaderSize); |
33 | - | ||
34 | size += 2; | 28 | size += 2; |
35 | 29 | ||
36 | - if (HTTP_MESSAGE_BUFFERED == message->type) { | ||
37 | - size += message->nbody; | ||
38 | - } | ||
39 | - | ||
40 | return size; | 30 | return size; |
41 | } | 31 | } |
42 | 32 |
@@ -4,6 +4,7 @@ | @@ -4,6 +4,7 @@ | ||
4 | 4 | ||
5 | #include "http/response.h" | 5 | #include "http/response.h" |
6 | #include "http/header.h" | 6 | #include "http/header.h" |
7 | +#include "interface/http_intro.h" | ||
7 | 8 | ||
8 | static char * string; | 9 | static char * string; |
9 | 10 | ||
@@ -18,40 +19,17 @@ addHeaderString(const void * node, const VISIT which, const int depth) | @@ -18,40 +19,17 @@ addHeaderString(const void * node, const VISIT which, const int depth) | ||
18 | } | 19 | } |
19 | 20 | ||
20 | char * | 21 | char * |
21 | -httpResponseToString(HttpResponse response, char * _string) | 22 | +httpMessageHeaderToString(HttpMessage response, char * _string) |
22 | { | 23 | { |
23 | HttpMessage message = (HttpMessage)response; | 24 | HttpMessage message = (HttpMessage)response; |
24 | - char status[4]; | ||
25 | 25 | ||
26 | - string = _string; | ||
27 | - | ||
28 | - snprintf(status, 4, "%d", response->status); | ||
29 | - | ||
30 | - strcpy(string, message->version); | ||
31 | - string += strlen(string); | ||
32 | - | ||
33 | - *string++ = ' '; | ||
34 | - | ||
35 | - strcpy(string, status); | ||
36 | - string += strlen(string); | ||
37 | - | ||
38 | - *string++ = ' '; | ||
39 | - | ||
40 | - strcpy(string, response->reason); | ||
41 | - string += strlen(string); | ||
42 | - | ||
43 | - *string++ = '\r'; | ||
44 | - *string++ = '\n'; | 26 | + string = httpIntroToString(response, _string); |
45 | 27 | ||
46 | twalk(message->header, addHeaderString); | 28 | twalk(message->header, addHeaderString); |
47 | 29 | ||
48 | *string++ = '\r'; | 30 | *string++ = '\r'; |
49 | *string++ = '\n'; | 31 | *string++ = '\n'; |
50 | 32 | ||
51 | - if (HTTP_MESSAGE_BUFFERED == message->type) { | ||
52 | - memcpy(string, message->body, message->nbody); | ||
53 | - } | ||
54 | - | ||
55 | return string; | 33 | return string; |
56 | } | 34 | } |
57 | 35 |
1 | #include <stdlib.h> | 1 | #include <stdlib.h> |
2 | #include <stdarg.h> | 2 | #include <stdarg.h> |
3 | +#include <string.h> | ||
4 | +#include <sys/types.h> | ||
3 | 5 | ||
4 | #include "class.h" | 6 | #include "class.h" |
5 | #include "interface/class.h" | 7 | #include "interface/class.h" |
8 | +#include "interface/http_intro.h" | ||
6 | 9 | ||
7 | #include "http/request.h" | 10 | #include "http/request.h" |
8 | #include "message/helper.c" | 11 | #include "message/helper.c" |
@@ -24,7 +27,47 @@ dtor(void * _this) | @@ -24,7 +27,47 @@ dtor(void * _this) | ||
24 | PARENTCALL(_this, Class, dtor); | 27 | PARENTCALL(_this, Class, dtor); |
25 | } | 28 | } |
26 | 29 | ||
30 | +static | ||
31 | +size_t | ||
32 | +sizeGet(void * _this) | ||
33 | +{ | ||
34 | + HttpRequest this = _this; | ||
35 | + size_t size = 0; | ||
36 | + | ||
37 | + size += strlen(this->method) + 1; | ||
38 | + size += strlen(this->uri) + 1; | ||
39 | + size += strlen(((HttpMessage)this)->version) + 2; | ||
40 | + | ||
41 | + return size; | ||
42 | +} | ||
43 | + | ||
44 | +static | ||
45 | +char * | ||
46 | +toString(void * _this, char * string) | ||
47 | +{ | ||
48 | + HttpRequest this = _this; | ||
49 | + | ||
50 | + strcpy(string, this->method); | ||
51 | + string += strlen(string); | ||
52 | + *string++ = ' '; | ||
53 | + | ||
54 | + strcpy(string, this->uri); | ||
55 | + string += strlen(string); | ||
56 | + *string++ = ' '; | ||
57 | + | ||
58 | + strcpy(string, ((HttpMessage)this)->version); | ||
59 | + string += strlen(string); | ||
60 | + *string++ = '\r'; | ||
61 | + *string++ = '\n'; | ||
62 | + | ||
63 | + return string; | ||
64 | +} | ||
65 | + | ||
27 | INIT_IFACE(Class, ctor, dtor, NULL); | 66 | INIT_IFACE(Class, ctor, dtor, NULL); |
28 | -CREATE_CLASS(HttpRequest, HttpMessage, IFACE(Class)); | 67 | +INIT_IFACE(HttpIntro, sizeGet, toString); |
68 | +CREATE_CLASS(HttpRequest, | ||
69 | + HttpMessage, | ||
70 | + IFACE(Class), | ||
71 | + IFACE(HttpIntro)); | ||
29 | 72 | ||
30 | // vim: set ts=4 sw=4: | 73 | // vim: set ts=4 sw=4: |
1 | #include <stdlib.h> | 1 | #include <stdlib.h> |
2 | #include <stdarg.h> | 2 | #include <stdarg.h> |
3 | +#include <string.h> | ||
4 | +#include <sys/types.h> | ||
5 | +#include <stdio.h> | ||
3 | 6 | ||
4 | #include "class.h" | 7 | #include "class.h" |
5 | #include "interface/class.h" | 8 | #include "interface/class.h" |
9 | +#include "interface/http_intro.h" | ||
6 | 10 | ||
7 | #include "http/response.h" | 11 | #include "http/response.h" |
8 | #include "message/helper.c" | 12 | #include "message/helper.c" |
@@ -35,7 +39,48 @@ dtor(void * _this) | @@ -35,7 +39,48 @@ dtor(void * _this) | ||
35 | PARENTCALL(_this, Class, dtor); | 39 | PARENTCALL(_this, Class, dtor); |
36 | } | 40 | } |
37 | 41 | ||
42 | +static | ||
43 | +size_t | ||
44 | +sizeGet(void * _this) | ||
45 | +{ | ||
46 | + HttpResponse this = _this; | ||
47 | + size_t size = 0; | ||
48 | + | ||
49 | + size += strlen(((HttpMessage)this)->version) + 1; | ||
50 | + size += 3 + 1; // for status | ||
51 | + size += strlen(this->reason) + 2; | ||
52 | + | ||
53 | + return size; | ||
54 | +} | ||
55 | + | ||
56 | +static | ||
57 | +char * | ||
58 | +toString(void * _this, char * string) | ||
59 | +{ | ||
60 | + HttpResponse this = _this; | ||
61 | + | ||
62 | + strcpy(string, ((HttpMessage)this)->version); | ||
63 | + string += strlen(string); | ||
64 | + *string++ = ' '; | ||
65 | + | ||
66 | + snprintf(string, 4, "%d", this->status); | ||
67 | + string += strlen(string); | ||
68 | + *string++ = ' '; | ||
69 | + | ||
70 | + strcpy(string, this->reason); | ||
71 | + string += strlen(string); | ||
72 | + *string++ = '\r'; | ||
73 | + *string++ = '\n'; | ||
74 | + | ||
75 | + return string; | ||
76 | +} | ||
77 | + | ||
38 | INIT_IFACE(Class, ctor, dtor, NULL); | 78 | INIT_IFACE(Class, ctor, dtor, NULL); |
39 | -CREATE_CLASS(HttpResponse, HttpMessage, IFACE(Class)); | 79 | +INIT_IFACE(HttpIntro, sizeGet, toString); |
80 | +CREATE_CLASS( | ||
81 | + HttpResponse, | ||
82 | + HttpMessage, | ||
83 | + IFACE(Class), | ||
84 | + IFACE(HttpIntro)); | ||
40 | 85 | ||
41 | // vim: set ts=4 sw=4: | 86 | // vim: set ts=4 sw=4: |
src/http/response/image.c
0 → 100644
1 | +#include <stdlib.h> | ||
2 | +#include <string.h> | ||
3 | +#include <stdio.h> | ||
4 | +#include <time.h> | ||
5 | +#include <sys/stat.h> | ||
6 | +#include <fcntl.h> | ||
7 | + | ||
8 | +#include "class.h" | ||
9 | +#include "interface/class.h" | ||
10 | + | ||
11 | +#include "http/response.h" | ||
12 | +#include "http/message.h" | ||
13 | +#include "http/header.h" | ||
14 | + | ||
15 | + | ||
16 | +HttpResponse | ||
17 | +httpResponseImage() | ||
18 | +{ | ||
19 | + time_t t; | ||
20 | + struct tm * tmp; | ||
21 | + char buffer[200]; | ||
22 | + struct stat st; | ||
23 | + HttpResponse response; | ||
24 | + HttpMessage message; | ||
25 | + | ||
26 | + response = new(HttpResponse, "HTTP/1.1", 200, "OK"); | ||
27 | + message = (HttpMessage)response; | ||
28 | + | ||
29 | + httpHeaderAdd(&(message->header), | ||
30 | + new(HttpHeader, "Content-Type", "image/jpeg")); | ||
31 | + httpHeaderAdd(&(message->header), | ||
32 | + new(HttpHeader, "Server", "testserver")); | ||
33 | + | ||
34 | + message->type = HTTP_MESSAGE_PIPED; | ||
35 | + message->handle = open("./assets/waldschrat.jpg", O_RDONLY); | ||
36 | + fstat(message->handle, &st); | ||
37 | + message->nbody = st.st_size; | ||
38 | + | ||
39 | + sprintf(buffer, "%d", message->nbody); | ||
40 | + httpHeaderAdd(&(message->header), | ||
41 | + new(HttpHeader, "Content-Length", buffer)); | ||
42 | + | ||
43 | + t = time(NULL); | ||
44 | + tmp = localtime(&t); | ||
45 | + strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp); | ||
46 | + httpHeaderAdd(&(message->header), | ||
47 | + new(HttpHeader, "Date", buffer)); | ||
48 | + | ||
49 | + return response; | ||
50 | +} | ||
51 | + | ||
52 | +// vim: set ts=4 sw=4: |
src/http/response/me.c
0 → 100644
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 | +#include "http/message.h" | ||
11 | +#include "http/header.h" | ||
12 | + | ||
13 | + | ||
14 | +#define RESP_DATA "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" \ | ||
15 | + "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" \ | ||
16 | + " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" \ | ||
17 | + "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n" \ | ||
18 | + "<head><title>200 - OK</title></head>" \ | ||
19 | + "<body><h1>200 - OK</h1><img src=\"/image/\" /></body>" \ | ||
20 | + "</html>" | ||
21 | + | ||
22 | + | ||
23 | +HttpResponse | ||
24 | +httpResponseMe() | ||
25 | +{ | ||
26 | + time_t t; | ||
27 | + struct tm * tmp; | ||
28 | + char buffer[200]; | ||
29 | + HttpResponse response; | ||
30 | + HttpMessage message; | ||
31 | + | ||
32 | + response = new(HttpResponse, "HTTP/1.1", 200, "OK"); | ||
33 | + message = (HttpMessage)response; | ||
34 | + | ||
35 | + httpHeaderAdd(&(message->header), | ||
36 | + new(HttpHeader, "Content-Type", "text/html")); | ||
37 | + httpHeaderAdd(&(message->header), | ||
38 | + new(HttpHeader, "Server", "testserver")); | ||
39 | + | ||
40 | + message->type = HTTP_MESSAGE_BUFFERED; | ||
41 | + message->nbody = sizeof(RESP_DATA) - 1; | ||
42 | + message->body = calloc(1, sizeof(RESP_DATA)); | ||
43 | + strcpy(message->body, RESP_DATA); | ||
44 | + | ||
45 | + sprintf(buffer, "%d", message->nbody); | ||
46 | + httpHeaderAdd(&(message->header), | ||
47 | + new(HttpHeader, "Content-Length", buffer)); | ||
48 | + | ||
49 | + t = time(NULL); | ||
50 | + tmp = localtime(&t); | ||
51 | + strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp); | ||
52 | + httpHeaderAdd(&(message->header), | ||
53 | + new(HttpHeader, "Date", buffer)); | ||
54 | + | ||
55 | + return response; | ||
56 | +} | ||
57 | + | ||
58 | +// vim: set ts=4 sw=4: |
@@ -8,6 +8,7 @@ | @@ -8,6 +8,7 @@ | ||
8 | 8 | ||
9 | #include "class.h" | 9 | #include "class.h" |
10 | #include "interface/class.h" | 10 | #include "interface/class.h" |
11 | +#include "http/message.h" | ||
11 | #include "http/response.h" | 12 | #include "http/response.h" |
12 | #include "http/response/writer.h" | 13 | #include "http/response/writer.h" |
13 | 14 | ||
@@ -15,98 +16,124 @@ HttpResponse | @@ -15,98 +16,124 @@ HttpResponse | ||
15 | httpResponseWriterWrite(HttpResponseWriter this, int fd) | 16 | httpResponseWriterWrite(HttpResponseWriter this, int fd) |
16 | { | 17 | { |
17 | HttpMessageQueue respq = this->response_queue; | 18 | HttpMessageQueue respq = this->response_queue; |
19 | + HttpResponse retval = this->cur_response; | ||
20 | + HttpMessage message = (HttpMessage)this->cur_response; | ||
18 | int cont = 1; | 21 | int cont = 1; |
19 | - HttpResponse retval = NULL; | ||
20 | 22 | ||
21 | while (cont) { | 23 | while (cont) { |
22 | switch (this->state) { | 24 | switch (this->state) { |
23 | - case HTTP_RESPONSE_NO: | 25 | + case HTTP_RESPONSE_GET: |
24 | if (NULL == this->cur_response && 0 < respq->nmsgs) { | 26 | if (NULL == this->cur_response && 0 < respq->nmsgs) { |
25 | - retval = this->cur_response = (HttpResponse)respq->msgs[0]; | 27 | + message = respq->msgs[0]; |
28 | + retval = this->cur_response = (HttpResponse)message; | ||
29 | + | ||
26 | memmove(respq->msgs, | 30 | memmove(respq->msgs, |
27 | &(respq->msgs[1]), | 31 | &(respq->msgs[1]), |
28 | sizeof(void*) * (--respq->nmsgs + 1)); | 32 | sizeof(void*) * (--respq->nmsgs + 1)); |
29 | - this->state = HTTP_RESPONSE_START; | 33 | + |
34 | + this->nbuffer = httpMessageHeaderSizeGet(message); | ||
35 | + this->buffer = malloc(this->nbuffer); | ||
36 | + this->written = 0; | ||
37 | + | ||
38 | + httpMessageHeaderToString(message, this->buffer); | ||
39 | + | ||
40 | + this->state = HTTP_RESPONSE_HEADER; | ||
30 | } | 41 | } |
31 | else { | 42 | else { |
32 | cont = 0; | 43 | cont = 0; |
33 | } | 44 | } |
34 | break; | 45 | break; |
35 | 46 | ||
36 | - case HTTP_RESPONSE_START: | ||
37 | - if (HTTP_MESSAGE_PIPED == | ||
38 | - ((HttpMessage)(this->cur_response))->type) { | ||
39 | - struct stat st; | ||
40 | - HttpMessage message = (HttpMessage)this->cur_response; | ||
41 | - char buffer[200]; | ||
42 | - | ||
43 | - message->handle = | ||
44 | - open("./assets/waldschrat.jpg", O_RDONLY); | ||
45 | - fstat(message->handle, &st); | ||
46 | - message->nbody = st.st_size; | ||
47 | - | ||
48 | - sprintf(buffer, "%d", message->nbody); | ||
49 | - httpHeaderAdd(&(message->header), | ||
50 | - new(HttpHeader, "Content-Length", buffer)); | ||
51 | - | 47 | + case HTTP_RESPONSE_HEADER: |
48 | + this->written += write( | ||
49 | + fd, | ||
50 | + &(this->buffer[this->written]), | ||
51 | + this->nbuffer - this->written); | ||
52 | + | ||
53 | + if (this->written == this->nbuffer) { | ||
54 | + free(this->buffer); | ||
55 | + this->buffer = NULL; | ||
56 | + this->nbuffer = 0; | ||
57 | + this->written = 0; | ||
58 | + this->pstart = 0; | ||
59 | + this->pend = 0; | ||
60 | + | ||
61 | + this->state = HTTP_RESPONSE_PIPE; | ||
62 | + } | ||
63 | + else { | ||
64 | + cont = 0; | ||
52 | } | 65 | } |
53 | - | ||
54 | - this->state = HTTP_RESPONSE_PIPE; | ||
55 | break; | 66 | break; |
56 | 67 | ||
57 | case HTTP_RESPONSE_PIPE: | 68 | case HTTP_RESPONSE_PIPE: |
58 | - { | ||
59 | - HttpMessage message = (HttpMessage)(this->cur_response); | ||
60 | - size_t headsize = httpResponseSizeGet(this->cur_response); | 69 | + switch (message->type) { |
70 | + case HTTP_MESSAGE_BUFFERED: | ||
71 | + this->written += write( | ||
72 | + fd, | ||
73 | + &(message->body[this->written]), | ||
74 | + message->nbody - this->written); | ||
75 | + break; | ||
76 | + | ||
77 | + case HTTP_MESSAGE_PIPED: | ||
78 | + /** | ||
79 | + * read | ||
80 | + */ | ||
81 | + if (this->nbuffer < message->nbody) { | ||
82 | + size_t rsize; | ||
83 | + size_t temp; | ||
84 | + | ||
85 | + this->pend = (1024 == this->pend)? | ||
86 | + 0 : this->pend; | ||
87 | + | ||
88 | + rsize = (this->pstart <= this->pend)? | ||
89 | + 1024 - this->pend : this->pstart - 1; | ||
90 | + | ||
91 | + temp = read( | ||
92 | + message->handle, | ||
93 | + &(this->pipe[this->pend]), | ||
94 | + rsize); | ||
95 | + | ||
96 | + this->nbuffer += temp; | ||
97 | + this->pend += temp; | ||
98 | + } | ||
61 | 99 | ||
62 | - this->buffer = malloc(headsize + message->nbody); | ||
63 | - httpResponseToString(this->cur_response, this->buffer); | ||
64 | - this->rpipe = headsize; | 100 | + /** |
101 | + * write | ||
102 | + */ | ||
103 | + { | ||
104 | + size_t wsize; | ||
105 | + size_t temp; | ||
65 | 106 | ||
66 | - if (HTTP_MESSAGE_PIPED == message->type && | ||
67 | - 0 != message->handle) { | ||
68 | - char * data = &(this->buffer[headsize]); | ||
69 | - size_t togo = message->nbody; | 107 | + wsize = (this->pstart <= this->pend)? |
108 | + this->pend - this->pstart : 1024 - this->pstart; | ||
70 | 109 | ||
71 | - size_t rsize = read(message->handle, data, togo); | 110 | + temp = write(fd, &(this->pipe[this->pstart]), wsize); |
72 | 111 | ||
73 | - while (rsize < togo) { | ||
74 | - data += rsize; | ||
75 | - togo -= rsize; | ||
76 | - rsize = read(message->handle, data, togo); | 112 | + this->written += temp; |
113 | + this->pstart += temp; | ||
77 | } | 114 | } |
115 | + break; | ||
78 | 116 | ||
79 | - this->wpipe = 0; | ||
80 | - this->rpipe += message->nbody; | ||
81 | - close(message->handle); | ||
82 | - message->handle = 0; | ||
83 | - } | ||
84 | - | ||
85 | - { | ||
86 | - char * data = &(this->buffer[this->wpipe]); | ||
87 | - size_t written; | ||
88 | - | ||
89 | - written = write(fd, data, this->rpipe - this->wpipe); | ||
90 | - data += written; | ||
91 | - this->wpipe += written; | ||
92 | - | ||
93 | - if (this->rpipe == this->wpipe) { | ||
94 | - this->rpipe = 0; | ||
95 | - this->wpipe = 0; | ||
96 | - free (this->buffer); | ||
97 | - this->buffer = NULL; | ||
98 | - this->state = HTTP_RESPONSE_DONE; | ||
99 | - } | ||
100 | - else { | ||
101 | - cont = 0; | ||
102 | - } | ||
103 | - } | 117 | + default: |
118 | + break; | ||
119 | + } | ||
120 | + | ||
121 | + if (this->written == message->nbody) { | ||
122 | + this->nbuffer = 0; | ||
123 | + this->written = 0; | ||
124 | + this->pstart = 0; | ||
125 | + this->pend = 0; | ||
126 | + | ||
127 | + this->state = HTTP_RESPONSE_DONE; | ||
128 | + } | ||
129 | + else { | ||
130 | + cont = 0; | ||
104 | } | 131 | } |
105 | break; | 132 | break; |
106 | 133 | ||
107 | case HTTP_RESPONSE_DONE: | 134 | case HTTP_RESPONSE_DONE: |
108 | - this->state = HTTP_RESPONSE_NO; | ||
109 | this->cur_response = NULL; | 135 | this->cur_response = NULL; |
136 | + this->state = HTTP_RESPONSE_GET; | ||
110 | cont = 0; | 137 | cont = 0; |
111 | 138 | ||
112 | break; | 139 | break; |
src/interface/http_intro.c
0 → 100644
1 | +#include "class.h" | ||
2 | +#include "interface/http_intro.h" | ||
3 | + | ||
4 | +const struct interface i_HttpIntro = { | ||
5 | + "httpIntro", | ||
6 | + 2 | ||
7 | +}; | ||
8 | + | ||
9 | +size_t | ||
10 | +httpIntroSizeGet(void * object) | ||
11 | +{ | ||
12 | + size_t ret; | ||
13 | + | ||
14 | + RETCALL(object, HttpIntro, sizeGet, ret); | ||
15 | + | ||
16 | + return ret; | ||
17 | +} | ||
18 | + | ||
19 | +char * | ||
20 | +httpIntroToString(void * object, char * string) | ||
21 | +{ | ||
22 | + char * ret; | ||
23 | + | ||
24 | + RETCALL(object, HttpIntro, toString, ret, string); | ||
25 | + | ||
26 | + return ret; | ||
27 | +} | ||
28 | + | ||
29 | +// vim: set ts=4 sw=4: |
@@ -122,62 +122,11 @@ serverRun(Server this) | @@ -122,62 +122,11 @@ serverRun(Server this) | ||
122 | 122 | ||
123 | if (0 == strcmp("GET", request->method) && | 123 | if (0 == strcmp("GET", request->method) && |
124 | 0 == strcmp("/me/", request->uri)) { | 124 | 0 == strcmp("/me/", request->uri)) { |
125 | - const char foo[] = | ||
126 | - "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" | ||
127 | - "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" | ||
128 | - " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" | ||
129 | - "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n" | ||
130 | - "<head><title>200 - OK</title></head>" | ||
131 | - "<body><h1>200 - OK</h1>" | ||
132 | - "<img src=\"/image/\" /></body>" | ||
133 | - "</html>"; | ||
134 | - char buffer[200]; | ||
135 | - time_t t; | ||
136 | - struct tm * tmp; | ||
137 | - | ||
138 | - response = (HttpMessage)new(HttpResponse, "HTTP/1.1", 200, "OK"); | ||
139 | - | ||
140 | - httpHeaderAdd(&(response->header), | ||
141 | - new(HttpHeader, "Content-Type", "text/html")); | ||
142 | - httpHeaderAdd(&(response->header), | ||
143 | - new(HttpHeader, "Server", "testserver")); | ||
144 | - | ||
145 | - response->type = HTTP_MESSAGE_BUFFERED; | ||
146 | - response->nbody = sizeof(foo) - 1; | ||
147 | - response->body = calloc(1, sizeof(foo)); | ||
148 | - strcpy(response->body, foo); | ||
149 | - | ||
150 | - sprintf(buffer, "%d", response->nbody); | ||
151 | - httpHeaderAdd(&(response->header), | ||
152 | - new(HttpHeader, "Content-Length", buffer)); | ||
153 | - | ||
154 | - t = time(NULL); | ||
155 | - tmp = localtime(&t); | ||
156 | - strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp); | ||
157 | - httpHeaderAdd(&(response->header), | ||
158 | - new(HttpHeader, "Date", buffer)); | 125 | + response = (HttpMessage)httpResponseMe(); |
159 | } | 126 | } |
160 | else if (0 == strcmp("GET", request->method) && | 127 | else if (0 == strcmp("GET", request->method) && |
161 | 0 == strcmp("/image/", request->uri)) { | 128 | 0 == strcmp("/image/", request->uri)) { |
162 | - char buffer[200]; | ||
163 | - time_t t; | ||
164 | - struct tm * tmp; | ||
165 | - | ||
166 | - response = (HttpMessage)new( | ||
167 | - HttpResponse, "HTTP/1.1", 200, "OK"); | ||
168 | - | ||
169 | - httpHeaderAdd(&(response->header), | ||
170 | - new(HttpHeader, "Content-Type", "image/jpeg")); | ||
171 | - httpHeaderAdd(&(response->header), | ||
172 | - new(HttpHeader, "Server", "testserver")); | ||
173 | - | ||
174 | - response->type = HTTP_MESSAGE_PIPED; | ||
175 | - | ||
176 | - t = time(NULL); | ||
177 | - tmp = localtime(&t); | ||
178 | - strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp); | ||
179 | - httpHeaderAdd(&(response->header), | ||
180 | - new(HttpHeader, "Date", buffer)); | 129 | + response = (HttpMessage)httpResponseImage(); |
181 | } | 130 | } |
182 | else { | 131 | else { |
183 | response = (HttpMessage)httpResponse404(); | 132 | response = (HttpMessage)httpResponse404(); |
@@ -217,25 +166,17 @@ serverRun(Server this) | @@ -217,25 +166,17 @@ serverRun(Server this) | ||
217 | events--; | 166 | events--; |
218 | nwrites--; | 167 | nwrites--; |
219 | 168 | ||
220 | - message = (HttpMessage)streamWriterWrite(writer, fd); | 169 | + message = streamWriterWrite(writer, fd); |
221 | 170 | ||
222 | - while (NULL != message) { | ||
223 | - if (writer->state == HTTP_RESPONSE_NO) { | ||
224 | - if (httpMessageHasKeepAlive(message)) { | ||
225 | - delete(&message); | ||
226 | - if (0 == writer->response_queue->nmsgs) { | ||
227 | - (this->fds)[i].events &= ~POLLOUT; | ||
228 | - break; | ||
229 | - } | ||
230 | - } | ||
231 | - else { | ||
232 | - delete(&message); | ||
233 | - serverCloseConn(this, i); | ||
234 | - break; | ||
235 | - } | 171 | + if (NULL != message && writer->state == HTTP_RESPONSE_GET) { |
172 | + if (httpMessageHasKeepAlive(message)) { | ||
173 | + (this->fds)[i].events &= ~POLLOUT; | ||
174 | + } | ||
175 | + else { | ||
176 | + serverCloseConn(this, i); | ||
236 | } | 177 | } |
237 | 178 | ||
238 | - message = (HttpMessage)streamWriterWrite(writer, fd); | 179 | + delete(&message); |
239 | } | 180 | } |
240 | } | 181 | } |
241 | } | 182 | } |
Please
register
or
login
to post a comment