diff --git a/include/http/request/parser.h b/include/http/parser.h
similarity index 60%
rename from include/http/request/parser.h
rename to include/http/parser.h
index e16b7a2..43a4bb1 100644
--- a/include/http/request/parser.h
+++ b/include/http/parser.h
@@ -21,11 +21,11 @@
* along with this program. If not, see .
*/
-#ifndef __HTTP_REQUEST_PARSER_H__
-#define __HTTP_REQUEST_PARSER_H__
+#ifndef __HTTP_PARSER_H__
+#define __HTTP_PARSER_H__
#include "class.h"
-#include "http/request.h"
+#include "http/message.h"
#include "http/message/queue.h"
#include "cbuf.h"
@@ -38,36 +38,33 @@
#endif
-typedef enum e_HttpRequestState {
- HTTP_REQUEST_GARBAGE=0,
- HTTP_REQUEST_START,
- HTTP_REQUEST_REQUEST_LINE_DONE,
- HTTP_REQUEST_HEADERS_DONE,
- HTTP_REQUEST_DONE
-} HttpRequestState;
+typedef enum e_HttpMessageState {
+ HTTP_MESSAGE_GARBAGE=0,
+ HTTP_MESSAGE_START,
+ HTTP_MESSAGE_INTRO_DONE,
+ HTTP_MESSAGE_HEADERS_DONE,
+ HTTP_MESSAGE_DONE
+} HttpMessageState;
-CLASS(HttpRequestParser) {
+CLASS(HttpParser) {
Cbuf buffer;
void * ourLock;
char * incomplete;
size_t isize;
- HttpMessageQueue request_queue;
- HttpRequest cur_request;
+ HttpMessageQueue queue;
+ HttpMessage current;
- HttpRequestState state;
+ HttpMessageState state;
};
-ssize_t httpRequestParserParse(HttpRequestParser, int);
-void httpRequestParserGetBody(HttpRequestParser);
+ssize_t httpParserParse(void *, int);
+void httpParserHeader(HttpParser, const char *, const char *);
+void httpParserNewMessage(HttpParser, const char *, const char * lend);
+size_t httpParserBody(HttpParser, const char *, size_t);
-void httpRequestParserGetRequestLine(
- HttpRequest, const char *, const char *);
-void httpRequestParserGetHeader(
- HttpRequest, const char *, const char *);
-
-#endif // __HTTP_REQUEST_PARSER_H__
+#endif // __HTTP_PARSER_H__
// vim: set ts=4 sw=4:
diff --git a/include/http/worker.h b/include/http/worker.h
index 08bf8dc..73dc9a4 100644
--- a/include/http/worker.h
+++ b/include/http/worker.h
@@ -27,7 +27,7 @@
#include
#include "class.h"
-#include "http/request/parser.h"
+#include "http/parser.h"
#include "http/response/writer.h"
#include "cbuf.h"
@@ -49,13 +49,10 @@ CLASS(HttpWorker) {
Cbuf pbuf;
Cbuf wbuf;
- HttpRequestParser parser;
+ HttpParser parser;
HttpResponseWriter writer;
};
-ssize_t httpWorkerProcess(HttpWorker, int);
-ssize_t httpWorkerWrite(HttpWorker, int);
-
#endif // __HTTP_WORKER_H__
// vim: set ts=4 sw=4:
diff --git a/include/utils/http.h b/include/utils/http.h
new file mode 100644
index 0000000..38d4511
--- /dev/null
+++ b/include/utils/http.h
@@ -0,0 +1,16 @@
+#ifndef __UTILS_HTTP_H__
+#define __UTILS_HTTP_H__
+
+#include
+
+#include "http/message.h"
+
+char isHttpVersion(const char *, size_t);
+HttpMessage httpGetMessage(
+ const char *, size_t,
+ const char *, size_t,
+ const char *, size_t);
+
+#endif // __UTILS_HTTP_H__
+
+// vim: set ts=4 sw=4:
diff --git a/src/Makefile.am b/src/Makefile.am
index 4fbfc6a..49cbb74 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -14,24 +14,38 @@ CB = cbuf.c cbuf/read.c cbuf/write.c \
cbuf/inc_read.c cbuf/inc_write.c cbuf/is_empty.c cbuf/memchr.c \
cbuf/skip_non_alpha.c cbuf/is_locked.c cbuf/lock.c cbuf/release.c \
cbuf/empty.c
-MSG = http/message.c http/message/queue.c http/message/has_keep_alive.c \
- http/message/header_size_get.c http/message/header_to_string.c \
- http/message/get_version.c http/message/has_valid_version.c
-REQ = http/request.c http/request/has_valid_method.c
+MSG = http/message.c \
+ http/message/has_keep_alive.c \
+ http/message/header_size_get.c \
+ http/message/header_to_string.c \
+ http/message/get_version.c \
+ http/message/has_valid_version.c
+MSGQ = http/message/queue.c
+REQ = http/request.c \
+ http/request/has_valid_method.c
RESP = http/response.c \
http/response/304.c \
http/response/404.c \
http/response/asset.c \
http/response/me.c
-WORKER = http/worker.c http/worker/process.c http/worker/write.c \
- http/worker/get_asset.c http/worker/add_common_header.c
+PARSER = http/parser.c \
+ http/parser/parse.c \
+ http/parser/new_message.c \
+ http/parser/header.c \
+ http/parser/body.c
+WORKER = http/worker.c \
+ http/worker/process.c \
+ http/worker/write.c \
+ http/worker/get_asset.c \
+ http/worker/add_common_header.c
WRITER = http/response/writer.c http/response/writer/write.c
HEADER = http/header.c http/header/get.c http/header/add.c \
http/header/to_string.c
-PARSER = http/request/parser.c http/request/parser/get_header.c \
- http/request/parser/parse.c http/request/parser/get_request_line.c \
- http/request/parser/get_body.c
-UTILS = utils/hash.c utils/memory.c utils/daemonize.c utils/signalHandling.c
+UTILS = utils/hash.c \
+ utils/memory.c \
+ utils/http.c \
+ utils/daemonize.c \
+ utils/signalHandling.c
AM_CFLAGS = -Wall -I ../include/
@@ -41,6 +55,6 @@ bin_PROGRAMS = testserver
testserver_SOURCES = testserver.c \
$(IFACE) $(SOCKET) $(SERVER) $(LOGGER) $(MSG) $(REQ) \
$(WRITER) $(RESP) $(HEADER) $(PARSER) $(WORKER) $(CB) \
- $(UTILS)
+ $(UTILS) $(MSGQ)
testserver_CFLAGS = -Wall -I ../include/
testserver_LDFLAGS = -lrt
diff --git a/src/http/message/has_keep_alive.c b/src/http/message/has_keep_alive.c
index 652cf5d..e92e575 100644
--- a/src/http/message/has_keep_alive.c
+++ b/src/http/message/has_keep_alive.c
@@ -28,6 +28,13 @@
#include "http/request.h"
#include "http/header.h"
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
char
httpMessageHasKeepAlive(HttpMessage message)
@@ -35,7 +42,6 @@ httpMessageHasKeepAlive(HttpMessage message)
HttpHeader header;
size_t size;
char * value;
- char * keep_alive = "keep-alive";
header = httpHeaderGet(
&(message->header),
@@ -46,21 +52,10 @@ httpMessageHasKeepAlive(HttpMessage message)
return 0;
}
- if ((sizeof("keep-alive")-1) != (header->nvalue)[0]) {
- return 0;
- }
-
size = (header->nvalue)[0];
value = (header->value)[0];
- for (; 0 < size && tolower(*value) == *keep_alive;
- size--, value++, keep_alive++);
-
- if (0 == size) {
- return 1;
- }
-
- return 0;
+ return (0 == strncasecmp("keep-alive", value, size))? 1 : 0;
}
// vim: set ts=4 sw=4:
diff --git a/src/http/message/has_valid_version.c b/src/http/message/has_valid_version.c
index 6fed4ab..1195995 100644
--- a/src/http/message/has_valid_version.c
+++ b/src/http/message/has_valid_version.c
@@ -23,6 +23,7 @@
#include
#include "http/message.h"
+#include "utils/http.h"
int
httpMessageHasValidVersion(HttpMessage this)
@@ -30,18 +31,12 @@ httpMessageHasValidVersion(HttpMessage this)
int major;
int minor;
- if (NULL == this->version)
- return 0;
-
- if (8 > strlen(this->version))
+ if (! isHttpVersion(this->version, strlen(this->version)))
return 0;
if (0 > httpMessageGetVersion(this, &major, &minor))
return 0;
- if (0 != memcmp("HTTP/", this->version, sizeof("HTTP/")-1))
- return 0;
-
if (1 != major)
return 0;
diff --git a/src/http/request/parser.c b/src/http/parser.c
similarity index 68%
rename from src/http/request/parser.c
rename to src/http/parser.c
index a3b57b3..d294a67 100644
--- a/src/http/request/parser.c
+++ b/src/http/parser.c
@@ -28,9 +28,10 @@
#include "interface/class.h"
#include "interface/stream_reader.h"
-#include "http/request/parser.h"
+#include "http/parser.h"
#include "http/message/queue.h"
#include "http/request.h"
+#include "http/response.h"
#include "cbuf.h"
#include "utils/memory.h"
@@ -38,33 +39,38 @@
static
int
-requestParserCtor(void * _this, va_list * params)
+httpParserCtor(void * _this, va_list * params)
{
- HttpRequestParser this = _this;
+ HttpParser this = _this;
- this->buffer = va_arg(* params, Cbuf);
- this->request_queue = new(HttpMessageQueue);
+ this->buffer = va_arg(* params, Cbuf);
+
+ if (NULL == this->buffer) {
+ return -1;
+ }
+
+ this->queue = new(HttpMessageQueue);
return 0;
}
static
void
-requestParserDtor(void * _this)
+httpParserDtor(void * _this)
{
- HttpRequestParser this = _this;
+ HttpParser this = _this;
- delete(this->request_queue);
+ delete(this->queue);
if (TRUE == this->ourLock)
cbufRelease(this->buffer);
FREE(this->incomplete);
- delete(this->cur_request);
+ delete(this->current);
}
-INIT_IFACE(Class, requestParserCtor, requestParserDtor, NULL);
-INIT_IFACE(StreamReader, (fptr_streamReaderRead)httpRequestParserParse);
-CREATE_CLASS(HttpRequestParser, NULL, IFACE(Class), IFACE(StreamReader));
+INIT_IFACE(Class, httpParserCtor, httpParserDtor, NULL);
+INIT_IFACE(StreamReader, httpParserParse);
+CREATE_CLASS(HttpParser, NULL, IFACE(Class), IFACE(StreamReader));
// vim: set ts=4 sw=4:
diff --git a/src/http/request/parser/get_header.c b/src/http/parser/body.c
similarity index 63%
rename from src/http/request/parser/get_header.c
rename to src/http/parser/body.c
index eadb079..8557217 100644
--- a/src/http/request/parser/get_header.c
+++ b/src/http/parser/body.c
@@ -20,31 +20,31 @@
* along with this program. If not, see .
*/
-#include
+#include
#include
-#include "class.h"
-#include "interface/class.h"
#include "http/header.h"
#include "http/message.h"
-#include "http/request/parser.h"
-#include "ringbuffer.h"
-
-void
-httpRequestParserGetHeader(
- HttpMessage message,
- const char * line,
- const char * line_end)
+#include "http/parser.h"
+#include "cbuf.h"
+
+#define MAX(a,b) (((a) > (b))? (a) : (b))
+
+size_t
+httpParserBody(HttpParser this, const char * buf, size_t nbuf)
{
- const char * name = line;
- char * value = memchr(line, ':', line_end - line);
- size_t nname = (value++) - name;
+ size_t len = 0;
+ HttpMessage current = this->current;
+
+ if (current->dbody < current->nbody) {
+ len = MAX(current->nbody - current->dbody, nbuf);
+
+ memcpy(current->body, buf, len);
- for (; *value == ' ' && *value != 0; value++);
+ current->dbody += len;
+ }
- httpHeaderAdd(
- &(message->header),
- new(HttpHeader, name, nname, value, line_end - value));
+ return len;
}
// vim: set ts=4 sw=4:
diff --git a/src/http/request/parser/get_body.c b/src/http/parser/header.c
similarity index 54%
rename from src/http/request/parser/get_body.c
rename to src/http/parser/header.c
index c5758a1..d6b48cf 100644
--- a/src/http/request/parser/get_body.c
+++ b/src/http/parser/header.c
@@ -21,14 +21,14 @@
*/
#include
+#include
+#include
+#include "class.h"
+#include "interface/class.h"
#include "http/header.h"
+#include "http/parser.h"
#include "http/message.h"
-#include "http/request/parser.h"
-#include "cbuf.h"
-
-#define MAX(a,b) (((a) > (b))? (a) : (b))
-
#define MAX(x,y) ((x) > (y) ? (x) : (y))
@@ -37,41 +37,38 @@
* @TODO: not final...input buffer handling not final
*/
void
-httpRequestParserGetBody(HttpRequestParser this)
+httpParserHeader(
+ HttpParser this,
+ const char * line,
+ const char * lend)
{
- HttpMessage message = (HttpMessage)(this->cur_request);
- size_t len;
+ const char * name = line;
+ char * value = memchr(line, ':', lend - line);
+ size_t nname = (value++) - name;
+ HttpMessage current = this->current;
- if (0 == message->nbody) {
- HttpHeader clen = httpHeaderGet(
- &(message->header),
- "Content-Length",
- sizeof("Content-Length")-1);
-
- if (NULL == clen) {
- this->state = HTTP_REQUEST_DONE;
- return;
- }
- else {
- message->type = HTTP_MESSAGE_BUFFERED;
- message->nbody = atoi((clen->value)[0]);
- if (0 < message->nbody) {
- message->body = malloc(message->nbody);
- }
- message->dbody = 0;
- }
+ if (NULL == value) {
+ return;
}
this->buffer->bused -= len;
- if (message->dbody < message->nbody) {
- len = MAX(
- message->nbody - message->dbody,
- this->buffer->bused);
+ for (; *value == ' ' && value < lend; value++);
- memcpy(message->body, cbufGetData(this->buffer, len), len);
+ if (value == lend) {
+ return;
+ }
- message->dbody += len;
+ if (0 == strncasecmp("content-length", name, nname-1)) {
+ current->nbody = strtoul(value, NULL, 10);
+ if (0 < this->current->nbody) {
+ current->body = malloc(current->nbody);
+ }
+ current->dbody = 0;
}
+
+ httpHeaderAdd(
+ &(current->header),
+ new(HttpHeader, name, nname, value, lend - value));
}
// vim: set ts=4 sw=4:
diff --git a/src/http/parser/new_message.c b/src/http/parser/new_message.c
new file mode 100644
index 0000000..5c392fc
--- /dev/null
+++ b/src/http/parser/new_message.c
@@ -0,0 +1,34 @@
+#include "http/parser.h"
+
+#include "utils/http.h"
+
+void
+httpParserNewMessage(
+ HttpParser this,
+ const char * line,
+ const char * lend)
+{
+ const char * part1, * part2, * part3;
+ size_t len1, len2, len3;
+
+ part1 = line;
+ part2 = memchr(line, ' ', lend - line);
+
+ if (NULL == part2) return;
+
+ len1 = part2 - part1;
+ for (; *part2 == ' ' && *part2 != 0; part2++);
+
+ part3 = memchr(part2, ' ', lend - part2);
+
+ if (NULL == part3) return;
+
+ len2 = part3 - part2;
+ for (; *part3 == ' ' && *part3 != 0; part3++);
+
+ len3 = lend - part3;
+
+ this->current = httpGetMessage(part1, len1, part2, len2, part3, len3);
+}
+
+// vim: set ts=4 sw=4:
diff --git a/src/http/request/parser/parse.c b/src/http/parser/parse.c
similarity index 63%
rename from src/http/request/parser/parse.c
rename to src/http/parser/parse.c
index 0ccfb0a..9962ea4 100644
--- a/src/http/request/parser/parse.c
+++ b/src/http/parser/parse.c
@@ -22,19 +22,19 @@
#include
-#include "http/request.h"
-#include "http/message.h"
-#include "http/request/parser.h"
+#include "http/parser.h"
#include "interface/class.h"
+#include "interface/http_intro.h"
#include "cbuf.h"
ssize_t
-httpRequestParserParse(HttpRequestParser this, int fd)
+httpParserParse(void * _this, int fd)
{
- int cont = 1;
- ssize_t read;
- char * line;
- char * line_end;
+ HttpParser this = _this;
+ int cont = 1;
+ ssize_t read;
+ char * line;
+ char * line_end;
if (cbufIsLocked(this->buffer)) {
if (FALSE == this->ourLock)
@@ -57,11 +57,10 @@ httpRequestParserParse(HttpRequestParser this, int fd)
while (cont) {
switch(this->state) {
- case HTTP_REQUEST_GARBAGE:
+ case HTTP_MESSAGE_GARBAGE:
cbufSkipNonAlpha(this->buffer);
if (! cbufIsEmpty(this->buffer)) {
- this->cur_request = new(HttpRequest);
- this->state = HTTP_REQUEST_START;
+ this->state = HTTP_MESSAGE_START;
}
else {
cbufRelease(this->buffer);
@@ -71,7 +70,7 @@ httpRequestParserParse(HttpRequestParser this, int fd)
break;
- case HTTP_REQUEST_START:
+ case HTTP_MESSAGE_START:
if (NULL == (line = cbufGetLine(this->buffer, &line_end))) {
if (! cbufIsEmpty(this->buffer)) {
this->isize = this->buffer->bused;
@@ -86,22 +85,17 @@ httpRequestParserParse(HttpRequestParser this, int fd)
break;
}
- httpRequestParserGetRequestLine(this->cur_request, line, line_end);
- if (! httpRequestHasValidMethod(this->cur_request)) {
- cbufRelease(this->buffer);
- this->ourLock = FALSE;
- return -1;
- }
- if (! httpMessageHasValidVersion((HttpMessage)this->cur_request)) {
+ httpParserNewMessage(this, line, line_end);
+ if (NULL == this->current) {
cbufRelease(this->buffer);
this->ourLock = FALSE;
return -1;
}
- this->state = HTTP_REQUEST_REQUEST_LINE_DONE;
+ this->state = HTTP_MESSAGE_INTRO_DONE;
break;
- case HTTP_REQUEST_REQUEST_LINE_DONE:
+ case HTTP_MESSAGE_INTRO_DONE:
if (NULL == (line = cbufGetLine(this->buffer, &line_end))) {
if (! cbufIsEmpty(this->buffer)) {
this->isize = this->buffer->bused;
@@ -116,46 +110,45 @@ httpRequestParserParse(HttpRequestParser this, int fd)
break;
}
- if (0 == line_end - this->buffer->buffer - this->buffer->bstart) {
- this->buffer->bstart += 2;
- if (this->buffer->bstart >= this->buffer->bsize) {
- this->buffer->bstart -= this->buffer->bsize;
- }
- this->buffer->bused -= 2;
-
- this->state = HTTP_REQUEST_HEADERS_DONE;
+ if (0 == strlen(line)) {
+ this->state = HTTP_MESSAGE_HEADERS_DONE;
break;
}
- httpRequestParserGetHeader(this->cur_request, line, line_end);
+ httpParserHeader(this->current, line, line_end);
break;
- case HTTP_REQUEST_HEADERS_DONE:
+ case HTTP_MESSAGE_HEADERS_DONE:
{
- HttpMessage message = (HttpMessage)this->cur_request;
+ cbufIncRead(
+ this->buffer,
+ httpParserBody(
+ this,
+ cbufGetRead(this->buffer),
+ this->buffer->bused));
- httpRequestParserGetBody(this);
if (cbufIsEmpty(this->buffer)) {
cbufRelease(this->buffer);
this->ourLock = FALSE;
}
- if (message->dbody == message->nbody) {
- this->state = HTTP_REQUEST_DONE;
+ if (this->current->dbody == this->current->nbody) {
+ this->state = HTTP_MESSAGE_DONE;
}
}
break;
- case HTTP_REQUEST_DONE:
- this->request_queue->msgs[(this->request_queue->nmsgs)++] =
- (HttpMessage)this->cur_request;
-
- this->cur_request = NULL;
+ case HTTP_MESSAGE_DONE:
+ /**
+ * enqueue current request
+ */
+ this->queue->msgs[(this->queue->nmsgs)++] = this->current;
+ this->current = NULL;
/**
* prepare for next request
*/
- this->state = HTTP_REQUEST_GARBAGE;
+ this->state = HTTP_MESSAGE_GARBAGE;
break;
@@ -164,7 +157,7 @@ httpRequestParserParse(HttpRequestParser this, int fd)
}
}
- return ret;
+ return this->queue->nmsgs;
}
// vim: set ts=4 sw=4:
diff --git a/src/http/request.c b/src/http/request.c
index 12a7960..4299a27 100644
--- a/src/http/request.c
+++ b/src/http/request.c
@@ -37,10 +37,25 @@ static
int
httpRequestCtor(void * _this, va_list * params)
{
- /**
- * the parent is not called by intention. All infomations
- * are read from the request stream.
- */
+ HttpRequest this = _this;
+ char * method, * uri;
+ size_t mlen, ulen;
+
+ method = va_arg(* params, char *);
+ mlen = va_arg(* params, size_t);
+ uri = va_arg(* params, char *);
+ ulen = va_arg(* params, size_t);
+
+ PARENTCALL(_this, Class, ctor, params);
+
+ this->method = malloc(mlen + 1);
+ this->method[mlen] = 0;
+ memcpy(this->method, method, mlen);
+
+ this->uri = malloc(ulen + 1);
+ this->uri[ulen] = 0;
+ memcpy(this->uri, uri, ulen);
+
return 0;
}
diff --git a/src/http/worker.c b/src/http/worker.c
index 62c21b2..5e84d55 100644
--- a/src/http/worker.c
+++ b/src/http/worker.c
@@ -6,7 +6,7 @@
#include "class.h"
#include "http/worker.h"
-#include "http/request/parser.h"
+#include "http/parser.h"
#include "http/response/writer.h"
#include "interface/class.h"
@@ -34,7 +34,7 @@ httpWorkerCtor(void * _this, va_list * params)
sprintf(cbuf_id, "%s_%s", "writer", id);
this->wbuf = new(Cbuf, cbuf_id, RESPONSE_WRITER_MAX_BUF);
- this->parser = new(HttpRequestParser, this->pbuf);
+ this->parser = new(HttpParser, this->pbuf);
this->writer = new(HttpResponseWriter, this->wbuf);
return 0;
@@ -67,13 +67,16 @@ _clone(void * _this, void * _base)
this->pbuf = NULL;
this->wbuf = NULL;
- this->parser = new(HttpRequestParser, base->pbuf);
+ this->parser = new(HttpParser, base->pbuf);
this->writer = new(HttpResponseWriter, base->wbuf);
}
+ssize_t httpWorkerProcess(void *, int);
+ssize_t httpWorkerWrite(void *, int);
+
INIT_IFACE(Class, httpWorkerCtor, httpWorkerDtor, _clone);
-INIT_IFACE(StreamReader, (fptr_streamReaderRead)httpWorkerProcess);
-INIT_IFACE(StreamWriter, (fptr_streamWriterWrite)httpWorkerWrite);
+INIT_IFACE(StreamReader, httpWorkerProcess);
+INIT_IFACE(StreamWriter, httpWorkerWrite);
CREATE_CLASS(
HttpWorker,
NULL,
diff --git a/src/http/worker/process.c b/src/http/worker/process.c
index ee5353f..b244e2a 100644
--- a/src/http/worker/process.c
+++ b/src/http/worker/process.c
@@ -29,10 +29,7 @@
#include "http/message.h"
#include "http/request.h"
#include "http/message/queue.h"
-#include "http/request/parser.h"
-#include "http/header.h"
-#include "http/request.h"
-#include "http/message.h"
+#include "http/parser.h"
HttpMessage httpWorkerGetAsset(HttpRequest, const char *, const char *, size_t);
void httpWorkerAddCommonHeader(HttpMessage, HttpMessage);
@@ -45,9 +42,9 @@ httpWorkerProcess(HttpWorker this, int fd)
char buffer[200];
ssize_t size;
- if (0 < (size = httpRequestParserParse(this->parser, fd))) {
+ if (0 < (size = httpParserParse(this->parser, fd))) {
int i;
- HttpMessageQueue reqq = this->parser->request_queue;
+ HttpMessageQueue reqq = this->parser->queue;
HttpMessageQueue respq = this->writer->response_queue;
for (i=0; inmsgs; i++) {
diff --git a/src/utils/http.c b/src/utils/http.c
new file mode 100644
index 0000000..ee57227
--- /dev/null
+++ b/src/utils/http.c
@@ -0,0 +1,57 @@
+#include
+#include
+#include
+
+#include "http/message.h"
+#include "http/request.h"
+#include "http/response.h"
+
+#include "interface/class.h"
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+char
+isHttpVersion(const char * str, size_t len)
+{
+ if (NULL == str)
+ return FALSE;
+
+ if (8 > len)
+ return FALSE;
+
+ if (0 != memcmp("HTTP/", str, sizeof("HTTP/")-1))
+ return FALSE;
+
+ return TRUE;
+}
+
+HttpMessage
+httpGetMessage(
+ const char * part1, size_t len1,
+ const char * part2, size_t len2,
+ const char * part3, size_t len3)
+{
+ if (isHttpVersion(part1, len1)) {
+ return new(HttpResponse,
+ part1, len1,
+ strtoul(part2, NULL, 10),
+ part3, len3);
+ }
+
+ if (isHttpVersion(part3, len3)) {
+ return new(HttpRequest,
+ part1, len1,
+ part2, len2,
+ part3, len3);
+ }
+
+ return NULL;
+}
+
+// vim: set ts=4 sw=4: