Browse Source
more generalizing of response writing (implemented a response writer...now it should be possible to implement a stream writer for images
master
more generalizing of response writing (implemented a response writer...now it should be possible to implement a stream writer for images
master
19 changed files with 270 additions and 106 deletions
-
17include/http/message/queue.h
-
4include/http/request/parser.h
-
17include/http/request/queue.h
-
34include/http/response/writer.h
-
19include/interface/stream_writer.h
-
19include/server.h
-
10src/Makefile.am
-
10src/http/message/queue.c
-
10src/http/request/parser.c
-
11src/http/request/parser/parse.c
-
1src/http/response.c
-
47src/http/response/writer.c
-
79src/http/response/writer/write.c
-
19src/interface/stream_writer.c
-
5src/server.c
-
5src/server/close_conn.c
-
3src/server/handle_accept.c
-
60src/server/run.c
-
6src/testserver.c
@ -0,0 +1,17 @@ |
|||||
|
#ifndef __HTTP_REQUEST_QUEUE_H__ |
||||
|
#define __HTTP_REQUEST_QUEUE_H__ |
||||
|
|
||||
|
#include "class.h" |
||||
|
#include "http/message.h" |
||||
|
|
||||
|
#define HTTP_MESSAGE_QUEUE_MAX 1024 |
||||
|
|
||||
|
|
||||
|
CLASS(HttpMessageQueue) { |
||||
|
HttpMessage msgs[HTTP_MESSAGE_QUEUE_MAX]; |
||||
|
size_t nmsgs; |
||||
|
}; |
||||
|
|
||||
|
#endif /* __HTTP_REQUEST_QUEUE_H__ */ |
||||
|
|
||||
|
// vim: set ts=4 sw=4: |
||||
@ -1,17 +0,0 @@ |
|||||
#ifndef __HTTP_REQUEST_QUEUE_H__ |
|
||||
#define __HTTP_REQUEST_QUEUE_H__ |
|
||||
|
|
||||
#include "class.h" |
|
||||
#include "http/request.h" |
|
||||
|
|
||||
#define HTTP_REQUEST_QUEUE_MAX 1024 |
|
||||
|
|
||||
|
|
||||
CLASS(HttpRequestQueue) { |
|
||||
HttpRequest requests[HTTP_REQUEST_QUEUE_MAX]; |
|
||||
size_t nrequests; |
|
||||
}; |
|
||||
|
|
||||
#endif /* __HTTP_REQUEST_QUEUE_H__ */ |
|
||||
|
|
||||
// vim: set ts=4 sw=4: |
|
||||
@ -0,0 +1,34 @@ |
|||||
|
#ifndef __HTTP_RESPONSE_WRITER_H__ |
||||
|
#define __HTTP_RESPONSE_WRITER_H__ |
||||
|
|
||||
|
#include "class.h" |
||||
|
#include "http/response.h" |
||||
|
#include "http/message/queue.h" |
||||
|
|
||||
|
typedef enum e_HttpResponseState { |
||||
|
HTTP_RESPONSE_NO=0, |
||||
|
HTTP_RESPONSE_START, |
||||
|
HTTP_RESPONSE_PIPE, |
||||
|
HTTP_RESPONSE_DONE |
||||
|
} HttpResponseState; |
||||
|
|
||||
|
CLASS(HttpResponseWriter) { |
||||
|
char * buffer; |
||||
|
char pipe[1024]; |
||||
|
|
||||
|
size_t nbuffer; |
||||
|
size_t rpipe; |
||||
|
size_t wpipe; |
||||
|
char pipe_flip; |
||||
|
|
||||
|
HttpMessageQueue response_queue; |
||||
|
HttpResponse cur_response; |
||||
|
|
||||
|
HttpResponseState state; |
||||
|
}; |
||||
|
|
||||
|
size_t httpResponseWriterWrite(HttpResponseWriter, int); |
||||
|
|
||||
|
#endif // __HTTP_RESPONSE_WRITER_H__ |
||||
|
|
||||
|
// vim: set ts=4 sw=4: |
||||
@ -0,0 +1,19 @@ |
|||||
|
#ifndef __STREAM_WRITER_H__ |
||||
|
#define __STREAM_WRITER_H__ |
||||
|
|
||||
|
#include <sys/types.h> |
||||
|
|
||||
|
typedef size_t (* fptr_streamWriterWrite)(void *, int fd); |
||||
|
|
||||
|
extern const struct interface i_StreamWriter; |
||||
|
|
||||
|
struct i_StreamWriter { |
||||
|
const struct interface * const _; |
||||
|
fptr_streamWriterWrite write; |
||||
|
}; |
||||
|
|
||||
|
extern size_t streamWriterWrite(void *, int fd); |
||||
|
|
||||
|
#endif // __STREAM_WRITER_H__ |
||||
|
|
||||
|
// vim: set ts=4 sw=4: |
||||
@ -0,0 +1,47 @@ |
|||||
|
#include <stdlib.h> |
||||
|
|
||||
|
#include "class.h" |
||||
|
#include "interface/class.h" |
||||
|
#include "interface/stream_writer.h" |
||||
|
|
||||
|
#include "http/message/queue.h" |
||||
|
#include "http/response/writer.h" |
||||
|
|
||||
|
static |
||||
|
void |
||||
|
ctor(void * _this, va_list * params) |
||||
|
{ |
||||
|
HttpResponseWriter this = _this; |
||||
|
|
||||
|
this->response_queue = new(HttpMessageQueue); |
||||
|
} |
||||
|
|
||||
|
static |
||||
|
void |
||||
|
dtor(void * _this) |
||||
|
{ |
||||
|
HttpResponseWriter this = _this; |
||||
|
|
||||
|
if (NULL != this->buffer) free(this->buffer); |
||||
|
delete(&(this->response_queue)); |
||||
|
|
||||
|
if (NULL != this->cur_response) |
||||
|
delete(&(this->cur_response)); |
||||
|
} |
||||
|
|
||||
|
static |
||||
|
void |
||||
|
_clone(void * _this, void * _base) |
||||
|
{ |
||||
|
HttpResponseWriter this = _this; |
||||
|
//HttpResponseWriter base = _base; |
||||
|
|
||||
|
this->response_queue = new(HttpMessageQueue); |
||||
|
} |
||||
|
|
||||
|
INIT_IFACE(Class, ctor, dtor, _clone); |
||||
|
INIT_IFACE(StreamWriter, |
||||
|
(fptr_streamWriterWrite)httpResponseWriterWrite); |
||||
|
CREATE_CLASS(HttpResponseWriter, NULL, IFACE(Class), IFACE(StreamWriter)); |
||||
|
|
||||
|
// vim: set ts=4 sw=4: |
||||
@ -0,0 +1,79 @@ |
|||||
|
#include <unistd.h> |
||||
|
#include <stdlib.h> |
||||
|
#include <string.h> |
||||
|
#include <sys/types.h> |
||||
|
|
||||
|
#include "class.h" |
||||
|
#include "interface/class.h" |
||||
|
#include "http/response.h" |
||||
|
#include "http/response/writer.h" |
||||
|
|
||||
|
size_t |
||||
|
httpResponseWriterWrite(HttpResponseWriter this, int fd) |
||||
|
{ |
||||
|
HttpMessageQueue respq = this->response_queue; |
||||
|
int cont = 1; |
||||
|
size_t written = 0; |
||||
|
|
||||
|
while (cont) { |
||||
|
switch (this->state) { |
||||
|
case HTTP_RESPONSE_NO: |
||||
|
if (NULL == this->cur_response && 0 < respq->nmsgs) { |
||||
|
this->cur_response = (HttpResponse)respq->msgs[0]; |
||||
|
memmove(respq->msgs, &(respq->msgs[1]), --respq->nmsgs); |
||||
|
this->state = HTTP_RESPONSE_START; |
||||
|
} |
||||
|
else { |
||||
|
cont = 0; |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case HTTP_RESPONSE_START: |
||||
|
if (NULL == this->buffer) { |
||||
|
this->nbuffer = httpResponseSizeGet(this->cur_response); |
||||
|
this->buffer = calloc(1, this->nbuffer); |
||||
|
httpResponseToString(this->cur_response, this->buffer); |
||||
|
} |
||||
|
{ |
||||
|
written = write(fd, this->buffer, this->nbuffer); |
||||
|
|
||||
|
if (-1 == written) { |
||||
|
free (this->buffer); |
||||
|
this->buffer = NULL; |
||||
|
return written; |
||||
|
} |
||||
|
|
||||
|
if (written == this->nbuffer) { |
||||
|
if (HTTP_MESSAGE_BUFFERED == |
||||
|
((HttpMessage)(this->cur_response))->type) { |
||||
|
this->state = HTTP_RESPONSE_DONE; |
||||
|
} |
||||
|
else { |
||||
|
this->state = HTTP_RESPONSE_PIPE; |
||||
|
} |
||||
|
} |
||||
|
else { |
||||
|
this->nbuffer -= written; |
||||
|
memmove(this->buffer, this->buffer + written, this->nbuffer); |
||||
|
cont = 0; |
||||
|
} |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case HTTP_RESPONSE_PIPE: |
||||
|
break; |
||||
|
|
||||
|
case HTTP_RESPONSE_DONE: |
||||
|
free (this->buffer); |
||||
|
this->buffer = NULL; |
||||
|
delete(&(this->cur_response)); |
||||
|
this->state = HTTP_RESPONSE_NO; |
||||
|
|
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return written; |
||||
|
} |
||||
|
|
||||
|
// vim: set ts=4 sw=4: |
||||
@ -0,0 +1,19 @@ |
|||||
|
#include "class.h" |
||||
|
#include "interface/stream_writer.h" |
||||
|
|
||||
|
const struct interface i_StreamWriter = { |
||||
|
"streamWriter", |
||||
|
1 |
||||
|
}; |
||||
|
|
||||
|
size_t |
||||
|
streamWriterWrite(void * object, int fd) |
||||
|
{ |
||||
|
size_t ret; |
||||
|
|
||||
|
RETCALL(object, StreamWriter, write, ret, fd); |
||||
|
|
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
// vim: set ts=4 sw=4: |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue