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 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 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 13 2012-02-20 21:36:55 +0100 Georg Hopp
10 14
... ...
... ... @@ -30,15 +30,16 @@
30 30 CLASS(HttpHeader) {
31 31 unsigned long hash;
32 32 char * name;
33   - char * value;
  33 + char ** value;
  34 + size_t nvalue;
34 35 };
35 36
36 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 44 #endif // __HTTP_HEADER_H__
44 45
... ...
... ... @@ -42,6 +42,7 @@ HttpResponse httpResponse304(int, const char *);
42 42 HttpResponse httpResponse404();
43 43 HttpResponse httpResponseMe(int);
44 44 HttpResponse httpResponseImage(int);
  45 +HttpResponse httpResponseJquery(int);
45 46
46 47 #endif // __HTTP_RESPONSE_H__
47 48
... ...
... ... @@ -24,6 +24,7 @@ RESP = http/response.c \
24 24 http/response/304.c \
25 25 http/response/404.c \
26 26 http/response/image.c \
  27 + http/response/jquery.c \
27 28 http/response/me.c
28 29 WORKER = http/worker.c http/worker/process.c http/worker/write.c
29 30 WRITER = http/response/writer.c http/response/writer/write.c
... ...
... ... @@ -29,6 +29,7 @@
29 29 #include "http/header.h"
30 30
31 31 #include "utils/hash.h"
  32 +#include "utils/memory.h"
32 33
33 34 static
34 35 int
... ... @@ -45,8 +46,9 @@ ctor(void * _this, va_list * params) {
45 46
46 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 53 return 0;
52 54 }
... ... @@ -56,9 +58,14 @@ void
56 58 dtor(void * _this)
57 59 {
58 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 71 INIT_IFACE(Class, ctor, dtor, NULL);
... ...
... ... @@ -22,6 +22,8 @@
22 22
23 23 #include <search.h>
24 24 #include <stdio.h>
  25 +#include <stdlib.h>
  26 +#include <string.h>
25 27
26 28 #include "class.h"
27 29 #include "interface/class.h"
... ... @@ -44,9 +46,9 @@ httpHeaderAdd(const HttpHeader * root, HttpHeader header)
44 46 HttpHeader * found = tsearch(header, (void **)root, comp);
45 47
46 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 52 delete(&header);
51 53 }
52 54 }
... ...
... ... @@ -38,13 +38,13 @@ comp(const void * _a, const void * _b)
38 38 return (a->hash < b->hash)? -1 : (a->hash > b->hash)? 1 : 0;
39 39 }
40 40
41   -char *
  41 +HttpHeader
42 42 httpHeaderGet(const HttpHeader * root, const char * name)
43 43 {
44 44 struct c_HttpHeader search = {sdbm((const unsigned char*)name), NULL, NULL};
45 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 50 // vim: set ts=4 sw=4:
... ...
... ... @@ -29,9 +29,12 @@ size_t
29 29 httpHeaderSizeGet(HttpHeader header)
30 30 {
31 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 39 return size;
37 40 }
... ...
... ... @@ -29,14 +29,21 @@ size_t
29 29 httpHeaderToString(HttpHeader header, char * string)
30 30 {
31 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 48 return size;
42 49 }
... ...
... ... @@ -31,8 +31,8 @@
31 31 char
32 32 httpMessageHasKeepAlive(HttpMessage message)
33 33 {
34   - char * header;
35   - char * header_ptr;
  34 + HttpHeader header;
  35 + char * con;
36 36
37 37 header = httpHeaderGet(&(message->header), "connection");
38 38
... ... @@ -40,11 +40,12 @@ httpMessageHasKeepAlive(HttpMessage message)
40 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 49 return 1;
49 50 }
50 51
... ...
... ... @@ -37,7 +37,7 @@ void
37 37 addHeaderSize(const void * node, const VISIT which, const int depth)
38 38 {
39 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 35 {
36 36 if (endorder == which || leaf == which) {
37 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 43 size_t len;
44 44
45 45 if (0 == message->nbody) {
46   - char * nbody = httpHeaderGet(
  46 + HttpHeader clen = httpHeaderGet(
47 47 &(message->header),
48 48 "Content-Length");
49 49
50   - if (NULL == nbody) {
  50 + if (NULL == clen) {
51 51 this->state = HTTP_REQUEST_DONE;
52 52 return;
53 53 }
54 54 else {
55 55 message->type = HTTP_MESSAGE_BUFFERED;
56   - message->nbody = atoi(nbody);
  56 + message->nbody = atoi((clen->value)[0]);
57 57 message->body = calloc(1, message->nbody);
58 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 35 #define RESP_DATA "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" \
36 36 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" \
37 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 56 "</html>"
42 57
43 58
... ... @@ -55,6 +70,10 @@ httpResponseMe(int value)
55 70 new(HttpHeader, "Content-Type", "text/html"));
56 71 httpHeaderAdd(&(message->header),
57 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 78 message->type = HTTP_MESSAGE_BUFFERED;
60 79 message->nbody = sizeof(RESP_DATA) - 1;
... ...
... ... @@ -71,6 +71,19 @@ httpWorkerProcess(HttpWorker this, int fd)
71 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 87 else {
75 88 response = (HttpMessage)httpResponse404();
76 89 }
... ...
... ... @@ -42,10 +42,10 @@
42 42
43 43 #include "utils/signalHandling.h"
44 44
45   -//#define DEFAULT_SECS 0
46   -//#define DEFAULT_USECS (1000000 / HZ)
47 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 50 void nullhandler() {}
51 51
... ... @@ -103,16 +103,16 @@ main()
103 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 109 interval.it_interval.tv_usec = DEFAULT_USECS;
110 110
111 111 setitimer(ITIMER_REAL, &interval, NULL);
112 112
113 113 // child
114 114 while(!doShutdown) {
115   - *value = rand() % 10;
  115 + *value = rand() % 100;
116 116 sigsuspend(&pause_mask);
117 117 }
118 118
... ...
Please register or login to post a comment