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 | 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 | 28 | #endif // __HTTP_MESSAGE__ |
| 27 | 29 | ... | ... |
| ... | ... | @@ -15,10 +15,10 @@ CLASS(HttpResponse) { |
| 15 | 15 | }; |
| 16 | 16 | |
| 17 | 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 | 23 | #endif /* __HTTP_RESPONSE_H__ */ |
| 24 | 24 | ... | ... |
| ... | ... | @@ -6,8 +6,8 @@ |
| 6 | 6 | #include "http/message/queue.h" |
| 7 | 7 | |
| 8 | 8 | typedef enum e_HttpResponseState { |
| 9 | - HTTP_RESPONSE_NO=0, | |
| 10 | - HTTP_RESPONSE_START, | |
| 9 | + HTTP_RESPONSE_GET=0, | |
| 10 | + HTTP_RESPONSE_HEADER, | |
| 11 | 11 | HTTP_RESPONSE_PIPE, |
| 12 | 12 | HTTP_RESPONSE_DONE |
| 13 | 13 | } HttpResponseState; |
| ... | ... | @@ -17,9 +17,9 @@ CLASS(HttpResponseWriter) { |
| 17 | 17 | char pipe[1024]; |
| 18 | 18 | |
| 19 | 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 | 24 | HttpMessageQueue response_queue; |
| 25 | 25 | HttpResponse cur_response; | ... | ... |
| ... | ... | @@ -2,15 +2,18 @@ ACLOCAL_AMFLAGS = -I m4 |
| 2 | 2 | AUTOMAKE_OPTIONS = subdir-objects |
| 3 | 3 | |
| 4 | 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 | 6 | CLASS = class.c interface.c |
| 7 | 7 | SOCKET = socket.c socket/accept.c socket/connect.c socket/listen.c |
| 8 | 8 | SERVER = server.c server/run.c server/close_conn.c |
| 9 | 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 | 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 | 17 | WRITER = http/response/writer.c http/response/writer/write.c |
| 15 | 18 | HEADER = http/header.c http/header/get.c http/header/add.c \ |
| 16 | 19 | http/header/size_get.c http/header/to_string.c | ... | ... |
| ... | ... | @@ -5,6 +5,7 @@ |
| 5 | 5 | #include "http/message.h" |
| 6 | 6 | #include "http/response.h" |
| 7 | 7 | #include "http/header.h" |
| 8 | +#include "interface/http_intro.h" | |
| 8 | 9 | |
| 9 | 10 | static size_t size; |
| 10 | 11 | |
| ... | ... | @@ -19,24 +20,13 @@ addHeaderSize(const void * node, const VISIT which, const int depth) |
| 19 | 20 | } |
| 20 | 21 | |
| 21 | 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 | 27 | twalk(message->header, addHeaderSize); |
| 33 | - | |
| 34 | 28 | size += 2; |
| 35 | 29 | |
| 36 | - if (HTTP_MESSAGE_BUFFERED == message->type) { | |
| 37 | - size += message->nbody; | |
| 38 | - } | |
| 39 | - | |
| 40 | 30 | return size; |
| 41 | 31 | } |
| 42 | 32 | ... | ... |
| ... | ... | @@ -4,6 +4,7 @@ |
| 4 | 4 | |
| 5 | 5 | #include "http/response.h" |
| 6 | 6 | #include "http/header.h" |
| 7 | +#include "interface/http_intro.h" | |
| 7 | 8 | |
| 8 | 9 | static char * string; |
| 9 | 10 | |
| ... | ... | @@ -18,40 +19,17 @@ addHeaderString(const void * node, const VISIT which, const int depth) |
| 18 | 19 | } |
| 19 | 20 | |
| 20 | 21 | char * |
| 21 | -httpResponseToString(HttpResponse response, char * _string) | |
| 22 | +httpMessageHeaderToString(HttpMessage response, char * _string) | |
| 22 | 23 | { |
| 23 | 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 | 28 | twalk(message->header, addHeaderString); |
| 47 | 29 | |
| 48 | 30 | *string++ = '\r'; |
| 49 | 31 | *string++ = '\n'; |
| 50 | 32 | |
| 51 | - if (HTTP_MESSAGE_BUFFERED == message->type) { | |
| 52 | - memcpy(string, message->body, message->nbody); | |
| 53 | - } | |
| 54 | - | |
| 55 | 33 | return string; |
| 56 | 34 | } |
| 57 | 35 | ... | ... |
| 1 | 1 | #include <stdlib.h> |
| 2 | 2 | #include <stdarg.h> |
| 3 | +#include <string.h> | |
| 4 | +#include <sys/types.h> | |
| 3 | 5 | |
| 4 | 6 | #include "class.h" |
| 5 | 7 | #include "interface/class.h" |
| 8 | +#include "interface/http_intro.h" | |
| 6 | 9 | |
| 7 | 10 | #include "http/request.h" |
| 8 | 11 | #include "message/helper.c" |
| ... | ... | @@ -24,7 +27,47 @@ dtor(void * _this) |
| 24 | 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 | 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 | 73 | // vim: set ts=4 sw=4: | ... | ... |
| 1 | 1 | #include <stdlib.h> |
| 2 | 2 | #include <stdarg.h> |
| 3 | +#include <string.h> | |
| 4 | +#include <sys/types.h> | |
| 5 | +#include <stdio.h> | |
| 3 | 6 | |
| 4 | 7 | #include "class.h" |
| 5 | 8 | #include "interface/class.h" |
| 9 | +#include "interface/http_intro.h" | |
| 6 | 10 | |
| 7 | 11 | #include "http/response.h" |
| 8 | 12 | #include "message/helper.c" |
| ... | ... | @@ -35,7 +39,48 @@ dtor(void * _this) |
| 35 | 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 | 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 | 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 | 8 | |
| 9 | 9 | #include "class.h" |
| 10 | 10 | #include "interface/class.h" |
| 11 | +#include "http/message.h" | |
| 11 | 12 | #include "http/response.h" |
| 12 | 13 | #include "http/response/writer.h" |
| 13 | 14 | |
| ... | ... | @@ -15,98 +16,124 @@ HttpResponse |
| 15 | 16 | httpResponseWriterWrite(HttpResponseWriter this, int fd) |
| 16 | 17 | { |
| 17 | 18 | HttpMessageQueue respq = this->response_queue; |
| 19 | + HttpResponse retval = this->cur_response; | |
| 20 | + HttpMessage message = (HttpMessage)this->cur_response; | |
| 18 | 21 | int cont = 1; |
| 19 | - HttpResponse retval = NULL; | |
| 20 | 22 | |
| 21 | 23 | while (cont) { |
| 22 | 24 | switch (this->state) { |
| 23 | - case HTTP_RESPONSE_NO: | |
| 25 | + case HTTP_RESPONSE_GET: | |
| 24 | 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 | 30 | memmove(respq->msgs, |
| 27 | 31 | &(respq->msgs[1]), |
| 28 | 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 | 42 | else { |
| 32 | 43 | cont = 0; |
| 33 | 44 | } |
| 34 | 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 | 66 | break; |
| 56 | 67 | |
| 57 | 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 | 132 | break; |
| 106 | 133 | |
| 107 | 134 | case HTTP_RESPONSE_DONE: |
| 108 | - this->state = HTTP_RESPONSE_NO; | |
| 109 | 135 | this->cur_response = NULL; |
| 136 | + this->state = HTTP_RESPONSE_GET; | |
| 110 | 137 | cont = 0; |
| 111 | 138 | |
| 112 | 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 | 122 | |
| 123 | 123 | if (0 == strcmp("GET", request->method) && |
| 124 | 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 | 127 | else if (0 == strcmp("GET", request->method) && |
| 161 | 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 | 131 | else { |
| 183 | 132 | response = (HttpMessage)httpResponse404(); |
| ... | ... | @@ -217,25 +166,17 @@ serverRun(Server this) |
| 217 | 166 | events--; |
| 218 | 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