Commit 59ccbf0207cf5acca3668f56cb5dc1f6da0de3c0

Authored by Georg Hopp
1 parent 424297cd

closes #10: values for header ids are now stored in a char ** making multiple va…

…lues for one id possible. Additionally added a jquery action that delivers the jquery java script and use it on the me action
  1 +2012-02-22 08:48:43 +0100 Georg Hopp
  2 +
  3 + * closes #10: values for header ids are now stored in a char ** making multiple values for one id possible. Additionally added a jquery action that delivers the jquery java script and use it on the me action (HEAD, master)
  4 +
1 2012-02-21 13:01:38 +0100 Georg Hopp 5 2012-02-21 13:01:38 +0100 Georg Hopp
2 6
3 - * now when a constructor returns -1 the new call will in turn call the destructor effectively freeing all resources. ATTENTION: now the destructor has to be aware that it might be called with a not completely initialized object. To make this more ease there is the FREE makro with the corresponding ffree that does NULL pointer checking and the destructor checks for NULL pointer too. Additionally the handle_accept now handles _SC_OPEN_MAX - 10 connections. The 10 are reserved for internal usage. (HEAD, master) 7 + * now when a constructor returns -1 the new call will in turn call the destructor effectively freeing all resources. ATTENTION: now the destructor has to be aware that it might be called with a not completely initialized object. To make this more ease there is the FREE makro with the corresponding ffree that does NULL pointer checking and the destructor checks for NULL pointer too. Additionally the handle_accept now handles _SC_OPEN_MAX - 10 connections. The 10 are reserved for internal usage. (origin/master, origin/HEAD)
4 8
5 2012-02-21 09:45:01 +0100 Georg Hopp 9 2012-02-21 09:45:01 +0100 Georg Hopp
6 10
7 - * now a child is spawned and writes random values in a shared memory segment. These values will be shown in the me action (origin/master, origin/HEAD) 11 + * now a child is spawned and writes random values in a shared memory segment. These values will be shown in the me action
8 12
9 2012-02-20 21:36:55 +0100 Georg Hopp 13 2012-02-20 21:36:55 +0100 Georg Hopp
10 14
@@ -30,15 +30,16 @@ @@ -30,15 +30,16 @@
30 CLASS(HttpHeader) { 30 CLASS(HttpHeader) {
31 unsigned long hash; 31 unsigned long hash;
32 char * name; 32 char * name;
33 - char * value; 33 + char ** value;
  34 + size_t nvalue;
34 }; 35 };
35 36
36 HttpHeader httpHeaderParse(char * line); // @INFO: destructive 37 HttpHeader httpHeaderParse(char * line); // @INFO: destructive
37 38
38 -void httpHeaderAdd(const HttpHeader *, HttpHeader);  
39 -char * httpHeaderGet(const HttpHeader *, const char *);  
40 -size_t httpHeaderSizeGet(HttpHeader);  
41 -size_t httpHeaderToString(HttpHeader, char *); 39 +void httpHeaderAdd(const HttpHeader *, HttpHeader);
  40 +HttpHeader httpHeaderGet(const HttpHeader *, const char *);
  41 +size_t httpHeaderSizeGet(HttpHeader);
  42 +size_t httpHeaderToString(HttpHeader, char *);
42 43
43 #endif // __HTTP_HEADER_H__ 44 #endif // __HTTP_HEADER_H__
44 45
@@ -42,6 +42,7 @@ HttpResponse httpResponse304(int, const char *); @@ -42,6 +42,7 @@ HttpResponse httpResponse304(int, const char *);
42 HttpResponse httpResponse404(); 42 HttpResponse httpResponse404();
43 HttpResponse httpResponseMe(int); 43 HttpResponse httpResponseMe(int);
44 HttpResponse httpResponseImage(int); 44 HttpResponse httpResponseImage(int);
  45 +HttpResponse httpResponseJquery(int);
45 46
46 #endif // __HTTP_RESPONSE_H__ 47 #endif // __HTTP_RESPONSE_H__
47 48
@@ -24,6 +24,7 @@ RESP = http/response.c \ @@ -24,6 +24,7 @@ RESP = http/response.c \
24 http/response/304.c \ 24 http/response/304.c \
25 http/response/404.c \ 25 http/response/404.c \
26 http/response/image.c \ 26 http/response/image.c \
  27 + http/response/jquery.c \
