Index: trunk/Server/config.c
===================================================================
--- trunk/Server/config.c	(revision 19)
+++ trunk/Server/config.c	(revision 20)
@@ -11,4 +11,8 @@
 #include <string.h>
 #include <unistd.h>
+
+#ifdef __MINGW32__
+#include <winsock2.h>
+#endif
 
 #include <cm_string.h>
Index: trunk/Server/http.c
===================================================================
--- trunk/Server/http.c	(revision 19)
+++ trunk/Server/http.c	(revision 20)
@@ -23,4 +23,5 @@
 	if(req->method != NULL) free(req->method);
 	if(req->path != NULL) free(req->path);
+	if(req->query != NULL) free(req->query);
 	if(req->headers != NULL) {
 		int i;
@@ -44,4 +45,5 @@
 	req->method = NULL;
 	req->path = NULL;
+	req->query = NULL;
 	req->headers = NULL;
 	req->body = NULL;
@@ -246,4 +248,31 @@
 		return 1;
 	}
+	char* result = malloc(1);
+	result[0] = 0;
+	int i;
+	for(i = 0; req->path[i] != 0; i++) {
+		if(req->path[i] == '?') {
+			req->path[i] = 0;
+			req->query = cm_strdup(req->path + i + 1);
+			break;
+		}
+	}
+	for(i = 0; req->path[i] != 0; i++) {
+		if(req->path[i] == '%') {
+			if(req->path[i + 1] == 0) continue;
+			cbuf[0] = cm_hex(req->path + i + 1, 2);
+			char* tmp = result;
+			result = cm_strcat(tmp, cbuf);
+			free(tmp);
+			i += 2;
+		} else {
+			cbuf[0] = req->path[i];
+			char* tmp = result;
+			result = cm_strcat(tmp, cbuf);
+			free(tmp);
+		}
+	}
+	free(req->path);
+	req->path = result;
 	return 0;
 }
Index: trunk/Server/main.c
===================================================================
--- trunk/Server/main.c	(revision 19)
+++ trunk/Server/main.c	(revision 20)
@@ -56,5 +56,5 @@
 	}
 	sprintf(tw_server, "Tewi/%s (%s)%s", tw_get_version(), tw_get_platform(), config.extension == NULL ? "" : config.extension);
-	cm_log("Daemon", "Ready");
+	cm_log("Daemon", "Ready, server: %s", tw_server);
 #ifndef __MINGW32__
 	signal(SIGCHLD, SIG_IGN);
Index: trunk/Server/server.c
===================================================================
--- trunk/Server/server.c	(revision 19)
+++ trunk/Server/server.c	(revision 20)
@@ -14,4 +14,5 @@
 #include <string.h>
 #include <stdbool.h>
+#include <stdarg.h>
 
 #include <cm_string.h>
@@ -136,12 +137,12 @@
 }
 
-#define ERROR_400 \
+#define ERROR_HTML \
 	"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n" \
 	"<html>\n" \
 	"	<head>\n" \
-	"		<title>400 Bad Request</title>" \
+	"		<title>%s</title>\n" \
 	"	</head>\n" \
 	"	<body>\n" \
-	"		<h1>Bad Request</h1>\n" \
+	"		<h1>%s</h1>\n" \
 	"		<hr>\n" \
 	"		", \
@@ -151,49 +152,4 @@
 	    "</html>\n"
 
