17 changed files with 335 additions and 85 deletions
-
8ChangeLog
-
2TODO
-
3include/http/header.h
-
4include/http/request.h
-
17include/http/response.h
-
2include/server.h
-
20src/Makefile.am
-
16src/http/header/size_get.c
-
21src/http/header/to_string.c
-
31src/http/request/has_keep_alive.c
-
60src/http/response.c
-
49src/http/response/404.c
-
13src/http/response/header_set.c
-
27src/http/response/size_get.c
-
46src/http/response/to_string.c
-
4src/server.c
-
81src/server/run.c
@ -0,0 +1,2 @@ |
|||
VERY BIG TODO: |
|||
- give a contructor a way to fail, so that no object will be created at all |
|||
@ -1,20 +1,26 @@ |
|||
ACLOCAL_AMFLAGS = -I m4 |
|||
AUTOMAKE_OPTIONS = subdir-objects |
|||
|
|||
CLASS = class.c interface.c interface/class.c |
|||
IFACE = interface/class.c interface/stream_reader.c interface/logger.c |
|||
CLASS = class.c interface.c |
|||
SOCKET = socket.c socket/accept.c socket/connect.c socket/listen.c |
|||
SERVER = server.c server/run.c server/close_conn.c |
|||
LOGGER = logger.c logger/stderr.c logger/syslog.c interface/logger.c |
|||
HTTP = interface/stream_reader.c http/request/parser.c http/request.c \
|
|||
http/request/queue.c http/header.c http/header/get.c \
|
|||
http/header/sort.c http/request/parser/get_header.c \
|
|||
LOGGER = logger.c logger/stderr.c logger/syslog.c |
|||
REQ = http/request.c http/request/queue.c http/request/has_keep_alive.c |
|||
RESP = http/response.c http/response/header_set.c \
|
|||
http/response/404.c http/response/size_get.c \
|
|||
http/response/to_string.c |
|||
HEADER = http/header.c http/header/get.c http/header/sort.c \
|
|||
http/header/size_get.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 |
|||
|
|||
|
|||
AM_CFLAGS = -Wall -I ../include/ |
|||
|
|||
bin_PROGRAMS = testserver |
|||
|
|||
testserver_SOURCES = testserver.c \
|
|||
$(CLASS) $(SOCKET) $(SERVER) $(LOGGER) $(HTTP) \
|
|||
signalHandling.c daemonize.c |
|||
$(IFACE) $(CLASS) $(SOCKET) $(SERVER) $(LOGGER) $(REQ) \
|
|||
$(RESP) $(HEADER) $(PARSER) signalHandling.c daemonize.c |
|||
testserver_CFLAGS = -Wall -I ../include/ |
|||
@ -0,0 +1,16 @@ |
|||
#include <sys/types.h> |
|||
|
|||
#include "http/header.h" |
|||
|
|||
size_t |
|||
httpHeaderSizeGet(HttpHeader header) |
|||
{ |
|||
size_t size = 0; |
|||
|
|||
size += strlen(header->name) + 2; |
|||
size += strlen(header->value); |
|||
|
|||
return size; |
|||
} |
|||
|
|||
// vim: set ts=4 sw=4: |
|||
@ -0,0 +1,21 @@ |
|||
#include <string.h> |
|||
|
|||
#include "http/header.h" |
|||
|
|||
size_t |
|||
httpHeaderToString(HttpHeader header, char * string) |
|||
{ |
|||
size_t size = httpHeaderSizeGet(header); |
|||
|
|||
strcpy(string, header->name); |
|||
string += strlen(string); |
|||
|
|||
*string++ = ':'; |
|||
*string++ = ' '; |
|||
|
|||
strcpy(string, header->value); |
|||
|
|||
return size; |
|||
} |
|||
|
|||
// vim: set ts=4 sw=4: |
|||
@ -0,0 +1,31 @@ |
|||
#include <string.h> |
|||
#include <ctype.h> |
|||
|
|||
#include "http/request.h" |
|||
#include "http/header.h" |
|||
|
|||
|
|||
char |
|||
httpRequestHasKeepAlive(HttpRequest request) |
|||
{ |
|||
char * header; |
|||
char * header_ptr; |
|||
|
|||
header = httpHeaderGet(request->header, request->nheader, "connection"); |
|||
|
|||
if (NULL == header) { |
|||
return 0; |
|||
} |
|||
|
|||
for (header_ptr = header; 0 != *header_ptr; header_ptr++) { |
|||
*header_ptr = tolower(*header_ptr); |
|||
} |
|||
|
|||
if (0 == strcmp(header, "keep-alive")) { |
|||
return 1; |
|||
} |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
// vim: set ts=4 sw=4: |
|||
@ -0,0 +1,60 @@ |
|||
#include <stdlib.h> |
|||
#include <stdarg.h> |
|||
|
|||
#include "class.h" |
|||
#include "interface/class.h" |
|||
|
|||
#include "http/response.h" |
|||
|
|||
|
|||
static |
|||
void |
|||
_free(void ** data) |
|||
{ |
|||
if (NULL != *data) { |
|||
free(*data); |
|||
} |
|||
} |
|||
|
|||
static |
|||
void |
|||
ctor(void * _this, va_list * params) |
|||
{ |
|||
char * version; |
|||
char * reason; |
|||
|
|||
HttpResponse this = _this; |
|||
|
|||
version = va_arg(* params, char *); |
|||
this->status = va_arg(* params, unsigned int); |
|||
reason = va_arg(* params, char *); |
|||
|
|||
this->version = calloc(1, strlen(version)+1); |
|||
strcpy(this->version, version); |
|||
|
|||
this->reason = calloc(1, strlen(reason)+1); |
|||
strcpy(this->reason, reason); |
|||
} |
|||
|
|||
static |
|||
void |
|||
dtor(void * _this) |
|||
{ |
|||
HttpResponse this = _this; |
|||
int i; |
|||
|
|||
_free((void **)&(this->version)); |
|||
_free((void **)&(this->reason)); |
|||
|
|||
for (i=0; i<128; i++) { |
|||
if (NULL == (this->header)[i]) break; |
|||
delete(&(this->header)[i]); |
|||
} |
|||
|
|||
_free((void **)&(this->body)); |
|||
} |
|||
|
|||
INIT_IFACE(Class, ctor, dtor, NULL); |
|||
CREATE_CLASS(HttpResponse, NULL, IFACE(Class)); |
|||
|
|||
// vim: set ts=4 sw=4: |
|||
@ -0,0 +1,49 @@ |
|||
#include <stdlib.h> |
|||
#include <string.h> |
|||
#include <stdio.h> |
|||
#include <time.h> |
|||
|
|||
#include "class.h" |
|||
#include "interface/class.h" |
|||
|
|||
#include "http/response.h" |
|||
|
|||
|
|||
#define RESP_DATA "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" \ |
|||
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" \ |
|||
" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" \ |
|||
"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n" \ |
|||
"<head><title>404 - Not Found</title></head>" \ |
|||
"<body><h1>404 - Not Found</h1></body>" \ |
|||
"</html>" |
|||
|
|||
|
|||
HttpResponse |
|||
httpResponse404() |
|||
{ |
|||
time_t t; |
|||
struct tm * tmp; |
|||
char buffer[200]; |
|||
HttpResponse response; |
|||
|
|||
response = new(HttpResponse, "HTTP/1.1", 404, "Not Found"); |
|||
|
|||
httpResponseHeaderSet(response, "Content-Type", "text/html"); |
|||
httpResponseHeaderSet(response, "Server", "testserver"); |
|||
|
|||
response->nbody = sizeof(RESP_DATA) - 1; |
|||
response->body = calloc(1, sizeof(RESP_DATA)); |
|||
strcpy(response->body, RESP_DATA); |
|||
|
|||
sprintf(buffer, "%d", response->nbody); |
|||
httpResponseHeaderSet(response, "Content-Length", buffer); |
|||
|
|||
t = time(NULL); |
|||
tmp = localtime(&t); |
|||
strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp); |
|||
httpResponseHeaderSet(response, "Date", buffer); |
|||
|
|||
return response; |
|||
} |
|||
|
|||
// vim: set ts=4 sw=4: |
|||
@ -0,0 +1,13 @@ |
|||
#include "class.h" |
|||
#include "interface/class.h" |
|||
|
|||
#include "http/response.h" |
|||
#include "http/header.h" |
|||
|
|||
void |
|||
httpResponseHeaderSet(HttpResponse this, const char * name, const char * value) |
|||
{ |
|||
(this->header)[this->nheader++] = new(HttpHeader, name, value); |
|||
} |
|||
|
|||
// vim: set ts=4 sw=4: |
|||
@ -0,0 +1,27 @@ |
|||
#include <string.h> |
|||
#include <sys/types.h> |
|||
|
|||
#include "http/response.h" |
|||
#include "http/header.h" |
|||
|
|||
size_t |
|||
httpResponseSizeGet(HttpResponse response) |
|||
{ |
|||
int i; |
|||
size_t size = 0; |
|||
|
|||
size += strlen(response->version) + 1; |
|||
size += 4; // for status |
|||
size += strlen(response->reason) + 2; |
|||
|
|||
for (i=0; i<response->nheader; i++) { |
|||
size += httpHeaderSizeGet(response->header[i]) + 2; |
|||
} |
|||
|
|||
size += 2; |
|||
size += response->nbody; |
|||
|
|||
return size; |
|||
} |
|||
|
|||
// vim: set ts=4 sw=4: |
|||
@ -0,0 +1,46 @@ |
|||
#include <string.h> |
|||
#include <stdio.h> |
|||
|
|||
#include "http/response.h" |
|||
#include "http/header.h" |
|||
|
|||
size_t |
|||
httpResponseToString(HttpResponse response, char * string) |
|||
{ |
|||
int i; |
|||
size_t size = httpResponseSizeGet(response); |
|||
char status[4]; |
|||
|
|||
snprintf(status, 4, "%d", response->status); |
|||
|
|||
strcpy(string, response->version); |
|||
string += strlen(string); |
|||
|
|||
*string++ = ' '; |
|||
|
|||
strcpy(string, status); |
|||
string += strlen(string); |
|||
|
|||
*string++ = ' '; |
|||
|
|||
strcpy(string, response->reason); |
|||
string += strlen(string); |
|||
|
|||
*string++ = '\r'; |
|||
*string++ = '\n'; |
|||
|
|||
for (i=0; i<response->nheader; i++) { |
|||
string += httpHeaderToString(response->header[i], string); |
|||
*string++ = '\r'; |
|||
*string++ = '\n'; |
|||
} |
|||
|
|||
*string++ = '\r'; |
|||
*string++ = '\n'; |
|||
|
|||
memcpy(string, response->body, response->nbody); |
|||
|
|||
return size; |
|||
} |
|||
|
|||
// vim: set ts=4 sw=4: |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue