Commit a0ec357e0a1299a30285622b206e70477ec64ee4
1 parent
0c3d467b
closes #11: first very crude session handling implementation, no persitence no m…
…emory cleanups, spread over to much files TODO: clean this
Showing
13 changed files
with
475 additions
and
19 deletions
| @@ -43,7 +43,9 @@ HttpResponse httpResponse304( | @@ -43,7 +43,9 @@ HttpResponse httpResponse304( | ||
| 43 | const char *, size_t, | 43 | const char *, size_t, |
| 44 | const char *, size_t); | 44 | const char *, size_t); |
| 45 | HttpResponse httpResponse404(); | 45 | HttpResponse httpResponse404(); |
| 46 | +HttpResponse httpResponse403(); | ||
| 46 | HttpResponse httpResponseMe(); | 47 | HttpResponse httpResponseMe(); |
| 48 | +HttpResponse httpResponseLoginForm(); | ||
| 47 | HttpResponse httpResponseRandval(time_t, int); | 49 | HttpResponse httpResponseRandval(time_t, int); |
| 48 | HttpResponse httpResponseAsset( | 50 | HttpResponse httpResponseAsset( |
| 49 | const char *, | 51 | const char *, |
| @@ -31,6 +31,7 @@ | @@ -31,6 +31,7 @@ | ||
| 31 | #include "http/parser.h" | 31 | #include "http/parser.h" |
| 32 | #include "http/writer.h" | 32 | #include "http/writer.h" |
| 33 | #include "cbuf.h" | 33 | #include "cbuf.h" |
| 34 | +#include "session.h" | ||
| 34 | 35 | ||
| 35 | 36 | ||
| 36 | #ifndef TRUE | 37 | #ifndef TRUE |
| @@ -56,6 +57,8 @@ CLASS(HttpWorker) { | @@ -56,6 +57,8 @@ CLASS(HttpWorker) { | ||
| 56 | 57 | ||
| 57 | HttpParser parser; | 58 | HttpParser parser; |
| 58 | HttpWriter writer; | 59 | HttpWriter writer; |
| 60 | + Session session; | ||
| 61 | + Session * sroot; | ||
| 59 | }; | 62 | }; |
| 60 | 63 | ||
| 61 | #endif // __HTTP_WORKER_H__ | 64 | #endif // __HTTP_WORKER_H__ |
include/session.h
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 | +#ifndef __SESSION_H__ | ||
| 24 | +#define __SESSION_H__ | ||
| 25 | + | ||
| 26 | +#include <time.h> | ||
| 27 | +#include <sys/types.h> | ||
| 28 | + | ||
| 29 | +#include "class.h" | ||
| 30 | + | ||
| 31 | +#define SESSION_LIVETIME 30 | ||
| 32 | + | ||
| 33 | + | ||
| 34 | +CLASS(Session) { | ||
| 35 | + unsigned long id; | ||
| 36 | + time_t livetime; | ||
| 37 | + | ||
| 38 | + char * username; | ||
| 39 | +}; | ||
| 40 | + | ||
| 41 | +Session sessionAdd(const Session *, Session); | ||
| 42 | +Session sessionGet(const Session *, const unsigned long id); | ||
| 43 | +void sessionDelete(const Session *, const unsigned long id); | ||
| 44 | + | ||
| 45 | +#endif // __SESSION_H__ | ||
| 46 | + | ||
| 47 | +// vim: set ts=4 sw=4: |
| @@ -26,6 +26,8 @@ REQ = http/request.c \ | @@ -26,6 +26,8 @@ REQ = http/request.c \ | ||
| 26 | RESP = http/response.c \ | 26 | RESP = http/response.c \ |
| 27 | http/response/304.c \ | 27 | http/response/304.c \ |
| 28 | http/response/404.c \ | 28 | http/response/404.c \ |
| 29 | + http/response/403.c \ | ||
| 30 | + http/response/login_form.c \ | ||
| 29 | http/response/asset.c \ | 31 | http/response/asset.c \ |
| 30 | http/response/me.c \ | 32 | http/response/me.c \ |
| 31 | http/response/randval.c | 33 | http/response/randval.c |
| @@ -43,6 +45,7 @@ WORKER = http/worker.c \ | @@ -43,6 +45,7 @@ WORKER = http/worker.c \ | ||
| 43 | http/worker/add_common_header.c | 45 | http/worker/add_common_header.c |
| 44 | HEADER = http/header.c http/header/get.c http/header/add.c \ | 46 | HEADER = http/header.c http/header/get.c http/header/add.c \ |
| 45 | http/header/to_string.c | 47 | http/header/to_string.c |
| 48 | +SESSION = session.c session/add.c session/get.c session/delete.c | ||
| 46 | UTILS = utils/hash.c \ | 49 | UTILS = utils/hash.c \ |
| 47 | utils/memory.c \ | 50 | utils/memory.c \ |
| 48 | utils/http.c \ | 51 | utils/http.c \ |
| @@ -57,6 +60,6 @@ bin_PROGRAMS = testserver | @@ -57,6 +60,6 @@ bin_PROGRAMS = testserver | ||
| 57 | testserver_SOURCES = testserver.c \ | 60 | testserver_SOURCES = testserver.c \ |
| 58 | $(IFACE) $(SOCKET) $(SERVER) $(LOGGER) $(MSG) $(REQ) \ | 61 | $(IFACE) $(SOCKET) $(SERVER) $(LOGGER) $(MSG) $(REQ) \ |
| 59 | $(WRITER) $(RESP) $(HEADER) $(PARSER) $(WORKER) $(CB) \ | 62 | $(WRITER) $(RESP) $(HEADER) $(PARSER) $(WORKER) $(CB) \ |
| 60 | - $(UTILS) $(MSGQ) | 63 | + $(UTILS) $(MSGQ) $(SESSION) |
| 61 | testserver_CFLAGS = -Wall -I ../include/ | 64 | testserver_CFLAGS = -Wall -I ../include/ |
| 62 | testserver_LDFLAGS = -lrt | 65 | testserver_LDFLAGS = -lrt |
src/http/response/403.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 <stdlib.h> | ||
| 24 | +#include <string.h> | ||
| 25 | +#include <stdio.h> | ||
| 26 | +#include <sys/types.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 | +httpResponse403() | ||
| 38 | +{ | ||
| 39 | + HttpResponse response; | ||
| 40 | + HttpMessage message; | ||
| 41 | + char buffer[200]; | ||
| 42 | + size_t nbuf; | ||
| 43 | + | ||
| 44 | + response = new(HttpResponse, "HTTP/1.1", 403, "Forbidden"); | ||
| 45 | + message = (HttpMessage)response; | ||
| 46 | + | ||
| 47 | + message->type = HTTP_MESSAGE_BUFFERED; | ||
| 48 | + message->nbody = 0; | ||
| 49 | + message->body = NULL; | ||
| 50 | + | ||
| 51 | + nbuf = sprintf(buffer, "%d", message->nbody); | ||
| 52 | + | ||
| 53 | + httpHeaderAdd(&(message->header), | ||
| 54 | + new(HttpHeader, | ||
| 55 | + "Content-Length", | ||
| 56 | + sizeof("Content-Length")-1, | ||
| 57 | + buffer, | ||
| 58 | + nbuf)); | ||
| 59 | + | ||
| 60 | + return response; | ||
| 61 | +} | ||
| 62 | + | ||
| 63 | +// vim: set ts=4 sw=4: |
src/http/response/login_form.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 <stdlib.h> | ||
| 24 | +#include <string.h> | ||
| 25 | +#include <stdio.h> | ||
| 26 | +#include <time.h> | ||
| 27 | +#include <sys/types.h> | ||
| 28 | + | ||
| 29 | +#include "class.h" | ||
| 30 | +#include "interface/class.h" | ||
| 31 | + | ||
| 32 | +#include "http/response.h" | ||
| 33 | +#include "http/message.h" | ||
| 34 | +#include "http/header.h" | ||
| 35 | + | ||
| 36 | +#define RESP_DATA "<form action=\"/me/\" method=\"POST\">" \ | ||
| 37 | + "<input name=\"username\" type=\"text\" />" \ | ||
| 38 | + "<input type=\"submit\">" \ | ||
| 39 | +"</form>" | ||
| 40 | + | ||
| 41 | +HttpResponse | ||
| 42 | +httpResponseLoginForm() | ||
| 43 | +{ | ||
| 44 | + char buffer[200]; | ||
| 45 | + HttpResponse response; | ||
| 46 | + HttpMessage message; | ||
| 47 | + size_t nbuf; | ||
| 48 | + | ||
| 49 | + response = new(HttpResponse, "HTTP/1.1", 200, "OK"); | ||
| 50 | + message = (HttpMessage)response; | ||
| 51 | + | ||
| 52 | + httpHeaderAdd(&(message->header), | ||
| 53 | + new(HttpHeader, | ||
| 54 | + "Content-Type", | ||
| 55 | + sizeof("Content-Type")-1, | ||
| 56 | + "text/html", | ||
| 57 | + sizeof("text/html")-1)); | ||
| 58 | + | ||
| 59 | + message->type = HTTP_MESSAGE_BUFFERED; | ||
| 60 | + | ||
| 61 | + message->nbody = sizeof(RESP_DATA)-1; | ||
| 62 | + message->body = malloc(message->nbody); | ||
| 63 | + memcpy(message->body, RESP_DATA, message->nbody); | ||
| 64 | + | ||
| 65 | + nbuf = sprintf(buffer, "%d", message->nbody); | ||
| 66 | + | ||
| 67 | + httpHeaderAdd(&(message->header), | ||
| 68 | + new(HttpHeader, | ||
| 69 | + "Content-Length", | ||
| 70 | + sizeof("Content-Length")-1, | ||
| 71 | + buffer, | ||
| 72 | + nbuf)); | ||
| 73 | + | ||
| 74 | + return response; | ||
| 75 | +} | ||
| 76 | + | ||
| 77 | +// vim: set ts=4 sw=4: |
| @@ -60,15 +60,31 @@ | @@ -60,15 +60,31 @@ | ||
| 60 | "$(document).ready(function() {" \ | 60 | "$(document).ready(function() {" \ |
| 61 | "var intervalId;" \ | 61 | "var intervalId;" \ |
| 62 | "var vnext = 0;" \ | 62 | "var vnext = 0;" \ |
| 63 | + "var clickclose = function() {" \ | ||
| 64 | + "clearInterval(intervalId);" \ | ||
| 65 | + "vnext = 0;" \ | ||
| 66 | + "$(\"#randval\").addClass(\"hide\");" \ | ||
| 67 | + "};" \ | ||
| 63 | "var counter = function() {" \ | 68 | "var counter = function() {" \ |
| 64 | "if (0 >= vnext) {" \ | 69 | "if (0 >= vnext) {" \ |
| 65 | - "$.getJSON(\"/randval/\", function(data) {" \ | 70 | + "$.getJSON(\"/randval/\", function(data, xhr) {" \ |
| 66 | "var date = new Date(data.ctime * 1000);" \ | 71 | "var date = new Date(data.ctime * 1000);" \ |
| 67 | "$(\"#ctime\").empty().append(date.toString());" \ | 72 | "$(\"#ctime\").empty().append(date.toString());" \ |
| 68 | "vnext = data.vnext;" \ | 73 | "vnext = data.vnext;" \ |
| 69 | "$(\"#value\").empty().append(data.value);" \ | 74 | "$(\"#value\").empty().append(data.value);" \ |
| 70 | "$(\"#vnext\").empty().append(vnext);" \ | 75 | "$(\"#vnext\").empty().append(vnext);" \ |
| 76 | + "$(\"#randval\").on(\"click\", clickclose);" \ | ||
| 77 | + "}).error(function(event, request, settings) {" \ | ||
| 78 | + "clearInterval(intervalId);" \ | ||
| 79 | + "$.get(\"/login/\", function(data) {" \ | ||
| 80 | + "$(\"#randval\")" \ | ||
| 81 | + ".off(\"click\", clickclose)" \ | ||
| 82 | + ".empty().append(data);" \ | ||
| 83 | + "});" \ | ||
| 71 | "});" \ | 84 | "});" \ |
| 85 | + "if ($(\"#randval\").hasClass(\"hide\")) {" \ | ||
| 86 | + "$(\"#randval\").removeClass(\"hide\");" \ | ||
| 87 | + "}" \ | ||
| 72 | "} else {" \ | 88 | "} else {" \ |
| 73 | "vnext--;" \ | 89 | "vnext--;" \ |
| 74 | "$(\"#vnext\").empty().append(vnext);" \ | 90 | "$(\"#vnext\").empty().append(vnext);" \ |
| @@ -83,12 +99,6 @@ | @@ -83,12 +99,6 @@ | ||
| 83 | "});" \ | 99 | "});" \ |
| 84 | "$(\"a\").click(function() {" \ | 100 | "$(\"a\").click(function() {" \ |
| 85 | "intervalId = setInterval(counter, 1000);" \ | 101 | "intervalId = setInterval(counter, 1000);" \ |
| 86 | - "$(\"#randval\").removeClass(\"hide\");" \ | ||
| 87 | - "});" \ | ||
| 88 | - "$(\"#randval\").click(function() {" \ | ||
| 89 | - "clearInterval(intervalId);" \ | ||
| 90 | - "vnext = 0;" \ | ||
| 91 | - "$(\"#randval\").addClass(\"hide\");" \ | ||
| 92 | "});" \ | 102 | "});" \ |
| 93 | "});" \ | 103 | "});" \ |
| 94 | "</script>" \ | 104 | "</script>" \ |
| @@ -103,6 +113,7 @@ | @@ -103,6 +113,7 @@ | ||
| 103 | "</div>" \ | 113 | "</div>" \ |
| 104 | "<div id=\"main\">" \ | 114 | "<div id=\"main\">" \ |
| 105 | "<h1>Testpage</h1>" \ | 115 | "<h1>Testpage</h1>" \ |
| 116 | + "Welcome %s<br />" \ | ||
| 106 | "<img src=\"/image/\" />" \ | 117 | "<img src=\"/image/\" />" \ |
| 107 | "<br /><a href=\"#\">Link</a>" \ | 118 | "<br /><a href=\"#\">Link</a>" \ |
| 108 | "</div>" \ | 119 | "</div>" \ |
| @@ -111,7 +122,7 @@ | @@ -111,7 +122,7 @@ | ||
| 111 | "</html>" | 122 | "</html>" |
| 112 | 123 | ||
| 113 | HttpResponse | 124 | HttpResponse |
| 114 | -httpResponseMe() | 125 | +httpResponseMe(char * uname) |
| 115 | { | 126 | { |
| 116 | char buffer[200]; | 127 | char buffer[200]; |
| 117 | HttpResponse response; | 128 | HttpResponse response; |
| @@ -141,9 +152,10 @@ httpResponseMe() | @@ -141,9 +152,10 @@ httpResponseMe() | ||
| 141 | sizeof("profession=\"coder\"")-1)); | 152 | sizeof("profession=\"coder\"")-1)); |
| 142 | 153 | ||
| 143 | message->type = HTTP_MESSAGE_BUFFERED; | 154 | message->type = HTTP_MESSAGE_BUFFERED; |
| 144 | - message->nbody = sizeof(RESP_DATA)-1; | ||
| 145 | - message->body = malloc(sizeof(RESP_DATA)-1); | ||
| 146 | - memcpy(message->body, RESP_DATA, sizeof(RESP_DATA)-1); | 155 | + message->nbody = sizeof(RESP_DATA)-1-2+strlen(uname); //!< the two are the %s |
| 156 | + message->body = malloc(message->nbody+1); | ||
| 157 | + sprintf(message->body, RESP_DATA, uname); | ||
| 158 | + //memcpy(message->body, RESP_DATA, sizeof(RESP_DATA)-1); | ||
| 147 | 159 | ||
| 148 | nbuf = sprintf(buffer, "%d", message->nbody); | 160 | nbuf = sprintf(buffer, "%d", message->nbody); |
| 149 | 161 |
| 1 | -#include <stdlib.h> | 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 | +#define _GNU_SOURCE | ||
| 24 | + | ||
| 2 | #include <stdarg.h> | 25 | #include <stdarg.h> |
| 3 | #include <stdlib.h> | 26 | #include <stdlib.h> |
| 4 | #include <string.h> | 27 | #include <string.h> |
| 5 | #include <stdio.h> | 28 | #include <stdio.h> |
| 29 | +#include <search.h> | ||
| 6 | 30 | ||
| 7 | #include "class.h" | 31 | #include "class.h" |
| 8 | #include "http/worker.h" | 32 | #include "http/worker.h" |
| @@ -37,10 +61,20 @@ httpWorkerCtor(void * _this, va_list * params) | @@ -37,10 +61,20 @@ httpWorkerCtor(void * _this, va_list * params) | ||
| 37 | this->parser = new(HttpParser, this->pbuf); | 61 | this->parser = new(HttpParser, this->pbuf); |
| 38 | this->writer = new(HttpWriter, this->wbuf); | 62 | this->writer = new(HttpWriter, this->wbuf); |
| 39 | 63 | ||
| 64 | + this->sroot = &(this->session); | ||
| 65 | + | ||
| 40 | return 0; | 66 | return 0; |
| 41 | } | 67 | } |
| 42 | 68 | ||
| 43 | static | 69 | static |
| 70 | +inline | ||
| 71 | +void | ||
| 72 | +tDelete(void * node) | ||
| 73 | +{ | ||
| 74 | + delete(node); | ||
| 75 | +} | ||
| 76 | + | ||
| 77 | +static | ||
| 44 | void | 78 | void |
| 45 | httpWorkerDtor(void * _this) | 79 | httpWorkerDtor(void * _this) |
| 46 | { | 80 | { |
| @@ -51,8 +85,11 @@ httpWorkerDtor(void * _this) | @@ -51,8 +85,11 @@ httpWorkerDtor(void * _this) | ||
| 51 | delete(this->parser); | 85 | delete(this->parser); |
| 52 | delete(this->writer); | 86 | delete(this->writer); |
| 53 | 87 | ||
| 54 | - delete(this->pbuf); //!< cloned workers have NULL, so delete won't do anything | ||
| 55 | - delete(this->wbuf); //!< cloned workers have NULL, so delete won't do anything | 88 | + if (NULL != this->pbuf) { |
| 89 | + delete(this->pbuf); //!< cloned workers have NULL, so delete won't do anything | ||
| 90 | + delete(this->wbuf); //!< cloned workers have NULL, so delete won't do anything | ||
| 91 | + tdestroy(*(this->sroot), tDelete); | ||
| 92 | + } | ||
| 56 | } | 93 | } |
| 57 | 94 | ||
| 58 | static | 95 | static |
| @@ -66,6 +103,8 @@ httpWorkerClone(void * _this, void * _base) | @@ -66,6 +103,8 @@ httpWorkerClone(void * _this, void * _base) | ||
| 66 | 103 | ||
| 67 | this->parser = new(HttpParser, base->pbuf); | 104 | this->parser = new(HttpParser, base->pbuf); |
| 68 | this->writer = new(HttpWriter, base->wbuf); | 105 | this->writer = new(HttpWriter, base->wbuf); |
| 106 | + | ||
| 107 | + this->sroot = &(base->session); | ||
| 69 | } | 108 | } |
| 70 | 109 | ||
| 71 | ssize_t httpWorkerProcess(void *, int); | 110 | ssize_t httpWorkerProcess(void *, int); |
| @@ -21,6 +21,9 @@ | @@ -21,6 +21,9 @@ | ||
| 21 | */ | 21 | */ |
| 22 | 22 | ||
| 23 | #include <sys/types.h> | 23 | #include <sys/types.h> |
| 24 | +#include <stdio.h> | ||
| 25 | +#include <stdlib.h> | ||
| 26 | +#include <time.h> | ||
| 24 | 27 | ||
| 25 | #include "class.h" | 28 | #include "class.h" |
| 26 | #include "interface/class.h" | 29 | #include "interface/class.h" |
| @@ -31,6 +34,7 @@ | @@ -31,6 +34,7 @@ | ||
| 31 | #include "http/response.h" | 34 | #include "http/response.h" |
| 32 | #include "http/message/queue.h" | 35 | #include "http/message/queue.h" |
| 33 | #include "http/parser.h" | 36 | #include "http/parser.h" |
| 37 | +#include "session.h" | ||
| 34 | 38 | ||
| 35 | HttpMessage httpWorkerGetAsset(HttpRequest, const char *, const char *, size_t); | 39 | HttpMessage httpWorkerGetAsset(HttpRequest, const char *, const char *, size_t); |
| 36 | void httpWorkerAddCommonHeader(HttpMessage, HttpMessage); | 40 | void httpWorkerAddCommonHeader(HttpMessage, HttpMessage); |
| @@ -49,19 +53,91 @@ httpWorkerProcess(HttpWorker this, int fd) | @@ -49,19 +53,91 @@ httpWorkerProcess(HttpWorker this, int fd) | ||
| 49 | HttpMessageQueue respq = this->writer->queue; | 53 | HttpMessageQueue respq = this->writer->queue; |
| 50 | 54 | ||
| 51 | for (i=0; i<reqq->nmsgs; i++) { | 55 | for (i=0; i<reqq->nmsgs; i++) { |
| 56 | + HttpMessage rmessage = reqq->msgs[i]; | ||
| 52 | HttpRequest request = (HttpRequest)(reqq->msgs[i]); | 57 | HttpRequest request = (HttpRequest)(reqq->msgs[i]); |
| 53 | HttpMessage response = NULL; | 58 | HttpMessage response = NULL; |
| 59 | + HttpHeader cookie = httpHeaderGet( | ||
| 60 | + &(rmessage->header), | ||
| 61 | + "cookie", | ||
| 62 | + sizeof("Cookie")-1); | ||
| 63 | + | ||
| 64 | + if (NULL == this->session && NULL != cookie) { | ||
| 65 | + int i; | ||
| 66 | + | ||
| 67 | + for (i=0; i<cookie->cvalue; i++) { | ||
| 68 | + char * sidstr = strstr(cookie->value[i], "sid"); | ||
| 69 | + | ||
| 70 | + if (NULL != sidstr) { | ||
| 71 | + unsigned long sid; | ||
| 72 | + | ||
| 73 | + sidstr = strchr(sidstr, '=')+1; | ||
| 74 | + sid = strtoul(sidstr, NULL, 10); | ||
| 75 | + | ||
| 76 | + this->session = sessionGet(this->sroot, sid); | ||
| 77 | + break; | ||
| 78 | + } | ||
| 79 | + } | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + if (NULL != this->session) { | ||
| 83 | + if (time(NULL) < this->session->livetime) { | ||
| 84 | + this->session->livetime = time(NULL) + SESSION_LIVETIME; | ||
| 85 | + } else { | ||
| 86 | + sessionDelete(this->sroot, this->session->id); | ||
| 87 | + delete(this->session); | ||
| 88 | + } | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + if (0 == strcmp("POST", request->method)) { | ||
| 92 | + if (0 == strcmp("/me/", request->uri)) { | ||
| 93 | + char * delim = memchr(rmessage->body, '=', rmessage->nbody); | ||
| 94 | + char * key = rmessage->body; | ||
| 95 | + char * val; | ||
| 96 | + size_t nkey, nval; | ||
| 97 | + char buffer[200]; | ||
| 98 | + size_t nbuf; | ||
| 99 | + | ||
| 100 | + nkey = delim - rmessage->body - 1; | ||
| 101 | + *delim = 0; | ||
| 102 | + val = delim + 1; | ||
| 103 | + nval = rmessage->nbody - (val - rmessage->body); | ||
| 104 | + | ||
| 105 | + this->session = sessionAdd( | ||
| 106 | + this->sroot, | ||
| 107 | + new(Session, val, nval)); | ||
| 108 | + nbuf = sprintf(buffer, "sid=%lu;Path=/", this->session->id); | ||
| 109 | + | ||
| 110 | + response = (HttpMessage)httpResponseMe(this->session->username); | ||
| 111 | + | ||
| 112 | + httpHeaderAdd( | ||
| 113 | + &(response->header), | ||
| 114 | + new(HttpHeader, | ||
| 115 | + "Set-Cookie", | ||
| 116 | + sizeof("Set-Cookie")-1, | ||
| 117 | + buffer, | ||
| 118 | + nbuf)); | ||
| 119 | + } | ||
| 120 | + } | ||
| 54 | 121 | ||
| 55 | if (0 == strcmp("GET", request->method)) { | 122 | if (0 == strcmp("GET", request->method)) { |
| 56 | 123 | ||
| 124 | + if (0 == strcmp("/login/", request->uri)) { | ||
| 125 | + response = (HttpMessage)httpResponseLoginForm(); | ||
| 126 | + } | ||
| 127 | + | ||
| 57 | if (0 == strcmp("/me/", request->uri)) { | 128 | if (0 == strcmp("/me/", request->uri)) { |
| 58 | - response = (HttpMessage)httpResponseMe(); | 129 | + char * uname = (NULL != this->session)? this->session->username : ""; |
| 130 | + response = (HttpMessage)httpResponseMe(uname); | ||
| 59 | } | 131 | } |
| 60 | 132 | ||
| 61 | if (0 == strcmp("/randval/", request->uri)) { | 133 | if (0 == strcmp("/randval/", request->uri)) { |
| 62 | - response = (HttpMessage)httpResponseRandval( | ||
| 63 | - this->val->timestamp, | ||
| 64 | - this->val->value); | 134 | + if (NULL != this->session) { |
| 135 | + response = (HttpMessage)httpResponseRandval( | ||
| 136 | + this->val->timestamp, | ||
| 137 | + this->val->value); | ||
| 138 | + } else { | ||
| 139 | + response = (HttpMessage)httpResponse403(); | ||
| 140 | + } | ||
| 65 | } | 141 | } |
| 66 | 142 | ||
| 67 | if (0 == strcmp("/image/", request->uri)) { | 143 | if (0 == strcmp("/image/", request->uri)) { |
src/session.c
0 → 100644
| 1 | +#include <time.h> | ||
| 2 | +#include <stdarg.h> | ||
| 3 | +#include <stdlib.h> | ||
| 4 | +#include <string.h> | ||
| 5 | +#include <stdio.h> | ||
| 6 | +#include <sys/types.h> | ||
| 7 | + | ||
| 8 | +#include "session.h" | ||
| 9 | +#include "class.h" | ||
| 10 | +#include "interface/class.h" | ||
| 11 | + | ||
| 12 | +#include "utils/hash.h" | ||
| 13 | +#include "utils/memory.h" | ||
| 14 | + | ||
| 15 | + | ||
| 16 | +static | ||
| 17 | +int | ||
| 18 | +sessionCtor(void * _this, va_list * params) | ||
| 19 | +{ | ||
| 20 | + Session this = _this; | ||
| 21 | + char * uname = va_arg(* params, char *); | ||
| 22 | + size_t nuname = va_arg(* params, size_t); | ||
| 23 | + | ||
| 24 | + this->livetime = time(NULL) + SESSION_LIVETIME; | ||
| 25 | + this->id = sdbm((unsigned char *)uname, nuname) & this->livetime; | ||
| 26 | + | ||
| 27 | + this->username = malloc(nuname + 1); | ||
| 28 | + this->username[nuname] = 0; | ||
| 29 | + memcpy(this->username, uname, nuname); | ||
| 30 | + | ||
| 31 | + return 0; | ||
| 32 | +} | ||
| 33 | + | ||
| 34 | +static | ||
| 35 | +void | ||
| 36 | +sessionDtor(void * _this) | ||
| 37 | +{ | ||
| 38 | + Session this = _this; | ||
| 39 | + | ||
| 40 | + FREE(this->username); | ||
| 41 | +} | ||
| 42 | + | ||
| 43 | +INIT_IFACE(Class, sessionCtor, sessionDtor, NULL); | ||
| 44 | +CREATE_CLASS(Session, NULL, IFACE(Class)); | ||
| 45 | + | ||
| 46 | +// vim: set ts=4 sw=4: |
src/session/add.c
0 → 100644
| 1 | +#include <search.h> | ||
| 2 | + | ||
| 3 | +#include "session.h" | ||
| 4 | +#include "interface/class.h" | ||
| 5 | + | ||
| 6 | + | ||
| 7 | +static | ||
| 8 | +inline | ||
| 9 | +int | ||
| 10 | +sessionAddComp(const void * _a, const void * _b) | ||
| 11 | +{ | ||
| 12 | + Session a = (Session)_a; | ||
| 13 | + Session b = (Session)_b; | ||
| 14 | + return (a->id < b->id)? -1 : (a->id > b->id)? 1 : 0; | ||
| 15 | +} | ||
| 16 | + | ||
| 17 | +Session | ||
| 18 | +sessionAdd(const Session * root, Session session) | ||
| 19 | +{ | ||
| 20 | + Session * found = tsearch(session, (void**)root, sessionAddComp); | ||
| 21 | + | ||
| 22 | + if (NULL == found) { | ||
| 23 | + return NULL; | ||
| 24 | + } | ||
| 25 | + | ||
| 26 | + if (*found != session) { | ||
| 27 | + /** | ||
| 28 | + * \todo this should not happen, so do some logging here. | ||
| 29 | + */ | ||
| 30 | + delete(session); | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + return *found; | ||
| 34 | +} | ||
| 35 | + | ||
| 36 | +// vim: set ts=4 sw=4: |
src/session/delete.c
0 → 100644
| 1 | +#include <search.h> | ||
| 2 | + | ||
| 3 | +#include "session.h" | ||
| 4 | +#include "interface/class.h" | ||
| 5 | + | ||
| 6 | + | ||
| 7 | +static | ||
| 8 | +inline | ||
| 9 | +int | ||
| 10 | +sessionDeleteComp(const void * _a, const void * _b) | ||
| 11 | +{ | ||
| 12 | + unsigned long a = *(unsigned long *)_a; | ||
| 13 | + Session b = (Session)_b; | ||
| 14 | + return (a < b->id)? -1 : (a > b->id)? 1 : 0; | ||
| 15 | +} | ||
| 16 | + | ||
| 17 | +void | ||
| 18 | +sessionDelete(const Session * root, const unsigned long id) | ||
| 19 | +{ | ||
| 20 | + tdelete(&id, (void**)root, sessionDeleteComp); | ||
| 21 | +} | ||
| 22 | + | ||
| 23 | +// vim: set ts=4 sw=4: |
src/session/get.c
0 → 100644
| 1 | +#include <search.h> | ||
| 2 | +#include <time.h> | ||
| 3 | + | ||
| 4 | +#include "session.h" | ||
| 5 | + | ||
| 6 | + | ||
| 7 | +static | ||
| 8 | +inline | ||
| 9 | +int | ||
| 10 | +sessionGetComp(const void * _a, const void * _b) | ||
| 11 | +{ | ||
| 12 | + unsigned long a = *(unsigned long *)_a; | ||
| 13 | + Session b = (Session)_b; | ||
| 14 | + return (a < b->id)? -1 : (a > b->id)? 1 : 0; | ||
| 15 | +} | ||
| 16 | + | ||
| 17 | +Session | ||
| 18 | +sessionGet(const Session * root, const unsigned long id) | ||
| 19 | +{ | ||
| 20 | + Session * found = tfind(&id, (void**)root, sessionGetComp); | ||
| 21 | + | ||
| 22 | + if (NULL == found) { | ||
| 23 | + return NULL; | ||
| 24 | + } | ||
| 25 | + | ||
| 26 | + return *found; | ||
| 27 | +} | ||
| 28 | + | ||
| 29 | +// vim: set ts=4 sw=4: |
Please
register
or
login
to post a comment