-#define ERROR_401 \
-	"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n" \
-	"<html>\n" \
-	"	<head>\n" \
-	"		<title>401 Unauthorized</title>" \
-	"	</head>\n" \
-	"	<body>\n" \
-	"		<h1>Unauthorized</h1>\n" \
-	"		<hr>\n" \
-	"		", \
-	    address, \
-	    "\n" \
-	    "	</body>\n" \
-	    "</html>\n"
-
-#define ERROR_403 \
-	"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n" \
-	"<html>\n" \
-	"	<head>\n" \
-	"		<title>403 Forbidden</title>" \
-	"	</head>\n" \
-	"	<body>\n" \
-	"		<h1>Forbidden</h1>\n" \
-	"		<hr>\n" \
-	"		", \
-	    address, \
-	    "\n" \
-	    "	</body>\n" \
-	    "</html>\n"
-
-#define ERROR_404 \
-	"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n" \
-	"<html>\n" \
-	"	<head>\n" \
-	"		<title>404 Not Found</title>" \
-	"	</head>\n" \
-	"	<body>\n" \
-	"		<h1>Not Found</h1>\n" \
-	"		<hr>\n" \
-	"		", \
-	    address, \
-	    "\n" \
-	    "	</body>\n" \
-	    "</html>\n"
-
 void tw_process_page(SSL* ssl, int sock, const char* status, const char* type, const unsigned char* doc, size_t size) {
 	char construct[512];
@@ -222,6 +178,14 @@
 
 const char* tw_http_status(int code) {
-	if(code == 400) {
+	if(code == 200) {
+		return "200 OK";
+	} else if(code == 400) {
 		return "400 Bad Request";
+	} else if(code == 401) {
+		return "401 Unauthorized";
+	} else if(code == 403) {
+		return "403 Forbidden";
+	} else if(code == 404) {
+		return "404 Not Found";
 	} else {
 		return "400 Bad Request";
@@ -232,9 +196,20 @@
 	char address[1024];
 	sprintf(address, "<address>%s Server at %s Port %d</address>", tw_server, name, port);
-	if(code == 400) {
-		return cm_strcat3(ERROR_400);
-	} else {
-		return cm_strcat3(ERROR_400);
-	}
+
+	char* st = cm_strdup(tw_http_status(code));
+	char* st2;
+	int i;
+	for(i = 0; st[i] != 0; i++) {
+		if(st[i] == ' ') {
+			st2 = cm_strdup(st + i + 1);
+			break;
+		}
+	}
+	char* buffer = malloc(4096);
+	char* str = cm_strcat3(ERROR_HTML);
+	sprintf(buffer, str, st, st2);
+	free(str);
+	free(st);
+	return buffer;
 }
 
@@ -243,4 +218,45 @@
 	tw_process_page(ssl, sock, tw_http_status(error), "text/html", str, strlen(str));
 	free(str);
+}
+
+void addstring(char** str, const char* add, ...) {
+	int i;
+	char cbuf[2];
+	cbuf[1] = 0;
+	va_list va;
+	va_start(va, add);
+	for(i = 0; add[i] != 0; i++) {
+		cbuf[0] = add[i];
+		if(add[i] == '%') {
+			i++;
+			if(add[i] == 's') {
+				char* tmp = *str;
+				*str = cm_strcat(tmp, va_arg(va, const char*));
+				free(tmp);
+			} else if(add[i] == 'h') {
+				char* h = cm_html_escape(va_arg(va, const char*));
+				char* tmp = *str;
+				*str = cm_strcat(tmp, h);
+				free(tmp);
+				free(h);
+			} else if(add[i] == 'd') {
+				int n = va_arg(va, int);
+				char* h = malloc(512);
+				sprintf(h, "%d", n);
+				char* tmp = *str;
+				*str = cm_strcat(tmp, h);
+				free(tmp);
+				free(h);
+			} else if(add[i] == '%') {
+				char* tmp = *str;
+				*str = cm_strcat(tmp, "%");
+				free(tmp);
+			}
+		} else {
+			char* tmp = *str;
+			*str = cm_strcat(tmp, cbuf);
+			free(tmp);
+		}
+	}
 }
 
@@ -273,6 +289,52 @@
 	}
 	struct tw_http_request req;
+	struct tw_http_response res;
+	struct tw_tool tools;
+	res._processed = false;
+	tw_init_tools(&tools);
 	int ret = tw_http_parse(s, sock, &req);
 	if(ret == 0) {
+		int i;
+		for(i = 0; i < config.module_count; i++) {
+			tw_mod_request_t mod_req = (tw_mod_request_t)tw_module_symbol(config.modules[i], "mod_request");
+			if(mod_req != NULL) {
+				int ret = mod_req(&tools, &req, &res);
+				int co = ret & 0xff;
+				if(co == _TW_MODULE_PASS) continue;
+				if(co == _TW_MODULE_STOP) {
+					res._processed = true;
+					break;
+				}
+				if(co == _TW_MODULE_ERROR) {
+					tw_http_error(s, sock, (ret & 0xffff00) >> 8, name, port);
+					break;
+				}
+			}
+		}
+		if(!res._processed) {
+			char* str = malloc(1);
+			str[0] = 0;
+			addstring(&str, "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n");
+			addstring(&str, "<html>\n");
+			addstring(&str, "	<head>\n");
+			addstring(&str, "		<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n");
+			addstring(&str, "		<title>Index of %h</title>\n", req.path);
+			addstring(&str, "	</head>\n");
+			addstring(&str, "	<body>\n");
+			addstring(&str, "		<h1>Index of %h</h1>\n", req.path);
+			addstring(&str, "		<hr>\n");
+			addstring(&str, "		<table border=\"0\">\n");
+			addstring(&str, "			<tr>\n");
+			addstring(&str, "				<th></th>\n");
+			addstring(&str, "				<th>Filename</th>\n");
+			addstring(&str, "			</tr>\n");
+			addstring(&str, "		</table>\n");
+			addstring(&str, "		<hr>\n");
+			addstring(&str, "		<address>%s Server at %s Port %d</address>\n", tw_server, name, port);
+			addstring(&str, "	</body>\n");
+			addstring(&str, "</html>\n");
+			tw_process_page(s, sock, tw_http_status(200), "text/html", str, strlen(str));
+			free(str);
+		}
 	} else {
 		tw_http_error(s, sock, 400, name, port);
Index: trunk/Server/ssl.c
===================================================================
--- trunk/Server/ssl.c	(revision 19)
+++ trunk/Server/ssl.c	(revision 20)
@@ -29,4 +29,5 @@
 		SSL_use_PrivateKey_file(ssl, config.root.sslkey, SSL_FILETYPE_PEM);
 		SSL_use_certificate_file(ssl, config.root.sslcert, SSL_FILETYPE_PEM);
+		return 1;
 	} else {
 		return 0;
Index: trunk/Server/tw_http.h
===================================================================
--- trunk/Server/tw_http.h	(revision 19)
+++ trunk/Server/tw_http.h	(revision 20)
@@ -4,7 +4,10 @@
 #define __TW_HTTP_H__
 
+#include <stdbool.h>
+
 struct tw_http_request {
 	char* method;
 	char* path;
+	char* query;
 	char* version;
 	char** headers;
@@ -14,4 +17,6 @@
 struct tw_http_response {
 	char** headers;
+	int status;
+	bool _processed; /* Internal parameter */
 };
 
Index: trunk/Server/tw_module.h
===================================================================
--- trunk/Server/tw_module.h	(revision 19)
+++ trunk/Server/tw_module.h	(revision 20)
@@ -13,8 +13,12 @@
 
 enum TW_MODULE_RETURN {
-	TW_MODULE_PASS = 0, /* Pass to the next module. */
-	TW_MODULE_STOP,	    /* Do not pass to the next module. */
-	TW_MODULE_ERROR	    /* Error, and do not pass to the next module. */
+	_TW_MODULE_PASS = 0, /* Pass to the next module. */
+	_TW_MODULE_STOP,     /* Do not pass to the next module. */
+	_TW_MODULE_ERROR     /* Error, and do not pass to the next module. */
 };
+
+#define TW_MODULE_PASS _TW_MODULE_PASS
+#define TW_MODULE_STOP _TW_MODULE_STOP
+#define TW_MODULE_ERROR(x) (_TW_MODULE_ERROR | ((x) << 8))
 
 typedef int (*tw_mod_init_t)(struct tw_config* config, struct tw_tool* tools);