27 http/response/me.c 28 http/response/me.c
28 WORKER = http/worker.c http/worker/process.c http/worker/write.c 29 WORKER = http/worker.c http/worker/process.c http/worker/write.c
29 WRITER = http/response/writer.c http/response/writer/write.c 30 WRITER = http/response/writer.c http/response/writer/write.c
@@ -29,6 +29,7 @@ @@ -29,6 +29,7 @@
29 #include "http/header.h" 29 #include "http/header.h"
30 30
31 #include "utils/hash.h" 31 #include "utils/hash.h"
  32 +#include "utils/memory.h"
32 33
33 static 34 static
34 int 35 int
@@ -45,8 +46,9 @@ ctor(void * _this, va_list * params) { @@ -45,8 +46,9 @@ ctor(void * _this, va_list * params) {
45 46
46 this->hash = sdbm((unsigned char *)name); 47 this->hash = sdbm((unsigned char *)name);
47 48
48 - this->value = malloc(strlen(value) + 1);  
49 - strcpy(this->value, value); 49 + this->value = malloc(sizeof(char*) * (++this->nvalue));
  50 + this->value[this->nvalue - 1] = malloc(strlen(value) + 1);
  51 + strcpy(this->value[this->nvalue - 1], value);
50 52
51 return 0; 53 return 0;
52 } 54 }
@@ -56,9 +58,14 @@ void @@ -56,9 +58,14 @@ void
56 dtor(void * _this) 58 dtor(void * _this)
57 { 59 {
58 HttpHeader this = _this; 60 HttpHeader this = _this;
  61 + size_t i;
59 62
60 - free(this->name);  
61 - free(this->value); 63 + FREE(&(this->name));
  64 +
  65 + for (i=0; i<this->nvalue; i++) {
  66 + FREE(&(this->value[i]));
  67 + }
  68 + FREE(&(this->value));
62 } 69 }
63 70
64 INIT_IFACE(Class, ctor, dtor, NULL); 71 INIT_IFACE(Class, ctor, dtor, NULL);
@@ -22,6 +22,8 @@ @@ -22,6 +22,8 @@
22 22
23 #include <search.h> 23 #include <search.h>
24 #include <stdio.h> 24 #include <stdio.h>
  25 +#include <stdlib.h>
  26 +#include <string.h>
