Browse Source

structural changes for worker/process. @TODO actually i have no idea why this happens.

master
Georg Hopp 14 years ago
parent
commit
87b0d50d1d
  1. 8
      ChangeLog
  2. 4
      TODO
  3. 6
      include/http/header.h
  4. 5
      include/http/response.h
  5. 2
      include/interface/class.h
  6. 2
      include/utils/memory.h
  7. 6
      src/Makefile.am
  8. 28
      src/cbuf.c
  9. 16
      src/http/header.c
  10. 17
      src/http/header/add.c
  11. 4
      src/http/header/size_get.c
  12. 12
      src/http/message.c
  13. 8
      src/http/message/queue.c
  14. 14
      src/http/request.c
  15. 17
      src/http/request/parser.c
  16. 8
      src/http/response.c
  17. 33
      src/http/response/304.c
  18. 2
      src/http/response/404.c
  19. 42
      src/http/response/asset.c
  20. 75
      src/http/response/image.c
  21. 2
      src/http/response/me.c
  22. 10
      src/http/response/writer.c
  23. 4
      src/http/response/writer/write.c
  24. 19
      src/http/worker.c
  25. 37
      src/http/worker/add_common_header.c
  26. 29
      src/http/worker/get_asset.c
  27. 76
      src/http/worker/process.c
  28. 6
      src/logger.c
  29. 16
      src/server.c
  30. 4
      src/server/close_conn.c
  31. 2
      src/server/handle_accept.c
  32. 8
      src/socket.c
  33. 6
      src/testserver.c

8
ChangeLog

@ -1,10 +1,14 @@
2012-02-22 12:19:40 +0100 Georg Hopp
* fix memory problems occured with latest changes (HEAD, master)
2012-02-22 09:03:40 +0100 Georg Hopp
* fixed bug in keep-alive check arised by implementation if #10 (HEAD, master)
* fixed bug in keep-alive check arised by implementation if #10 (origin/master, origin/HEAD)
2012-02-22 08:51:05 +0100 Georg Hopp
* add forgotten jquery assets (origin/master, origin/HEAD)
* add forgotten jquery assets
2012-02-22 08:48:43 +0100 Georg Hopp

4
TODO

@ -1,6 +1,6 @@
VERY BIG TODO:
- give a contructor a way to fail, so that no object will be created at all
- right now i will use long polling ajax calls when feedback from to the client
is needed. In the long term this should be changed to websockets (ws). But
right now ws specification is not final anyway. :)
- handle errors after all system call...especially open, close, etc.

6
include/http/header.h

@ -27,16 +27,18 @@
#include "class.h"
#define HTTP_HEADER_VALUE_CHUNK_SIZE 128
CLASS(HttpHeader) {
unsigned long hash;
char * name;
char ** value;
char * value[HTTP_HEADER_VALUE_CHUNK_SIZE];
size_t nvalue;
};
HttpHeader httpHeaderParse(char * line); // @INFO: destructive
void httpHeaderAdd(const HttpHeader *, HttpHeader);
HttpHeader httpHeaderAdd(const HttpHeader *, HttpHeader);
HttpHeader httpHeaderGet(const HttpHeader *, const char *);
size_t httpHeaderSizeGet(HttpHeader);
size_t httpHeaderToString(HttpHeader, char *);

5
include/http/response.h

@ -38,11 +38,10 @@ CLASS(HttpResponse) {
char * reason;
};
HttpResponse httpResponse304(int, const char *);
HttpResponse httpResponse304(const char *, const char *, const char *);
HttpResponse httpResponse404();
HttpResponse httpResponseMe(int);
HttpResponse httpResponseImage(int);
HttpResponse httpResponseJquery(int);
HttpResponse httpResponseAsset(const char *, const char *, const char *);
#endif // __HTTP_RESPONSE_H__

2
include/interface/class.h

@ -49,7 +49,7 @@ extern void classDelete(void **);
extern void * classClone(void *);
#define new(class,...) classNew(_##class, ##__VA_ARGS__)
#define delete(object) classDelete((void **)(object))
#define delete(object) classDelete((void **)&(object))
#define clone(object) classClone((void *)(object))
#endif // __INTERFACE_CLASS_H__

