Commit 59ccbf0207cf5acca3668f56cb5dc1f6da0de3c0
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
Showing
17 changed files
with
179 additions
and
44 deletions
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 | ... | ... |
... | ... | @@ -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 | ... | ... |
... | ... | @@ -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 | } | ... | ... |
src/http/response/jquery.c
0 → 100644
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