25 27
26 #include "class.h" 28 #include "class.h"
27 #include "interface/class.h" 29 #include "interface/class.h"
@@ -44,9 +46,9 @@ httpHeaderAdd(const HttpHeader * root, HttpHeader header) @@ -44,9 +46,9 @@ httpHeaderAdd(const HttpHeader * root, HttpHeader header)
44 HttpHeader * found = tsearch(header, (void **)root, comp); 46 HttpHeader * found = tsearch(header, (void **)root, comp);
45 47
46 if (*found != header) { 48 if (*found != header) {
47 - puts("uhh, duplicate header set. "  
48 - "This is not implemented right now. "  
49 - "Keep the first one found."); 49 + (*found)->value = realloc((*found)->value, sizeof(char) * (++(*found)->nvalue));
  50 + (*found)->value[(*found)->nvalue - 1] = malloc(strlen(header->value) + 1);
  51 + strcpy(((*found)->value)[(*found)->nvalue - 1], (header->value)[0]);
50 delete(&header); 52 delete(&header);
51 } 53 }
52 } 54 }
@@ -38,13 +38,13 @@ comp(const void * _a, const void * _b) @@ -38,13 +38,13 @@ comp(const void * _a, const void * _b)
38 return (a->hash < b->hash)? -1 : (a->hash > b->hash)? 1 : 0; 38 return (a->hash < b->hash)? -1 : (a->hash > b->hash)? 1 : 0;
39 } 39 }
40 40
41 -char * 41 +HttpHeader
42 httpHeaderGet(const HttpHeader * root, const char * name) 42 httpHeaderGet(const HttpHeader * root, const char * name)
43 { 43 {
44 struct c_HttpHeader search = {sdbm((const unsigned char*)name), NULL, NULL}; 44 struct c_HttpHeader search = {sdbm((const unsigned char*)name), NULL, NULL};
45 HttpHeader * found = tfind(&search, (void**)root, comp); 45 HttpHeader * found = tfind(&search, (void**)root, comp);
46 46
47 - return (NULL != found)? (*found)->value : NULL; 47 + return (NULL != found)? *found : NULL;
48 } 48 }
49 49
50 // vim: set ts=4 sw=4: 50 // vim: set ts=4 sw=4:
@@ -29,9 +29,12 @@ size_t @@ -29,9 +29,12 @@ size_t
29 httpHeaderSizeGet(HttpHeader header) 29 httpHeaderSizeGet(HttpHeader header)
30 { 30 {
31 size_t size = 0; 31 size_t size = 0;
  32 + int i;
32 33
33 - size += strlen(header->name) + 2;  
34 - size += strlen(header->value); 34 + for (i=0; i<header->nvalue; i++) {
  35 + size += strlen(header->name) + 2;
  36 + size += strlen(header->value[i]) + 2;
  37 + }
35 38
36 return size; 39 return size;
37 } 40 }
@@ -29,14 +29,21 @@ size_t @@ -29,14 +29,21 @@ size_t
29 httpHeaderToString(HttpHeader header, char * string) 29 httpHeaderToString(HttpHeader header, char * string)
30 { 30 {
31 size_t size = httpHeaderSizeGet(header); 31 size_t size = httpHeaderSizeGet(header);
  32 + int i;
32 33
33 - strcpy(string, header->name);  
34 - string += strlen(string); 34 + for (i=0; i<header->nvalue; i++) {
  35 + strcpy(string, header->name);
  36 + string += strlen(string);
35 37
36 - *string++ = ':';  
37 - *string++ = ' '; 38 + *string++ = ':';
  39 + *string++ = ' ';
38 40
39 - strcpy(string, header->value); 41 + strcpy(string, header->value[i]);
  42 + string += strlen(string);
  43 +
  44 + *string++ = '\r';
  45 + *string++ = '\n';
  46 + }
40 47
41 return size; 48 return size;
42 } 49 }
@@ -31,8 +31,8 @@ @@ -31,8 +31,8 @@
31 char 31 char
32 httpMessageHasKeepAlive(HttpMessage message) 32 httpMessageHasKeepAlive(HttpMessage message)
33 { 33 {
34 - char * header;  
35 - char * header_ptr; 34 + HttpHeader header;
  35 + char * con;
36 36
37 header = httpHeaderGet(&(message->header), "connection"); 37 header = httpHeaderGet(&(message->header), "connection");
38 38
@@ -40,11 +40,12 @@ httpMessageHasKeepAlive(HttpMessage message) @@ -40,11 +40,12 @@ httpMessageHasKeepAlive(HttpMessage message)
40 return 0; 40 return 0;
41 } 41 }
42 42
43 - for (header_ptr = header; 0 != *header_ptr; header_ptr++) {  
44 - *header_ptr = tolower(*header_ptr); 43 + con = (header->value)[0];
  44 + for (; 0 != *con; con++) {
  45 + *con = tolower(*con);
45 } 46 }
46 47
47 - if (0 == strcmp(header, "keep-alive")) { 48 + if (0 == strcmp(con, "keep-alive")) {
48 return 1; 49 return 1;
49 } 50 }
50 51
@@ -37,7 +37,7 @@ void @@ -37,7 +37,7 @@ void
37 addHeaderSize(const void * node, const VISIT which, const int depth) 37 addHeaderSize(const void * node, const VISIT which, const int depth)
38 { 38 {
39 if (endorder == which || leaf == which) { 39 if (endorder == which || leaf == which) {
40 - size += httpHeaderSizeGet(*(HttpHeader *)node) + 2; 40 + size += httpHeaderSizeGet(*(HttpHeader *)node);
41 } 41 }
42 } 42 }
43 43
@@ -35,8 +35,6 @@ addHeaderString(const void * node, const VISIT which, const int depth) @@ -35,8 +35,6 @@ addHeaderString(const void * node, const VISIT which, const int depth)
35 { 35 {
36 if (endorder == which || leaf == which) { 36 if (endorder == which || leaf == which) {
37 string += httpHeaderToString(*(HttpHeader *)node, string); 37 string += httpHeaderToString(*(HttpHeader *)node, string);
38 - *string++ = '\r';  
39 - *string++ = '\n';  
40 } 38 }
41 } 39 }
42 40
@@ -43,17 +43,17 @@ httpRequestParserGetBody(HttpRequestParser this) @@ -43,17 +43,17 @@ httpRequestParserGetBody(HttpRequestParser this)
43 size_t len; 43 size_t len;
44 44
45 if (0 == message->nbody) { 45 if (0 == message->nbody) {
46 - char * nbody = httpHeaderGet( 46 + HttpHeader clen = httpHeaderGet(
47 &(message->header), 47 &(message->header),
48 "Content-Length"); 48 "Content-Length");
49 49
50 - if (NULL == nbody) { 50 + if (NULL == clen) {
51 this->state = HTTP_REQUEST_DONE; 51 this->state = HTTP_REQUEST_DONE;
52 return; 52 return;
53 } 53 }
54 else { 54 else {
55 message->type = HTTP_MESSAGE_BUFFERED; 55 message->type = HTTP_MESSAGE_BUFFERED;
56 - message->nbody = atoi(nbody); 56 + message->nbody = atoi((clen->value)[0]);
57 message->body = calloc(1, message->nbody); 57 message->body = calloc(1, message->nbody);
58 message->dbody = 0; 58 message->dbody = 0;
59 } 59 }
  1 +/**
  2 + * \file
  3 + *
  4 + * \author Georg Hopp
  5 + *
  6 + * \copyright
  7 + * Copyright (C) 2012 Georg Hopp
  8 + *
  9 + * This program is free software: you can redistribute it and/or modify
  10 + * it under the terms of the GNU General Public License as published by
  11 + * the Free Software Foundation, either version 3 of the License, or
  12 + * (at your option) any later version.
  13 + *
  14 + * This program is distributed in the hope that it will be useful,
  15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17 + * GNU General Public License for more details.
  18 + *
  19 + * You should have received a copy of the GNU General Public License
  20 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21 + */
  22 +
  23 +#include <stdio.h>
  24 +#include <time.h>
  25 +#include <sys/stat.h>
  26 +#include <fcntl.h>
  27 +
  28 +#include "class.h"
  29 +#include "interface/class.h"
  30 +
  31 +#include "http/response.h"
  32 +#include "http/message.h"
  33 +#include "http/header.h"
  34 +
  35 +
  36 +HttpResponse
  37 +httpResponseJquery(int handle)
  38 +{
  39 + time_t t;
  40 + struct tm * tmp;
  41 + char buffer[200];
  42 + struct stat st;
  43 + HttpResponse response;
  44 + HttpMessage message;
  45 +
  46 + fstat(handle, &st);
  47 +
  48 + response = new(HttpResponse, "HTTP/1.1", 200, "OK");
  49 + message = (HttpMessage)response;
  50 +
  51 + httpHeaderAdd(&(message->header),
  52 + new(HttpHeader, "Content-Type", "text/javascript"));
  53 + httpHeaderAdd(&(message->header),
  54 + new(HttpHeader, "Server", "testserver"));
  55 +
  56 + message->type = HTTP_MESSAGE_PIPED;
  57 + message->handle = handle;
  58 + message->nbody = st.st_size;
  59 +
  60 + sprintf(buffer, "%d", message->nbody);
  61 + httpHeaderAdd(&(message->header),
  62 + new(HttpHeader, "Content-Length", buffer));
  63 +
  64 + tmp = localtime(&(st.st_mtime));
  65 + strftime(buffer, sizeof(buffer), "%s", tmp);
  66 + httpHeaderAdd(&(message->header),
  67 + new(HttpHeader, "ETag", buffer));
  68 +
  69 + t = time(NULL);
  70 + tmp = localtime(&t);
  71 + strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp);
  72 + httpHeaderAdd(&(message->header),
  73 + new(HttpHeader, "Date", buffer));
  74 +
  75 + return response;
  76 +}
  77 +
  78 +// vim: set ts=4 sw=4:
@@ -35,9 +35,24 @@ @@ -35,9 +35,24 @@
35 #define RESP_DATA "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" \ 35 #define RESP_DATA "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" \
36 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" \ 36 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" \
37 " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" \ 37 " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" \
38 - "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n" \  
39 - "<head><title>200 - OK</title></head>" \  
40 - "<body><h1>200 - OK</h1><img src=\"/image/\" /><hr />%02d</body>" \ 38 + "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">" \
  39 + "<head>" \
  40 + "<title>200 - OK</title>" \
  41 + "<script type=\"text/javascript\" src=\"/jquery/\"></script>" \
  42 + "<script>" \
  43 + "$(document).ready(function() {" \
  44 + "$(\"a\").click(function() {" \
  45 + "alert(\"Hello world!\");" \
  46 + "});" \
  47 + "});" \
  48 + "</script>" \
  49 + "</head>" \
  50 + "<body>" \
  51 + "<h1>Testpage</h1>" \
  52 + "<img src=\"/image/\" />" \
  53 + "<hr />%02d" \
  54 + "<hr /><a href=\"#\">Link</a>" \
  55 + "</body>" \
41 "</html>" 56 "</html>"
42 57
43 58
@@ -55,6 +70,10 @@ httpResponseMe(int value) @@ -55,6 +70,10 @@ httpResponseMe(int value)
55 new(HttpHeader, "Content-Type", "text/html")); 70 new(HttpHeader, "Content-Type", "text/html"));
56 httpHeaderAdd(&(message->header), 71 httpHeaderAdd(&(message->header),
57 new(HttpHeader, "Server", "testserver")); 72 new(HttpHeader, "Server", "testserver"));
  73 + httpHeaderAdd(&(message->header),
  74 + new(HttpHeader, "Set-Cookie", "name=\"Georg Hopp\""));
  75 + httpHeaderAdd(&(message->header),
  76 + new(HttpHeader, "Set-Cookie", "profession=\"coder\""));