2
include/utils/memory.h

@ -23,7 +23,7 @@
#ifndef __UTILS_MEMORY_H__
#define __UTILS_MEMORY_H__
#define FREE(val) (ffree((void**)(val)))
#define FREE(val) (ffree((void**)&(val)))
void ffree(void **);

6
src/Makefile.am

@ -23,10 +23,10 @@ REQ = http/request.c http/request/has_valid_method.c
RESP = http/response.c \
http/response/304.c \
http/response/404.c \
http/response/image.c \
http/response/jquery.c \
http/response/asset.c \
http/response/me.c
WORKER = http/worker.c http/worker/process.c http/worker/write.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/size_get.c http/header/to_string.c

28
src/cbuf.c

@ -35,18 +35,19 @@
#include "class.h"
#include "interface/class.h"
#include "utils/memory.h"
#include "cbuf.h"
static void dtor(void*);
static void cbufDtor(void*);
static
int
ctor(void * _this, va_list * params)
cbufCtor(void * _this, va_list * params)
{
Cbuf this = _this;
char state = 0;
char state = -1;
char * shm_name = va_arg(*params, char*);
long psize = sysconf(_SC_PAGESIZE);
size_t size;
@ -64,7 +65,7 @@ ctor(void * _this, va_list * params)
size = (0 >= size)? 1 : (0 != size%psize)? (size/psize)+1 : size/psize;
this->bsize = psize * size;
while (0 == state) {
while (-1 == state) {
shm = shm_open(this->shm_name, O_RDWR|O_CREAT|O_EXCL, S_IRWXU);
if (-1 == shm) {
break;
@ -93,7 +94,7 @@ ctor(void * _this, va_list * params)
break;
}
state = 1;
state = 0;
}
if (-1 != shm) {
@ -101,32 +102,25 @@ ctor(void * _this, va_list * params)
close(shm);
}
if (1 != state) {
dtor(this);
}
return 0;
return state;
}
static
void
dtor(void * _this)
cbufDtor(void * _this)
{
Cbuf this = _this;
if (NULL != this->shm_name) {
free(this->shm_name);
}
FREE(this->shm_name);
if (NULL != this->data && MAP_FAILED != this->data) {
munmap(this->data, this->bsize << 1);
}
this->shm_name = NULL;
this->data = NULL;
this->data = NULL;
}
INIT_IFACE(Class, ctor, dtor, NULL);
INIT_IFACE(Class, cbufCtor, cbufDtor, NULL);
CREATE_CLASS(Cbuf, NULL, IFACE(Class));
// vim: set ts=4 sw=4:

16
src/http/header.c

@ -33,7 +33,7 @@
static
int
ctor(void * _this, va_list * params) {
httpHeaderCtor(void * _this, va_list * params) {
HttpHeader this = _this;
char * name;
char * value;
@ -46,29 +46,27 @@ ctor(void * _this, va_list * params) {
this->hash = sdbm((unsigned char *)name);
this->value = malloc(sizeof(char*) * (++(this->nvalue)));
(this->value)[this->nvalue - 1] = malloc(strlen(value) + 1);
strcpy((this->value)[this->nvalue - 1], value);
(this->value)[this->nvalue] = malloc(strlen(value) + 1);
strcpy((this->value)[this->nvalue++], value);
return 0;
}
static
void
dtor(void * _this)
httpHeaderDtor(void * _this)
{
HttpHeader this = _this;
size_t i;
FREE(&(this->name));
FREE(this->name);
for (i=0; i<this->nvalue; i++) {
FREE(&(this->value[i]));
FREE(this->value[i]);
}
FREE(&(this->value));
}
INIT_IFACE(Class, ctor, dtor, NULL);
INIT_IFACE(Class, httpHeaderCtor, httpHeaderDtor, NULL);
CREATE_CLASS(HttpHeader, NULL, IFACE(Class));
// vim: set ts=4 sw=4:

17
src/http/header/add.c

@ -40,20 +40,21 @@ comp(const void * _a, const void * _b)
return (a->hash < b->hash)? -1 : (a->hash > b->hash)? 1 : 0;
}
void
HttpHeader
httpHeaderAdd(const HttpHeader * root, HttpHeader header)
{
HttpHeader * found = tsearch(header, (void **)root, comp);
if (*found != header) {
(*found)->value = realloc(
(*found)->value,
sizeof(char*) * (++(*found)->nvalue));
(*found)->value[(*found)->nvalue - 1] = malloc(
strlen((header->value)[0]) + 1);
strcpy(((*found)->value)[(*found)->nvalue - 1], (header->value)[0]);
delete(&header);
if ((*found)->nvalue >= HTTP_HEADER_VALUE_CHUNK_SIZE) {
return NULL;
}
(*found)->value[(*found)->nvalue++] = (header->value)[0];
(header->value)[0] = NULL;
delete(header);
}
return *found;
}
// vim: set ts=4 sw=4:

4
src/http/header/size_get.c

@ -28,11 +28,11 @@
size_t
httpHeaderSizeGet(HttpHeader header)
{
size_t size = 0;
size_t nsize = strlen(header->name) + 2;
size_t size = header->nvalue * nsize;
int i;
for (i=0; i<header->nvalue; i++) {
size += strlen(header->name) + 2;
size += strlen(header->value[i]) + 2;
}

12
src/http/message.c

@ -42,12 +42,12 @@ inline
void
tDelete(void * node)
{
delete(&node);
delete(node);
}
static
int
ctor(void * _this, va_list * params)
httpMessageCtor(void * _this, va_list * params)
{
HttpMessage this = _this;
char * version = va_arg(* params, char *);
@ -60,11 +60,11 @@ ctor(void * _this, va_list * params)
static
void
dtor(void * _this)
httpMessageDtor(void * _this)
{
HttpMessage this = _this;
ffree((void **)&(this->version));
FREE(this->version);
/**
* this is a GNU extension...anyway on most non
@ -75,7 +75,7 @@ dtor(void * _this)
switch (this->type) {
case HTTP_MESSAGE_BUFFERED:
ffree((void **)&(this->body));
FREE(this->body);
break;
case HTTP_MESSAGE_PIPED:
@ -87,7 +87,7 @@ dtor(void * _this)
}
}
INIT_IFACE(Class, ctor, dtor, NULL);
INIT_IFACE(Class, httpMessageCtor, httpMessageDtor, NULL);
CREATE_CLASS(HttpMessage, NULL, IFACE(Class));
// vim: set ts=4 sw=4:

8
src/http/message/queue.c

@ -29,24 +29,24 @@
static
int
ctor(void * _this, va_list * params)
messageQueueCtor(void * _this, va_list * params)
{
return 0;
}
static
void
dtor(void * _this)
messageQueueDtor(void * _this)
{
HttpMessageQueue this = _this;
int i;
for (i=0; i<this->nmsgs; i++) {
delete(&(this->msgs)[i]);
delete((this->msgs)[i]);
}
}
INIT_IFACE(Class, ctor, dtor, NULL);
INIT_IFACE(Class, messageQueueCtor, messageQueueDtor, NULL);
CREATE_CLASS(HttpMessageQueue, NULL, IFACE(Class));
// vim: set ts=4 sw=4:

14
src/http/request.c

@ -35,19 +35,23 @@
static
int
ctor(void * _this, va_list * params)
httpRequestCtor(void * _this, va_list * params)
{
/**
* the parent is not called by intention. All infomations
* are read from the request stream.
*/
return 0;
}
static
void
dtor(void * _this)
httpRequestDtor(void * _this)
{
HttpRequest this = _this;
ffree((void **)&(this->uri));
ffree((void **)&(this->method));
FREE(this->uri);
FREE(this->method);
PARENTCALL(_this, Class, dtor);
}
@ -88,7 +92,7 @@ toString(void * _this, char * string)
return string;
}
INIT_IFACE(Class, ctor, dtor, NULL);
INIT_IFACE(Class, httpRequestCtor, httpRequestDtor, NULL);
INIT_IFACE(HttpIntro, sizeGet, toString);
CREATE_CLASS(HttpRequest,
HttpMessage,

17
src/http/request/parser.c

@ -33,10 +33,12 @@
#include "http/request.h"
#include "cbuf.h"
#include "utils/memory.h"
static
int
ctor(void * _this, va_list * params)
requestParserCtor(void * _this, va_list * params)
{
HttpRequestParser this = _this;
@ -48,23 +50,20 @@ ctor(void * _this, va_list * params)
static
void
dtor(void * _this)
requestParserDtor(void * _this)
{
HttpRequestParser this = _this;
delete(&(this->request_queue));
delete(this->request_queue);
if (TRUE == this->ourLock)
cbufRelease(this->buffer);
if (NULL != this->incomplete)
free(this->incomplete);
if (NULL != this->cur_request)
delete(&(this->cur_request));
FREE(this->incomplete);
delete(this->cur_request);
}
INIT_IFACE(Class, ctor, dtor, NULL);
INIT_IFACE(Class, requestParserCtor, requestParserDtor, NULL);
INIT_IFACE(StreamReader, (fptr_streamReaderRead)httpRequestParserParse);
CREATE_CLASS(HttpRequestParser, NULL, IFACE(Class), IFACE(StreamReader));

8
src/http/response.c

@ -36,7 +36,7 @@
static
int
ctor(void * _this, va_list * params)
httpResponseCtor(void * _this, va_list * params)
{
HttpResponse this = _this;
char * reason;
@ -54,11 +54,11 @@ ctor(void * _this, va_list * params)
static
void
dtor(void * _this)
httpResponseDtor(void * _this)
{
HttpResponse this = _this;
ffree((void **)&(this->reason));
FREE(this->reason);
PARENTCALL(_this, Class, dtor);
}
@ -99,7 +99,7 @@ toString(void * _this, char * string)
return string;
}
INIT_IFACE(Class, ctor, dtor, NULL);
INIT_IFACE(Class, httpResponseCtor, httpResponseDtor, NULL);
INIT_IFACE(HttpIntro, sizeGet, toString);
CREATE_CLASS(
HttpResponse,

33
src/http/response/304.c

@ -20,11 +20,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <time.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "class.h"
#include "interface/class.h"
@ -34,44 +29,24 @@
HttpResponse
httpResponse304(int handle, const char * content_type)
httpResponse304(const char * mime, const char * etag, const char * mtime)
{
time_t t;
struct tm * tmp;
char buffer[200];
struct stat st;
HttpResponse response;
HttpMessage message;
fstat(handle, &st);
response = new(HttpResponse, "HTTP/1.1", 304, "Not Modified");
message = (HttpMessage)response;
httpHeaderAdd(&(message->header),
new(HttpHeader, "Content-Type", content_type));
httpHeaderAdd(&(message->header),
new(HttpHeader, "Server", "testserver"));
message->type = HTTP_MESSAGE_BUFFERED;
message->nbody = 0;
message->body = NULL;
tmp = localtime(&(st.st_mtime));
strftime(buffer, sizeof(buffer), "%s", tmp);
httpHeaderAdd(&(message->header),
new(HttpHeader, "ETag", buffer));
tmp = localtime(&(st.st_mtime));
strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp);
new(HttpHeader, "Content-Type", mime));
httpHeaderAdd(&(message->header),
new(HttpHeader, "Last-Modified", buffer));
t = time(NULL);
tmp = localtime(&t);
strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp);
new(HttpHeader, "ETag", etag));
httpHeaderAdd(&(message->header),
new(HttpHeader, "Date", buffer));
new(HttpHeader, "Last-Modified", mtime));
return response;
}

2
src/http/response/404.c

@ -53,8 +53,6 @@ httpResponse404()
httpHeaderAdd(&(message->header),
new(HttpHeader, "Content-Type", "text/html"));
httpHeaderAdd(&(message->header),
new(HttpHeader, "Server", "testserver"));
message->type = HTTP_MESSAGE_BUFFERED;
message->nbody = sizeof(RESP_DATA) - 1;

42
src/http/response/jquery.c → src/http/response/asset.c

@ -21,9 +21,9 @@
*/
#include <stdio.h>
#include <time.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include "class.h"
#include "interface/class.h"
@ -34,43 +34,45 @@
HttpResponse
httpResponseJquery(int handle)
httpResponseAsset(const char * fname, const char * mime, const char * match)
{
time_t t;
struct tm * tmp;
char buffer[200];
char etag[200];
char mtime[200];
char clen[200];
struct stat st;
HttpResponse response;
HttpMessage message;
int handle;
handle = open(fname, O_RDONLY);
fstat(handle, &st);
tmp = localtime(&(st.st_mtime));
strftime(etag, sizeof(etag), "%s", tmp);
strftime(mtime, sizeof(mtime), "%a, %d %b %Y %T %Z", tmp);
if (0 == strcmp(etag, match)) {
return httpResponse304(mime, etag, mtime);
}
response = new(HttpResponse, "HTTP/1.1", 200, "OK");
message = (HttpMessage)response;
httpHeaderAdd(&(message->header),
new(HttpHeader, "Content-Type", "text/javascript"));
httpHeaderAdd(&(message->header),
new(HttpHeader, "Server", "testserver"));
message->type = HTTP_MESSAGE_PIPED;
message->handle = handle;
message->nbody = st.st_size;
sprintf(buffer, "%d", message->nbody);
httpHeaderAdd(&(message->header),
new(HttpHeader, "Content-Length", buffer));
sprintf(clen, "%d", message->nbody);
tmp = localtime(&(st.st_mtime));
strftime(buffer, sizeof(buffer), "%s", tmp);
httpHeaderAdd(&(message->header),
new(HttpHeader, "ETag", buffer));
t = time(NULL);
tmp = localtime(&t);
strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp);
new(HttpHeader, "Content-Type", mime));
httpHeaderAdd(&(message->header),
new(HttpHeader, "Content-Length", clen));
httpHeaderAdd(&(message->header),
new(HttpHeader, "ETag", etag));
httpHeaderAdd(&(message->header),
new(HttpHeader, "Date", buffer));
new(HttpHeader, "Last-Modified", mtime));
return response;
}

75
src/http/response/image.c

@ -1,75 +0,0 @@
/**
* \file
*
* \author Georg Hopp
*
* \copyright
* Copyright (C) 2012 Georg Hopp
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "class.h"
#include "interface/class.h"
#include "http/response.h"
#include "http/message.h"
#include "http/header.h"
HttpResponse
httpResponseImage(int handle)
{
char buffer[200];
struct stat st;
HttpResponse response;
HttpMessage message;
fstat(handle, &st);
response = new(HttpResponse, "HTTP/1.1", 200, "OK");
message = (HttpMessage)response;
httpHeaderAdd(&(message->header),
new(HttpHeader, "Content-Type", "image/jpeg"));
httpHeaderAdd(&(message->header),
new(HttpHeader, "Server", "testserver"));
message->type = HTTP_MESSAGE_PIPED;
message->handle = handle;
message->nbody = st.st_size;
sprintf(buffer, "%d", message->nbody);
httpHeaderAdd(&(message->header),
new(HttpHeader, "Content-Length", buffer));
tmp = localtime(&(st.st_mtime));
strftime(buffer, sizeof(buffer), "%s", tmp);
httpHeaderAdd(&(message->header),
new(HttpHeader, "ETag", buffer));
t = time(NULL);
tmp = localtime(&t);
strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp);
httpHeaderAdd(&(message->header),
new(HttpHeader, "Date", buffer));
return response;
}
// vim: set ts=4 sw=4:

2
src/http/response/me.c

@ -68,8 +68,6 @@ httpResponseMe(int value)
httpHeaderAdd(&(message->header),
new(HttpHeader, "Content-Type", "text/html"));
httpHeaderAdd(&(message->header),
new(HttpHeader, "Server", "testserver"));
httpHeaderAdd(&(message->header),
new(HttpHeader, "Set-Cookie", "name=\"Georg Hopp\""));
httpHeaderAdd(&(message->header),

10
src/http/response/writer.c

@ -31,7 +31,7 @@
static
int
ctor(void * _this, va_list * params)
responseWriterCtor(void * _this, va_list * params)
{
HttpResponseWriter this = _this;
@ -43,20 +43,20 @@ ctor(void * _this, va_list * params)
static
void
dtor(void * _this)
responseWriterDtor(void * _this)
{
HttpResponseWriter this = _this;
delete(&(this->response_queue));
delete(this->response_queue);
if (TRUE == this->ourLock)
cbufRelease(this->buffer);
if (NULL != this->cur_response)
delete(&(this->cur_response));
delete(this->cur_response);
}
INIT_IFACE(Class, ctor, dtor, NULL);
INIT_IFACE(Class, responseWriterCtor, responseWriterDtor, NULL);
INIT_IFACE(StreamWriter, (fptr_streamWriterWrite)httpResponseWriterWrite);
CREATE_CLASS(HttpResponseWriter, NULL, IFACE(Class), IFACE(StreamWriter));

4
src/http/response/writer/write.c

@ -143,13 +143,13 @@ httpResponseWriterWrite(HttpResponseWriter this, int fd)
*/
cbufRelease(this->buffer);
this->ourLock = FALSE;
delete(&this->cur_response);
delete(this->cur_response);
return -1;
}
cbufRelease(this->buffer);
this->ourLock = FALSE;
delete(&this->cur_response);
delete(this->cur_response);
break;
}