58 77
59 message->type = HTTP_MESSAGE_BUFFERED; 78 message->type = HTTP_MESSAGE_BUFFERED;
60 message->nbody = sizeof(RESP_DATA) - 1; 79 message->nbody = sizeof(RESP_DATA) - 1;
@@ -71,6 +71,19 @@ httpWorkerProcess(HttpWorker this, int fd) @@ -71,6 +71,19 @@ httpWorkerProcess(HttpWorker this, int fd)
71 response = (HttpMessage)httpResponseImage(handle); 71 response = (HttpMessage)httpResponseImage(handle);
72 } 72 }
73 } 73 }
  74 + else if (0 == strcmp("GET", request->method) &&
  75 + 0 == strcmp("/jquery/", request->uri)) {
  76 + int handle = open("./assets/jquery-1.7.1.min.js", O_RDONLY);
  77 +
  78 + if (NULL != httpHeaderGet(
  79 + &(((HttpMessage)request)->header),
  80 + "If-None-Match")) {
  81 + response = (HttpMessage)httpResponse304(handle, "text/javascript");
  82 + }
  83 + else {
  84 + response = (HttpMessage)httpResponseJquery(handle);
  85 + }
  86 + }
74 else { 87 else {
75 response = (HttpMessage)httpResponse404(); 88 response = (HttpMessage)httpResponse404();
76 } 89 }
@@ -42,10 +42,10 @@ @@ -42,10 +42,10 @@
42 42
43 #include "utils/signalHandling.h" 43 #include "utils/signalHandling.h"
44 44
45 -//#define DEFAULT_SECS 0  
46 -//#define DEFAULT_USECS (1000000 / HZ)  
47 #define DEFAULT_SECS 1 45 #define DEFAULT_SECS 1
48 -#define DEFAULT_USECS 0 46 +#define DEFAULT_USECS (1000000 / HZ * 2)
  47 +//#define DEFAULT_SECS 1
  48 +//#define DEFAULT_USECS 0
49 49
50 void nullhandler() {} 50 void nullhandler() {}
51 51
@@ -103,16 +103,16 @@ main() @@ -103,16 +103,16 @@ main()
103 exit (1); 103 exit (1);
104 } 104 }
105 105
106 - interval.it_value.tv_sec = DEFAULT_SECS;  
107 - interval.it_value.tv_usec = DEFAULT_USECS;  
108 - interval.it_interval.tv_sec = DEFAULT_SECS; 106 + interval.it_value.tv_sec = DEFAULT_SECS;
  107 + interval.it_value.tv_usec = DEFAULT_USECS;
  108 + interval.it_interval.tv_sec = DEFAULT_SECS;
109 interval.it_interval.tv_usec = DEFAULT_USECS; 109 interval.it_interval.tv_usec = DEFAULT_USECS;
110 110
111 setitimer(ITIMER_REAL, &interval, NULL); 111 setitimer(ITIMER_REAL, &interval, NULL);
112 112
113 // child 113 // child
114 while(!doShutdown) { 114 while(!doShutdown) {
115 - *value = rand() % 10; 115 + *value = rand() % 100;
116 sigsuspend(&pause_mask); 116 sigsuspend(&pause_mask);
117 } 117 }
118 118
Please register or login to post a comment