19
src/http/worker.c

@ -13,10 +13,11 @@
#include "interface/stream_reader.h"
#include "interface/stream_writer.h"
#define SHMN "/worker_"
#include "utils/memory.h"
static
int
ctor(void * _this, va_list * params)
httpWorkerCtor(void * _this, va_list * params)
{
HttpWorker this = _this;
char * id = va_arg(*params, char *);
@ -41,17 +42,17 @@ ctor(void * _this, va_list * params)
static
void
dtor(void * _this)
httpWorkerDtor(void * _this)
{
HttpWorker this = _this;
if (NULL != this->id) free(this->id);
FREE(this->id);
delete(&(this->parser));
delete(&(this->writer));
delete(this->parser);
delete(this->writer);
if (NULL != this->pbuf) delete(&(this->pbuf));
if (NULL != this->wbuf) delete(&(this->wbuf));
if (NULL != this->pbuf) delete(this->pbuf);
if (NULL != this->wbuf) delete(this->wbuf);
}
static
@ -70,7 +71,7 @@ _clone(void * _this, void * _base)
this->writer = new(HttpResponseWriter, base->wbuf);
}
INIT_IFACE(Class, ctor, dtor, _clone);
INIT_IFACE(Class, httpWorkerCtor, httpWorkerDtor, _clone);
INIT_IFACE(StreamReader, (fptr_streamReaderRead)httpWorkerProcess);
INIT_IFACE(StreamWriter, (fptr_streamWriterWrite)httpWorkerWrite);
CREATE_CLASS(

37
src/http/worker/add_common_header.c

@ -0,0 +1,37 @@
#include <time.h>
#include "class.h"
#include "interface/class.h"
#include "http/message.h"
#include "http/response.h"
void
httpWorkerAddCommonHeader(HttpMessage request, HttpMessage response)
{
time_t t;
struct tm * tmp;
char buffer[200];
if (httpMessageHasKeepAlive(request)) {
httpHeaderAdd(
&(response->header),
new(HttpHeader, "Connection", "Keep-Alive"));
}
else {
httpHeaderAdd(
&(response->header),
new(HttpHeader, "Connection", "Close"));
}
httpHeaderAdd(&(response->header),
new(HttpHeader, "Server", "testserver"));
t = time(NULL);
tmp = localtime(&t);
strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp);
httpHeaderAdd(&(response->header),
new(HttpHeader, "Date", buffer));
}
// vim: set ts=4 sw=4:

29
src/http/worker/get_asset.c

@ -0,0 +1,29 @@
#include "http/header.h"
#include "http/message.h"
#include "http/request.h"
#include "http/response.h"
HttpMessage
httpWorkerGetAsset(
HttpRequest request,
const char * fname,
const char * mime)
{
char * match;
HttpHeader header;
header = httpHeaderGet(
&(((HttpMessage)request)->header),
"If-None-Match");
if (NULL == header) {
match = "";
}
else {
match = (header->value)[0];
}
return (HttpMessage)httpResponseAsset(fname, mime, match);
}
// vim: set ts=4 sw=4:

76
src/http/worker/process.c

@ -21,18 +21,22 @@
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "class.h"
#include "interface/class.h"
#include "http/worker.h"
#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"
HttpMessage httpWorkerGetAsset(HttpRequest, const char *, const char *);
void httpWorkerAddCommonHeader(HttpMessage, HttpMessage);
ssize_t
httpWorkerProcess(HttpWorker this, int fd)
{
@ -47,57 +51,35 @@ httpWorkerProcess(HttpWorker this, int fd)
HttpMessageQueue respq = this->writer->response_queue;
for (i=0; i<reqq->nmsgs; i++) {
/**
* \todo for now simply remove request and send not found.
* Make this sane.
*/
HttpRequest request = (HttpRequest)(reqq->msgs[i]);
HttpMessage response = NULL;
if (0 == strcmp("GET", request->method) &&
0 == strcmp("/me/", request->uri)) {
response = (HttpMessage)httpResponseMe(*(this->val));
}
else if (0 == strcmp("GET", request->method) &&
0 == strcmp("/image/", request->uri)) {
int handle = open("./assets/waldschrat.jpg", O_RDONLY);
if (NULL != httpHeaderGet(
&(((HttpMessage)request)->header),
"If-None-Match")) {
response = (HttpMessage)httpResponse304(handle, "image/jpeg");
}
else {
response = (HttpMessage)httpResponseImage(handle);
HttpRequest request = (HttpRequest)(reqq->msgs[i]);
HttpMessage response = NULL;
if (0 == strcmp("GET", request->method)) {
if (0 == strcmp("/me/", request->uri)) {
response = (HttpMessage)httpResponseMe(*(this->val));
}
}
else if (0 == strcmp("GET", request->method) &&
0 == strcmp("/jquery/", request->uri)) {
int handle = open("./assets/jquery-1.7.1.min.js", O_RDONLY);
if (NULL != httpHeaderGet(
&(((HttpMessage)request)->header),
"If-None-Match")) {
response = (HttpMessage)httpResponse304(handle, "text/javascript");
if (0 == strcmp("/image/", request->uri)) {
response = httpWorkerGetAsset(
request,
"./assets/waldschrat.jpg",
"image/jpeg");
}
else {
response = (HttpMessage)httpResponseJquery(handle);
if (0 == strcmp("/jquery/", request->uri)) {
response = httpWorkerGetAsset(
request,
"./assets/jquery-1.7.1.min.js",
"text/javascript");
}
}
else {
if (NULL == response) {
response = (HttpMessage)httpResponse404();
}
if (httpMessageHasKeepAlive(reqq->msgs[i])) {
httpHeaderAdd(
&(response->header),
new(HttpHeader, "Connection", "Keep-Alive"));
}
else {
httpHeaderAdd(
&(response->header),
new(HttpHeader, "Connection", "Close"));
}
httpWorkerAddCommonHeader((HttpMessage)request, response);
t = time(NULL);
tmp = localtime(&t);
@ -107,7 +89,7 @@ httpWorkerProcess(HttpWorker this, int fd)
respq->msgs[(respq->nmsgs)++] = response;
response = NULL;
delete(&(reqq->msgs[i]));
delete((reqq->msgs)[i]);
}
reqq->nmsgs = 0;

6
src/logger.c

@ -41,7 +41,7 @@ logger_level_str[] = {
static
int
ctor(void * _this, va_list * params)
loggerCtor(void * _this, va_list * params)
{
Logger this = _this;
this->min_level = va_arg(*params, int);
@ -49,9 +49,9 @@ ctor(void * _this, va_list * params)
return 0;
}
static void dtor(void * _this) {}
static void loggerDtor(void * _this) {}
INIT_IFACE(Class, ctor, dtor, NULL);
INIT_IFACE(Class, loggerCtor, loggerDtor, NULL);
CREATE_CLASS(Logger, NULL, IFACE(Class));
// vim: set ts=4 sw=4:

16
src/server.c

@ -34,7 +34,7 @@
static
int
ctor(void * _this, va_list * params)
serverCtor(void * _this, va_list * params)
{
Server this = _this;
in_port_t port;
@ -73,25 +73,25 @@ ctor(void * _this, va_list * params)
static
void
dtor(void * _this)
serverDtor(void * _this)
{
Server this = _this;
int i;
for (i=0; i<this->nfds; i++) {
if (this->sock->handle != (this->fds)[i].fd) {
delete(&(this->conns[(this->fds)[i].fd]).sock);
delete(&(this->conns[(this->fds)[i].fd]).worker);
delete((this->conns[(this->fds)[i].fd]).sock);
delete((this->conns[(this->fds)[i].fd]).worker);
}
}
FREE(&(this->fds));
FREE(&(this->conns));
FREE(this->fds);
FREE(this->conns);
delete(&this->sock);
delete(this->sock);
}
INIT_IFACE(Class, ctor, dtor, NULL);
INIT_IFACE(Class, serverCtor, serverDtor, NULL);
CREATE_CLASS(Server, NULL, IFACE(Class));
// vim: set ts=4 sw=4:

4
src/server/close_conn.c

@ -31,8 +31,8 @@ serverCloseConn(Server this, unsigned int i)
{
int fd = (this->fds)[i].fd;
delete(&((this->conns)[fd].sock));
delete(&((this->conns)[fd].worker));
delete((this->conns)[fd].sock);
delete((this->conns)[fd].worker);
memset(&(this->fds[i]), 0, sizeof(struct pollfd));
}

2
src/server/handle_accept.c

@ -52,7 +52,7 @@ serverHandleAccept(Server this)
(this->fds)[this->nfds].events = POLLIN;
this->nfds++;
} else {
delete(&acc);
delete(acc);
switch(errno) {
case EAGAIN:

8
src/socket.c

@ -31,7 +31,7 @@
static
int
ctor(void * _this, va_list * params)
socketCtor(void * _this, va_list * params)
{
Sock this = _this;
int reUse = 1; //! \todo make this configurable
@ -44,7 +44,7 @@ ctor(void * _this, va_list * params)
loggerLog(this->log, LOGGER_CRIT,
"error opening socket: %s - service terminated",
strerror(errno));
return;
return -1;
}
//! Make the socket REUSE a TIME_WAIT socket
@ -55,7 +55,7 @@ ctor(void * _this, va_list * params)
static
void
dtor(void * _this)
socketDtor(void * _this)
{
Sock this = _this;
@ -65,7 +65,7 @@ dtor(void * _this)
}
}
INIT_IFACE(Class, ctor, dtor, NULL);
INIT_IFACE(Class, socketCtor, socketDtor, NULL);
CREATE_CLASS(Sock, NULL, IFACE(Class));
// vim: set ts=4 sw=4:

6
src/testserver.c

@ -165,9 +165,9 @@ main()
}
} while (!WIFEXITED(status) && !WIFSIGNALED(status));
if (NULL != server) delete(&server);
if (NULL != worker) delete(&worker);
if (NULL != logger) delete(&logger);
if (NULL != server) delete(server);
if (NULL != worker) delete(worker);
if (NULL != logger) delete(logger);
}
break;

Loading…
Cancel
Save