[Cherokee-commits] rev 948 - in cherokee/trunk

cherokee at cherokee-project.com cherokee at cherokee-project.com
Tue Dec 4 17:32:06 CET 2007


Author: alo
Date: 2007-12-04 17:32:06 +0100 (Tue, 04 Dec 2007)
New Revision: 948
Log:

Get the changeset with:
  svn diff -r 947:948 svn://svn.cherokee-project.com/

Added:
  cherokee/trunk/cherokee/downloader_async.c
  cherokee/trunk/cherokee/downloader_async.h
  cherokee/trunk/cherokee/main_tweak.c
Removed:
  cherokee/trunk/cherokee/cherokee_logrotate.c
Modified:
  cherokee/trunk/cherokee/Makefile.am
   19 
  cherokee/trunk/cherokee/access.c
    2 
  cherokee/trunk/cherokee/admin_client.c
  244 ++++++++---
  cherokee/trunk/cherokee/admin_client.h
   30 -
  cherokee/trunk/cherokee/admin_server.c
   42 +
  cherokee/trunk/cherokee/admin_server.h
    3 
  cherokee/trunk/cherokee/buffer.c
   33 +
  cherokee/trunk/cherokee/buffer.h
    3 
  cherokee/trunk/cherokee/cherokee_show.c
    6 
  cherokee/trunk/cherokee/connection.c
    6 
  cherokee/trunk/cherokee/downloader-protected.h
    3 
  cherokee/trunk/cherokee/downloader.c
   45 +-
  cherokee/trunk/cherokee/downloader.h
    2 
  cherokee/trunk/cherokee/fcgi_manager.c
    6 
  cherokee/trunk/cherokee/fdpoll-kqueue.c
    2 
  cherokee/trunk/cherokee/handler_admin.c
   17 
  cherokee/trunk/cherokee/handler_cgi_base.c
    2 
  cherokee/trunk/cherokee/header-protected.h
    1 
  cherokee/trunk/cherokee/header.c
  542 +++++++++++++------------
  cherokee/trunk/cherokee/header.h
    8 
  cherokee/trunk/cherokee/logger_ncsa.c
    2 
  cherokee/trunk/cherokee/post.c
   19 
  cherokee/trunk/cherokee/request.c
   45 +-
  cherokee/trunk/cherokee/request.h
    9 
  cherokee/trunk/cherokee/server.c
   14 
  cherokee/trunk/cherokee/trace.c
   18 
  cherokee/trunk/cherokee/trace.h
    1 
  cherokee/trunk/cherokee/url.c
   43 -
  cherokee/trunk/cherokee/url.h
    5 
  cherokee/trunk/cherokee/validator.c
    2 
  cherokee/trunk/mods-icons.conf.sample
    2 

Modified: cherokee/trunk/cherokee/Makefile.am
===================================================================
--- cherokee/trunk/cherokee/Makefile.am	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/Makefile.am	2007-12-04 16:32:06 UTC (rev 948)
@@ -12,7 +12,7 @@
 -DCHEROKEE_SRV_PATH=\""$(prefix)/sbin/cherokee"\" \
 -DCHEROKEE_ICONSDIR=\""$(prefix)/share/cherokee/icons"\" \
 -DCHEROKEE_THEMEDIR=\""$(prefix)/share/cherokee/themes"\" \
--DCHEROKEE_PANIC_PATH=\""$(prefix)/bin/cherokee-panic"\"
+-DCHEROKEE_PANIC_PATH=\""$(prefix)/bin/cherokee-panic"\" 
 
 #
 # Scripts
@@ -784,7 +784,9 @@
 request.c \
 downloader.h \
 downloader-protected.h \
-downloader.c 
+downloader.c \
+downloader_async.h \
+downloader_async.c
 
 
 if STATIC_HANDLER_FCGI
@@ -1012,11 +1014,13 @@
 #
 # Log rotate utility
 #
-bin_PROGRAMS = cherokee_logrotate
+bin_PROGRAMS = cherokee_tweak
 
-cherokee_logrotate_SOURCES = cherokee_logrotate.c
-cherokee_logrotate_LDADD = libcherokee-base.la libcherokee-client.la libcherokee-server.la libcherokee-config.la
+cherokee_tweak_SOURCES = main_tweak.c
+cherokee_tweak_LDADD = libcherokee-base.la libcherokee-client.la libcherokee-server.la libcherokee-config.la
 
+
+
 #
 # Win32 service
 #
@@ -1032,11 +1036,8 @@
 #
 # Test programs
 #
-noinst_PROGRAMS = cherokee_show $(win32_cherokeeserv)
+noinst_PROGRAMS = $(win32_cherokeeserv)
 
-cherokee_show_SOURCES = cherokee_show.c 
-cherokee_show_LDADD = libcherokee-config.la libcherokee-base.la libcherokee-client.la 
-
 # test_SOURCES = test.c
 # test_LDADD = libcherokee-config.la libcherokee-base.la libcherokee-client.la 
 

Modified: cherokee/trunk/cherokee/access.c
===================================================================
--- cherokee/trunk/cherokee/access.c	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/access.c	2007-12-04 16:32:06 UTC (rev 948)
@@ -238,7 +238,7 @@
 	}
 
 
-	/* Lenght mask
+	/* Length mask
 	 * Eg: 16
 	 */
 	if (strlen(netmask) > 3) {

Modified: cherokee/trunk/cherokee/admin_client.c
===================================================================
--- cherokee/trunk/cherokee/admin_client.c	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/admin_client.c	2007-12-04 16:32:06 UTC (rev 948)
@@ -29,10 +29,12 @@
 
 #include "util.h"
 #include "buffer.h"
-#include "downloader.h"
+#include "downloader_async.h"
 #include "downloader-protected.h"
 
+#define ENTRIES "admin,client"
 
+
 typedef enum {
 	admin_phase_init,
 	admin_phase_stepping,
@@ -41,16 +43,15 @@
 
 
 struct cherokee_admin_client {
-	cherokee_post_t          *post;
-	cherokee_buffer_t        *url_ref;
-	cherokee_buffer_t         request;
-	cherokee_buffer_t         reply;
-	cherokee_buffer_t         tmp1;
-	cherokee_buffer_t         tmp2;
+	cherokee_downloader_async_t *downloader;
 
-	admin_phase_t             phase;
-	cherokee_fdpoll_t        *poll_ref;
-	cherokee_downloader_t     downloader;
+	cherokee_buffer_t           *url_ref;
+	cherokee_buffer_t            request;
+	cherokee_buffer_t            reply;
+
+	cherokee_post_t              post;
+	admin_phase_t                phase;
+	cherokee_fdpoll_t           *poll_ref;
 };
 
 #define strcmp_begin(line,sub)       strncmp(line, sub, strlen(sub))
@@ -68,17 +69,12 @@
 
 	n->poll_ref     = NULL;
 	n->url_ref      = NULL;
-	n->post         = NULL;
 
-	cherokee_downloader_init (&n->downloader);
+	cherokee_post_init (&n->post);
+	cherokee_downloader_async_new (&n->downloader);
 	cherokee_buffer_init (&n->request);
 	cherokee_buffer_init (&n->reply);
-	cherokee_buffer_init (&n->tmp1);
-	cherokee_buffer_init (&n->tmp2);
 
-	cherokee_buffer_ensure_size(&n->tmp1, 512);
-	cherokee_buffer_ensure_size(&n->tmp2, 512);
-
 	/* Return the object
 	 */
 	*admin = n;
@@ -91,10 +87,8 @@
 {
 	cherokee_buffer_mrproper (&admin->request);
 	cherokee_buffer_mrproper (&admin->reply);
-	cherokee_buffer_mrproper (&admin->tmp1);
-	cherokee_buffer_mrproper (&admin->tmp2);
 
-	cherokee_downloader_mrproper (&admin->downloader);
+	cherokee_downloader_async_free (admin->downloader);
 
 	free (admin);
 	return ret_ok;
@@ -112,16 +106,22 @@
 
 
 ret_t 
-cherokee_admin_client_prepare (cherokee_admin_client_t *admin, cherokee_fdpoll_t *poll, cherokee_buffer_t *url)
+cherokee_admin_client_prepare (cherokee_admin_client_t *admin, 
+			       cherokee_fdpoll_t       *poll,
+			       cherokee_buffer_t       *url,
+			       cherokee_buffer_t       *user,
+			       cherokee_buffer_t       *pass)
 {
 	ret_t                  ret;
-	cherokee_downloader_t *downloader = &admin->downloader;
+	cherokee_downloader_t *downloader = DOWNLOADER(admin->downloader);
 
 	admin->phase    = admin_phase_init;
 
 	admin->poll_ref = poll;
 	admin->url_ref  = url;
 
+	TRACE(ENTRIES, "fdpoll=%p url=%p\n", poll, url);
+
 	/* Sanity check
 	 */
 	if ((admin->url_ref == NULL) || 
@@ -133,20 +133,25 @@
 	
 	/* Set up the downloader object properties
 	 */
-#warning "Fix this!"
-
-/* 	ret = cherokee_downloader_set_fdpoll (downloader, admin->poll_ref, true); */
-/* 	if (unlikely (ret != ret_ok)) return ret; */
+	ret = cherokee_downloader_async_set_fdpoll (downloader, admin->poll_ref);
+	if (unlikely (ret != ret_ok)) return ret;
 	
-	ret = cherokee_downloader_set_url (&admin->downloader, admin->url_ref); 
+	ret = cherokee_downloader_set_url (downloader, admin->url_ref); 
 	if (unlikely (ret != ret_ok)) return ret;
 
 	ret = cherokee_downloader_set_keepalive (downloader, true);
 	if (unlikely (ret != ret_ok)) return ret;
 
+	/* Set the authentication data
+	 */
+	ret = cherokee_downloader_set_auth (downloader, user, pass);
+	if (unlikely (ret != ret_ok)) return ret;	
+
+#warning "Fix this!"
 /* 	ret = cherokee_downloader_connect_event (downloader, downloader_event_finish, on_downloader_finish, admin); */
 /* 	if (unlikely (ret != ret_ok)) return ret; */
 
+	TRACE(ENTRIES, "Exists obj=%p\n", admin);
 	return ret_ok;
 }
 
@@ -154,24 +159,22 @@
 ret_t 
 cherokee_admin_client_connect (cherokee_admin_client_t *admin)
 {
-	return cherokee_downloader_connect (&admin->downloader);
+	return cherokee_downloader_async_connect (admin->downloader);
 }
 
 ret_t 
 cherokee_admin_client_get_reply_code (cherokee_admin_client_t *admin, cherokee_http_t *code)
 {
-	return cherokee_downloader_get_reply_code (&admin->downloader, code);
+	return cherokee_downloader_get_reply_code (DOWNLOADER(admin->downloader), code);
 }
 
 ret_t 
 cherokee_admin_client_reuse (cherokee_admin_client_t *admin)
 {
-	cherokee_downloader_reuse (&admin->downloader);
+	cherokee_downloader_reuse (DOWNLOADER(admin->downloader));
 
 	cherokee_buffer_clean (&admin->request);
 	cherokee_buffer_clean (&admin->reply);
-	cherokee_buffer_clean (&admin->tmp1);
-	cherokee_buffer_clean (&admin->tmp2);
 
 	admin->phase = admin_phase_init;
 	return ret_ok;
@@ -181,9 +184,10 @@
 ret_t
 cherokee_admin_client_internal_step (cherokee_admin_client_t *admin)
 {
-	ret_t                  ret;
-	cherokee_downloader_t *downloader = &admin->downloader;
+	ret_t ret;
 
+	TRACE(ENTRIES, "Enters phase=%d\n", admin->phase);
+
 	/* Has it finished?
 	 */
 	if (admin->phase == admin_phase_finished) 
@@ -196,9 +200,10 @@
 
 	/* It's stepping
 	 */
-	ret = cherokee_downloader_step (downloader, &admin->tmp1, &admin->tmp2);
+	ret = cherokee_downloader_async_step (admin->downloader);
 	switch (ret) {
 	case ret_eof:
+	case ret_eof_have_data:
 		return ret_ok;
 	case ret_error:
 	case ret_eagain:
@@ -216,15 +221,16 @@
 static void
 prepare_and_set_post (cherokee_admin_client_t *admin, char *str, cuint_t str_len)
 {
-	cherokee_downloader_t *downloader = &admin->downloader;
+	cherokee_downloader_t *downloader = DOWNLOADER(admin->downloader);
 
+	cherokee_downloader_set_url (downloader, admin->url_ref); 
 	cherokee_buffer_add (&admin->request, str, str_len); 
 
-	cherokee_downloader_reuse (downloader); 
-	cherokee_downloader_set_url (downloader, admin->url_ref); 
-	/* Fixme
-	cherokee_downloader_post_set (downloader, &admin->request); 
+	/* Build and set the post object
 	 */
+	cherokee_post_init (&admin->post);
+	cherokee_post_set_len (&admin->post, str_len);
+	cherokee_post_append (&admin->post, str, str_len);
 	cherokee_downloader_post_set (downloader, &admin->post); 
 
 	admin->phase = admin_phase_stepping;
@@ -238,19 +244,44 @@
 	if ((string == NULL) || (strlen(string) == 0)) \
 		return ret_error; \
 	if (strncmp (string, substr, sizeof(substr)-1)) { \
-		if (0) PRINT_ERROR ("ERROR: Uknown response len(%d): '%s'\n", strlen(string), string); \
+		PRINT_ERROR ("ERROR: Uknown response len(%d): '%s'\n", strlen(string), string); \
 		return ret_error; \
 	} \
 	string += sizeof(substr)-1;
 
 
 static ret_t
+check_and_skip_literal (cherokee_buffer_t *buf, const char *literal) 
+{
+	cint_t  re;
+	cuint_t len;
+	
+	len = strlen(literal);
+	cherokee_buffer_trim (buf);
+
+	re = strncmp (buf->buf, literal, len);
+	if (re != 0) {
+#if 0
+		PRINT_ERROR ("ERROR: Couldn't find len(%d):'%s' in len(%d):'%s'\n", 
+			     strlen(literal), literal, buf->len, buf->buf);
+#endif
+		return ret_error;
+	}
+
+	cherokee_buffer_move_to_begin (buf, len);
+	return ret_ok;
+}
+
+
+static ret_t
 common_processing (cherokee_admin_client_t *admin, 
 		   void (*conf_request_func) (cherokee_admin_client_t *admin, void *argument),
 		   void *argument) 
 {
 	ret_t ret;
 
+	TRACE(ENTRIES, "phase %d\n", admin->phase);
+
 	switch (admin->phase) {
 	case admin_phase_init:
 		conf_request_func (admin, argument);
@@ -277,10 +308,14 @@
 }
 
 static ret_t
-parse_reply_get_port (char *reply, cuint_t *port)
+parse_reply_get_port (cherokee_buffer_t *reply, cuint_t *port)
 {
-	CHECK_AND_SKIP_LITERAL (reply, "server.port is ");
-	*port = strtol (reply, NULL, 10);
+	ret_t ret;
+
+	ret = check_and_skip_literal (reply, "server.port is ");
+	if (ret != ret_ok) return ret;
+
+	*port = strtol (reply->buf, NULL, 10);
 	return ret_ok;
 }
 
@@ -292,7 +327,7 @@
 	ret = common_processing (admin, ask_get_port, NULL);
 	if (ret != ret_ok) return ret;
 
-	return parse_reply_get_port (admin->downloader.body.buf, port);
+	return parse_reply_get_port (&DOWNLOADER(admin->downloader)->body, port);
 }
 
 
@@ -305,11 +340,14 @@
 }
 
 static ret_t
-parse_reply_get_port_tls (char *reply, cuint_t *port)
+parse_reply_get_port_tls (cherokee_buffer_t *reply, cuint_t *port)
 {
-	CHECK_AND_SKIP_LITERAL (reply, "server.port_tls is ");
+	ret_t ret;
 
-	*port = strtol (reply, NULL, 10);
+	ret = check_and_skip_literal (reply, "server.port_tls is ");
+	if (ret != ret_ok) return ret;
+
+	*port = strtol (reply->buf, NULL, 10);
 	return ret_ok;
 }
 
@@ -321,7 +359,7 @@
 	ret = common_processing (admin, ask_get_port_tls, NULL);
 	if (ret != ret_ok) return ret;
 
-	return parse_reply_get_port_tls (admin->downloader.body.buf, port);
+	return parse_reply_get_port_tls (&DOWNLOADER(admin->downloader)->body, port);
 }
 
 
@@ -334,11 +372,14 @@
 }
 
 static ret_t
-parse_reply_get_rx (char *reply, cherokee_buffer_t *rx)
+parse_reply_get_rx (cherokee_buffer_t *reply, cherokee_buffer_t *rx)
 {
-	CHECK_AND_SKIP_LITERAL (reply, "server.rx is ");
+	ret_t ret;
 
-	cherokee_buffer_add (rx, reply, strlen(reply));
+	ret = check_and_skip_literal (reply, "server.rx is ");
+	if (ret != ret_ok) return ret;
+
+	cherokee_buffer_add_buffer (rx, reply);
 	return ret_ok;
 }
 
@@ -350,7 +391,7 @@
 	ret = common_processing (admin, ask_get_rx, NULL);
 	if (ret != ret_ok) return ret;
 
-	return parse_reply_get_rx (admin->downloader.body.buf, rx);	
+	return parse_reply_get_rx (&DOWNLOADER(admin->downloader)->body, rx);	
 }
 
 
@@ -363,11 +404,14 @@
 }
 
 static ret_t
-parse_reply_get_tx (char *reply, cherokee_buffer_t *tx)
+parse_reply_get_tx (cherokee_buffer_t *reply, cherokee_buffer_t *tx)
 {
-	CHECK_AND_SKIP_LITERAL (reply, "server.tx is ");
+	ret_t ret;
 
-	cherokee_buffer_add (tx, reply, strlen(reply));
+	ret = check_and_skip_literal (reply, "server.tx is ");
+	if (ret != ret_ok) return ret;
+
+	cherokee_buffer_add_buffer (tx, reply);
 	return ret_ok;
 }
 
@@ -379,7 +423,7 @@
 	ret = common_processing (admin, ask_get_tx, NULL);
 	if (ret != ret_ok) return ret;
 
-	return parse_reply_get_tx (admin->downloader.body.buf, tx);	
+	return parse_reply_get_tx (&DOWNLOADER(admin->downloader)->body, tx);	
 }
 
 
@@ -469,7 +513,7 @@
 	ret = common_processing (admin, ask_get_connections, NULL);
 	if (ret != ret_ok) return ret;
 
-	return parse_reply_get_connections (admin->downloader.body.buf, conns_list);		
+	return parse_reply_get_connections (DOWNLOADER(admin->downloader)->body.buf, conns_list);		
 }
 
 
@@ -506,7 +550,7 @@
 	ret = common_processing (admin, ask_del_connection, id);
 	if (ret != ret_ok) return ret;
 
-	return parse_reply_del_connection (admin->downloader.body.buf, id);	
+	return parse_reply_del_connection (DOWNLOADER(admin->downloader)->body.buf, id);	
 }
 
 
@@ -519,11 +563,14 @@
 }
 
 static ret_t
-parse_reply_thread_number (char *reply, cherokee_buffer_t *num)
+parse_reply_thread_number (cherokee_buffer_t *reply, cherokee_buffer_t *num)
 {
-	CHECK_AND_SKIP_LITERAL (reply, "server.thread_num is ");
+	ret_t ret;
 
-	cherokee_buffer_add (num, reply, strlen(reply));
+	ret = check_and_skip_literal (reply, "server.thread_num is ");
+	if (ret != ret_ok) return ret;
+
+	cherokee_buffer_add_buffer (num, reply);
 	return ret_ok;
 }
 
@@ -535,7 +582,7 @@
 	ret = common_processing (admin, ask_thread_number, NULL);
 	if (ret != ret_ok) return ret;
 
-	return parse_reply_thread_number (admin->downloader.body.buf, num);
+	return parse_reply_thread_number (&DOWNLOADER(admin->downloader)->body, num);
 }
 
 
@@ -574,5 +621,74 @@
 	ret = common_processing (admin, set_backup_mode, INT_TO_POINTER(active));
 	if (ret != ret_ok) return ret;
 
-	return parse_reply_set_backup_mode (admin->downloader.body.buf, active);	
+	return parse_reply_set_backup_mode (DOWNLOADER(admin->downloader)->body.buf, active);	
 }
+
+
+/* Tracing
+ */
+static void
+ask_trace (cherokee_admin_client_t *admin, void *arg)
+{
+	SET_POST (admin, "get server.trace");
+}
+
+static ret_t
+parse_reply_trace (cherokee_buffer_t *reply, cherokee_buffer_t *trace)
+{
+	ret_t ret;
+
+	ret = check_and_skip_literal (reply, "server.trace is ");
+	if (ret != ret_ok) return ret;
+
+	cherokee_buffer_add_buffer (trace, reply);
+	return ret_ok;
+}
+
+ret_t 
+cherokee_admin_client_ask_trace (cherokee_admin_client_t *admin, cherokee_buffer_t *trace)
+{
+	ret_t ret;
+
+	ret = common_processing (admin, ask_trace, NULL);
+	if (ret != ret_ok) return ret;
+
+	return parse_reply_trace (&DOWNLOADER(admin->downloader)->body, trace);
+}
+
+
+static ret_t
+check_reply_trace (cherokee_buffer_t *reply, cherokee_buffer_t *trace)
+{
+	ret_t ret;
+
+	ret = check_and_skip_literal (reply, "ok");
+	if (ret != ret_ok) return ret;
+
+	return ret_ok;
+}
+
+static void
+set_trace_mode (cherokee_admin_client_t *admin, void *arg)
+{
+	cherokee_buffer_t *trace = arg;
+	cherokee_buffer_t  tmp   = CHEROKEE_BUF_INIT;
+	
+	cherokee_buffer_add_str (&tmp, "set server.trace ");
+	cherokee_buffer_add_buffer (&tmp, trace);
+	cherokee_buffer_add_str (&tmp, "\n");
+
+	prepare_and_set_post (admin, tmp.buf, tmp.len);
+	cherokee_buffer_mrproper (&tmp);
+}
+
+ret_t 
+cherokee_admin_client_set_trace (cherokee_admin_client_t *admin, cherokee_buffer_t *trace)
+{
+	ret_t ret;
+
+	ret = common_processing (admin, set_trace_mode, trace);
+	if (ret != ret_ok) return ret;
+
+	return check_reply_trace (&DOWNLOADER(admin->downloader)->body, trace);
+}

Modified: cherokee/trunk/cherokee/admin_client.h
===================================================================
--- cherokee/trunk/cherokee/admin_client.h	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/admin_client.h	2007-12-04 16:32:06 UTC (rev 948)
@@ -41,15 +41,10 @@
 typedef struct cherokee_admin_client cherokee_admin_client_t;
 #define ADMIN_CLIENT(x) ((cherokee_admin_client_t *)(x))
 
-#define RUN_CLIENT_BASE(fdpoll,func_string) { \
-	int                re;                \
+#define RUN_CLIENT_LOOP(func_string) {        \
 	cherokee_boolean_t exit;              \
 	                                      \
 	for (exit = false; !exit;) {          \
-		re = cherokee_fdpoll_watch (  \
-	 		fdpoll, WATCH_SLEEP); \
-		if (re <= 0) continue;        \
-		                              \
 		ret = func_string;            \
 		switch (ret) {                \
 		case ret_error:               \
@@ -71,23 +66,23 @@
 	}                                     \
 }
 
-#define RUN_CLIENT1(client,fdpoll,func,arg)  \
-	cherokee_admin_client_reuse(client); \
-        RUN_CLIENT_BASE(fdpoll,func(client,arg))
+#define RUN_CLIENT1(client,func,arg)            \
+	cherokee_admin_client_reuse(client);    \
+        RUN_CLIENT_LOOP(func(client,arg))
 
-#define RUN_CLIENT2(client,fdpoll,func,arg1,arg2) \
-	cherokee_admin_client_reuse(client);      \
-	RUN_CLIENT_BASE(fdpoll,func(client,arg1,arg2))
+#define RUN_CLIENT2(client,func,arg1,arg2)      \
+	cherokee_admin_client_reuse(client);    \
+	RUN_CLIENT_LOOP(func(client,arg1,arg2))
 
-#define RUN_CLIENT3(client,fdpoll,func,arg1,arg2,arg3) \
-	cherokee_admin_client_reuse(client);           \
-	RUN_CLIENT_BASE(fdpoll,func(client,arg1,arg2,arg3))
+#define RUN_CLIENT3(client,func,arg1,arg2,arg3) \
+	cherokee_admin_client_reuse(client);    \
+	RUN_CLIENT_LOOP(func(client,arg1,arg2,arg3))
 
 
 ret_t cherokee_admin_client_new      (cherokee_admin_client_t **admin);
 ret_t cherokee_admin_client_free     (cherokee_admin_client_t  *admin);
 
-ret_t cherokee_admin_client_prepare        (cherokee_admin_client_t *admin, cherokee_fdpoll_t *poll, cherokee_buffer_t *url);
+ret_t cherokee_admin_client_prepare        (cherokee_admin_client_t *admin, cherokee_fdpoll_t *poll, cherokee_buffer_t *url, cherokee_buffer_t *user, cherokee_buffer_t *pass);
 ret_t cherokee_admin_client_connect        (cherokee_admin_client_t *admin);
 ret_t cherokee_admin_client_reuse          (cherokee_admin_client_t *admin);
 ret_t cherokee_admin_client_internal_step  (cherokee_admin_client_t *admin);
@@ -103,9 +98,12 @@
 
 ret_t cherokee_admin_client_ask_connections (cherokee_admin_client_t *admin, cherokee_list_t *conns);
 ret_t cherokee_admin_client_del_connection  (cherokee_admin_client_t *admin, char *id);
+
 ret_t cherokee_admin_client_ask_thread_num  (cherokee_admin_client_t *admin, cherokee_buffer_t *num);
 ret_t cherokee_admin_client_set_backup_mode (cherokee_admin_client_t *admin, cherokee_boolean_t active);
 
+ret_t cherokee_admin_client_ask_trace       (cherokee_admin_client_t *admin, cherokee_buffer_t *trace);
+ret_t cherokee_admin_client_set_trace       (cherokee_admin_client_t *admin, cherokee_buffer_t *trace);
 
 CHEROKEE_END_DECLS
 

Modified: cherokee/trunk/cherokee/admin_server.c
===================================================================
--- cherokee/trunk/cherokee/admin_server.c	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/admin_server.c	2007-12-04 16:32:06 UTC (rev 948)
@@ -45,7 +45,7 @@
 {
 	cherokee_server_t *srv = HANDLER_SRV(ahdl);
 	srv = srv;
-	cherokee_buffer_add (reply, "ok\n", 3);
+	cherokee_buffer_add_str (reply, "ok\n");
 	return ret_ok;
 }
 
@@ -65,7 +65,7 @@
 {
 	cherokee_server_t *srv = HANDLER_SRV(ahdl);
 	srv = srv;
-	cherokee_buffer_add (reply, "ok\n", 3);
+	cherokee_buffer_add_str (reply, "ok\n");
 	return ret_ok;
 }
 
@@ -236,9 +236,9 @@
 
 	/* Read if the resquest if for turning it on or off
 	 */
-	if (!strncmp (question->buf, "set server.backup_mode on", 25)) {
+	if (cherokee_buffer_cmp_str (question, "set server.backup_mode on") == 0) { 
 		mode = true;
-	} else if (!strncmp (question->buf, "set server.backup_mode off", 26)) {
+	} else if (cherokee_buffer_cmp_str (question, "set server.backup_mode off") == 0) { 
 		mode = false;
 	} else {
 		return ret_error;
@@ -261,3 +261,37 @@
 	return ret_ok;
 }
 
+
+/* Trace
+ */
+
+ret_t 
+cherokee_admin_server_reply_get_trace (cherokee_handler_admin_t *ahdl, cherokee_buffer_t *question, cherokee_buffer_t *reply)
+{
+	ret_t              ret;
+	cherokee_buffer_t *modules_ref = NULL;
+
+	ret = cherokee_trace_get_trace (&modules_ref);
+	if (ret != ret_ok) return ret;
+
+	if (cherokee_buffer_is_empty (modules_ref)) {
+		cherokee_buffer_add_str (reply, "server.trace is None\n");
+	} else {
+		cherokee_buffer_add_va (reply, "server.trace is %s\n", modules_ref->buf);
+	}
+
+	return ret_ok;
+}
+
+
+ret_t 
+cherokee_admin_server_reply_set_trace (cherokee_handler_admin_t *ahdl, cherokee_buffer_t *question, cherokee_buffer_t *reply)
+{
+	ret_t ret;
+
+	ret = cherokee_trace_set_modules (question);
+	if (ret != ret_ok) return ret;
+
+	cherokee_buffer_add_str (reply, "ok\n");
+	return ret_ok;
+}

Modified: cherokee/trunk/cherokee/admin_server.h
===================================================================
--- cherokee/trunk/cherokee/admin_server.h	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/admin_server.h	2007-12-04 16:32:06 UTC (rev 948)
@@ -39,6 +39,9 @@
 ret_t cherokee_admin_server_reply_get_connections (cherokee_handler_admin_t *ahdl, cherokee_buffer_t *question, cherokee_buffer_t *reply);
 ret_t cherokee_admin_server_reply_del_connection  (cherokee_handler_admin_t *ahdl, cherokee_buffer_t *question, cherokee_buffer_t *reply);
 
+ret_t cherokee_admin_server_reply_get_trace (cherokee_handler_admin_t *ahdl, cherokee_buffer_t *question, cherokee_buffer_t *reply);
+ret_t cherokee_admin_server_reply_set_trace (cherokee_handler_admin_t *ahdl, cherokee_buffer_t *question, cherokee_buffer_t *reply);
+
 ret_t cherokee_admin_server_reply_get_thread_num  (cherokee_handler_admin_t *ahdl, cherokee_buffer_t *question, cherokee_buffer_t *reply);
 ret_t cherokee_admin_server_reply_set_backup_mode (cherokee_handler_admin_t *ahdl, cherokee_buffer_t *question, cherokee_buffer_t *reply);
 

Modified: cherokee/trunk/cherokee/buffer.c
===================================================================
--- cherokee/trunk/cherokee/buffer.c	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/buffer.c	2007-12-04 16:32:06 UTC (rev 948)
@@ -1720,3 +1720,36 @@
 	return ret_ok;
 }
 
+
+ret_t 
+cherokee_buffer_trim (cherokee_buffer_t *buf)
+{
+	cuint_t s, e;
+	cuint_t len;
+
+	if (buf->len <= 0)
+		return ret_ok;
+
+	for (s=0; s < buf->len; s++) {
+		char c = buf->buf[s];
+
+		if (c != ' ' && c != '\t' && c != '\r' && c != '\n')
+			break;
+	}
+
+	for (e=0; e < (buf->len - s); e++) {
+		char c = buf->buf[buf->len-(e+1)];
+
+		if (c != ' ' && c != '\t' && c != '\r' && c != '\n')
+			break;		
+	}
+
+	len = buf->len - (s + e);
+
+	memmove (buf->buf, buf->buf+s, len);
+
+	buf->len = len;
+	buf->buf[len] = '\0';
+
+	return ret_ok;
+}

Modified: cherokee/trunk/cherokee/buffer.h
===================================================================
--- cherokee/trunk/cherokee/buffer.h	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/buffer.h	2007-12-04 16:32:06 UTC (rev 948)
@@ -41,7 +41,7 @@
 typedef struct {
 	char *buf;        /**< Memory chunk           */
 	int   size;       /**< Total amount of memory */
-	int   len;        /**< Lenght of the string   */
+	int   len;        /**< Length of the string   */
 } cherokee_buffer_t;
 
 #define BUF(x) ((cherokee_buffer_t *)(x))
@@ -97,6 +97,7 @@
 ret_t cherokee_buffer_remove_chunk       (cherokee_buffer_t  *buf, int from, int len);
 ret_t cherokee_buffer_replace_string     (cherokee_buffer_t  *buf, char *subs, int subs_len, char *repl, int repl_len);
 ret_t cherokee_buffer_substitute_string  (cherokee_buffer_t  *bufsrc, cherokee_buffer_t *bufdst, char *subs, int subs_len, char *repl, int repl_len);
+ret_t cherokee_buffer_trim               (cherokee_buffer_t  *buf);
 
 ret_t cherokee_buffer_ensure_addlen      (cherokee_buffer_t  *buf, size_t alen);
 ret_t cherokee_buffer_ensure_size        (cherokee_buffer_t  *buf, size_t size);

Deleted: cherokee/trunk/cherokee/cherokee_logrotate.c

Modified: cherokee/trunk/cherokee/cherokee_show.c
===================================================================
--- cherokee/trunk/cherokee/cherokee_show.c	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/cherokee_show.c	2007-12-04 16:32:06 UTC (rev 948)
@@ -94,16 +94,16 @@
 	CHECK_ERROR ("port");
 	printf ("Port is %d\n", port);
 
-	RUN_CLIENT1 (client, fdpoll, cherokee_admin_client_ask_port_tls, &port);
+	RUN_CLIENT1 (client, cherokee_admin_client_ask_port_tls, &port);
 	CHECK_ERROR ("port_tls");
 	printf ("Port TLS is %d\n", port);
 	
-	RUN_CLIENT1 (client, fdpoll, cherokee_admin_client_ask_rx, &buf);
+	RUN_CLIENT1 (client, cherokee_admin_client_ask_rx, &buf);
 	CHECK_ERROR ("rx");
 	printf ("Server RX is %s\n", buf.buf);
 	cherokee_buffer_clean (&buf);
 
-	RUN_CLIENT1 (client, fdpoll, cherokee_admin_client_ask_tx, &buf);
+	RUN_CLIENT1 (client, cherokee_admin_client_ask_tx, &buf);
 	CHECK_ERROR ("tx");
 	printf ("Server TX is %s\n", buf.buf);
 

Modified: cherokee/trunk/cherokee/connection.c
===================================================================
--- cherokee/trunk/cherokee/connection.c	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/connection.c	2007-12-04 16:32:06 UTC (rev 948)
@@ -139,7 +139,7 @@
 	cherokee_buffer_init (&n->request_original);
 
 	cherokee_socket_init (&n->socket);
-	cherokee_header_init (&n->header);
+	cherokee_header_init (&n->header, header_type_request);
 	cherokee_post_init (&n->post);
 
 	*conn = n;
@@ -1282,7 +1282,7 @@
 	cuint_t  info_len = 0;
 	CHEROKEE_TEMP(buf, 64);
 
-	/* Get the header "Content-Lenght" content
+	/* Get the header "Content-Length" content
 	 */
 	ret = cherokee_header_get_known (&conn->header, header_content_length, &info, &info_len);
 	if (ret != ret_ok) {
@@ -1368,7 +1368,7 @@
 
 	/* Header parsing
 	 */
-	ret = cherokee_header_parse (&conn->header, &conn->incoming_header, header_type_request, &error_code);
+	ret = cherokee_header_parse (&conn->header, &conn->incoming_header, &error_code);
 	if (unlikely (ret < ret_ok))
 		goto error;
 

Modified: cherokee/trunk/cherokee/downloader-protected.h
===================================================================
--- cherokee/trunk/cherokee/downloader-protected.h	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/downloader-protected.h	2007-12-04 16:32:06 UTC (rev 948)
@@ -62,6 +62,7 @@
 	cherokee_sockaddr_t          sockaddr;
 
 	cherokee_downloader_phase_t  phase;
+	cherokee_downloader_status_t status;
 
 	int                          content_length;
 
@@ -74,8 +75,6 @@
 		uint32_t body_recv;
 	} info;
 
-	cherokee_downloader_status_t status;
-
 	cherokee_buffer_t            tmp1;
 	cherokee_buffer_t            tmp2;
 };

Modified: cherokee/trunk/cherokee/downloader.c
===================================================================
--- cherokee/trunk/cherokee/downloader.c	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/downloader.c	2007-12-04 16:32:06 UTC (rev 948)
@@ -68,7 +68,7 @@
 	ret = cherokee_socket_init (&n->socket);
 	if (unlikely(ret != ret_ok)) return ret;	
 
-	ret = cherokee_header_new (&n->header);	
+	ret = cherokee_header_new (&n->header, header_type_response);	
 	if (unlikely(ret != ret_ok)) return ret;
 
 	cherokee_buffer_init (&n->proxy);
@@ -130,15 +130,7 @@
 ret_t 
 cherokee_downloader_set_url (cherokee_downloader_t *downloader, cherokee_buffer_t *url_string)
 {
-	ret_t                      ret;
-	cherokee_request_header_t *req = &downloader->request;
-
-	/* Parse the string in a URL object
-	 */
-	ret = cherokee_url_parse (&req->url, url_string);
-	if (unlikely(ret < ret_ok)) return ret;
-	
-	return ret_ok;
+	return cherokee_request_header_parse_string (&downloader->request, url_string);
 }
 
 
@@ -173,6 +165,15 @@
 }
 
 
+ret_t
+cherokee_downloader_set_auth (cherokee_downloader_t *downloader, 
+			      cherokee_buffer_t     *user, 
+			      cherokee_buffer_t     *password)
+{
+	return cherokee_request_header_set_auth (&downloader->request, http_auth_basic, user, password);
+}
+
+
 ret_t 
 cherokee_downloader_get_reply_code (cherokee_downloader_t *downloader, cherokee_http_t *code)
 {
@@ -313,7 +314,7 @@
 
 		/* Check the header. Is it complete? 
 		 */
-		ret = cherokee_header_has_header (downloader->header, &downloader->reply_header, readed+4);
+		ret = cherokee_header_has_header (downloader->header, &downloader->reply_header, 0);
 		switch (ret) {
 		case ret_ok:
 			break;
@@ -331,10 +332,8 @@
 		 */
 		ret = cherokee_header_parse (downloader->header,
 		                             &downloader->reply_header,
-		                             header_type_response,
-		                             &error_code
-		);		
-		if (unlikely(ret != ret_ok)) return ret_error;
+		                             &error_code);
+		if (unlikely (ret != ret_ok)) return ret_error;
 
 		/* Look for the length, it will need to drop out the header from the buffer
 		 */
@@ -345,6 +344,9 @@
 		if (downloader->reply_header.len > len) {
 			uint32_t body_chunk;
 			
+			/* Skip the CRLF separator and copy the body
+			 */
+			len += 2;
 			body_chunk = downloader->reply_header.len - len;
 			
 			downloader->info.body_recv += body_chunk;
@@ -360,6 +362,8 @@
 			cherokee_buffer_clean (tmp1);
 			ret = cherokee_header_copy_known (downloader->header, header_content_length, tmp1);
 			downloader->content_length = atoi (tmp1->buf);
+
+			TRACE (ENTRIES, "Known lenght: %d bytes\n", downloader->content_length);
 		}
 
 		return ret_ok;
@@ -438,6 +442,7 @@
 		if (downloader->post != NULL) {
 			req->method = http_post;
 			cherokee_post_walk_reset (downloader->post);
+			req->post_len = downloader->post->size;
 		}
 
 		/* Build the request header
@@ -471,7 +476,6 @@
 
 		if (downloader->post != NULL) {
 			ret = cherokee_post_walk_to_fd (downloader->post, downloader->socket.socket, NULL, NULL);
-
 /*			ret = send_post (downloader); */
 /* 			ret = downloader_send_buffer (downloader, downloader->post_ref); */
 			if (unlikely(ret != ret_ok)) return ret;
@@ -541,6 +545,8 @@
 ret_t 
 cherokee_downloader_post_set (cherokee_downloader_t *downloader, cherokee_post_t *post)
 {
+	TRACE(ENTRIES, "post=%p\n", post);
+
 	if (downloader->post != NULL) {
 		PRINT_ERROR_S ("WARNING: Overwriting post info\n");
 	}
@@ -553,9 +559,16 @@
 ret_t 
 cherokee_downloader_reuse (cherokee_downloader_t *downloader)
 {
+	TRACE(ENTRIES, "%p\n", downloader);
+
 	downloader->phase = downloader_phase_init;
 	downloader->post  = NULL;
 
+	downloader->info.request_sent = 0;
+	downloader->info.headers_recv = 0;
+	downloader->info.post_sent    = 0;
+	downloader->info.body_recv    = 0;
+
 	cherokee_buffer_clean (&downloader->request_header);
 	cherokee_buffer_clean (&downloader->reply_header);
 	cherokee_buffer_clean (&downloader->body);

Modified: cherokee/trunk/cherokee/downloader.h
===================================================================
--- cherokee/trunk/cherokee/downloader.h	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/downloader.h	2007-12-04 16:32:06 UTC (rev 948)
@@ -56,6 +56,7 @@
 ret_t cherokee_downloader_set_url         (cherokee_downloader_t *downloader, cherokee_buffer_t *url);
 ret_t cherokee_downloader_set_keepalive   (cherokee_downloader_t *downloader, cherokee_boolean_t active);
 ret_t cherokee_downloader_set_proxy       (cherokee_downloader_t *downloader, cherokee_buffer_t *proxy, cuint_t port);
+ret_t cherokee_downloader_set_auth        (cherokee_downloader_t *downloader, cherokee_buffer_t *user, cherokee_buffer_t *password);
 
 ret_t cherokee_downloader_get_reply_code  (cherokee_downloader_t *downloader, cherokee_http_t *code);
 
@@ -67,7 +68,6 @@
 ret_t cherokee_downloader_connect         (cherokee_downloader_t *downloader);
 
 ret_t cherokee_downloader_get_status      (cherokee_downloader_t *downloader, cherokee_downloader_status_t *status);
-
 ret_t cherokee_downloader_is_request_sent (cherokee_downloader_t *downloader);
 
 CHEROKEE_END_DECLS

Added: cherokee/trunk/cherokee/downloader_async.c
===================================================================
--- cherokee/trunk/cherokee/downloader_async.c	                        (rev 0)
+++ cherokee/trunk/cherokee/downloader_async.c	2007-12-04 16:32:06 UTC (rev 948)
@@ -0,0 +1,150 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/* Cherokee
+ *
+ * Authors:
+ *      Alvaro Lopez Ortega <alvaro at alobbs.com>
+ *
+ * Copyright (C) 2001-2007 Alvaro Lopez Ortega
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#include "common-internal.h"
+#include "downloader_async.h"
+#include "downloader-protected.h"
+#include "socket.h"
+#include "fdpoll.h"
+#include "util.h"
+
+#define ENTRIES     "adownloader,async"
+#define WATCH_SLEEP 1000
+
+struct cherokee_downloader_async {
+	cherokee_downloader_t  downloader;
+	cherokee_fdpoll_t     *fdpoll_ref;
+	int                    fd_added;
+};
+
+
+
+ret_t 
+cherokee_downloader_async_init (cherokee_downloader_async_t *adownloader)
+{
+	ret_t ret;
+
+	ret = cherokee_downloader_init (DOWNLOADER(adownloader));
+	if (ret != ret_ok) return ret;
+
+	adownloader->fd_added   = -1;
+	adownloader->fdpoll_ref = NULL;
+	return ret_ok;
+}
+
+
+ret_t 
+cherokee_downloader_async_mrproper (cherokee_downloader_async_t *adownloader)
+{
+	if (adownloader->fd_added != -1) 
+		cherokee_fdpoll_del (adownloader->fdpoll_ref, adownloader->fd_added);
+
+	cherokee_downloader_mrproper (DOWNLOADER(adownloader));
+	return ret_ok;
+}
+
+
+CHEROKEE_ADD_FUNC_NEW (downloader_async);
+CHEROKEE_ADD_FUNC_FREE (downloader_async);
+
+
+ret_t 
+cherokee_downloader_async_set_fdpoll (cherokee_downloader_async_t *adownloader, cherokee_fdpoll_t *fdpoll)
+{
+	adownloader->fdpoll_ref = fdpoll;
+	return ret_ok;
+}
+
+
+ret_t 
+cherokee_downloader_async_connect (cherokee_downloader_async_t *adownloader)
+{
+	ret_t                  ret;
+	cherokee_downloader_t *down   = DOWNLOADER(adownloader);
+	cherokee_fdpoll_t     *fdpoll = adownloader->fdpoll_ref;
+
+	if (fdpoll == NULL)
+		return ret_error;
+
+	ret = cherokee_downloader_connect (down);
+	if (ret != ret_ok) return ret;
+
+	ret = cherokee_fd_set_nonblocking (down->socket.socket);
+	if (ret != ret_ok) return ret;
+
+	ret = cherokee_fdpoll_add (fdpoll, down->socket.socket, FDPOLL_MODE_WRITE);
+	if (ret != ret_ok) return ret;
+
+	adownloader->fd_added = down->socket.socket;
+	return ret_ok;
+}
+
+
+ret_t
+cherokee_downloader_async_step (cherokee_downloader_async_t *adownloader)
+{
+	int                    re;
+	int                    fd;
+	int                    rw     = FDPOLL_MODE_READ;
+	cherokee_downloader_t *down   = DOWNLOADER(adownloader);
+	cherokee_fdpoll_t     *fdpoll = adownloader->fdpoll_ref;
+
+	TRACE(ENTRIES, "Enters obj=%p fdpoll=%p\n", adownloader, fdpoll);
+
+	if (fdpoll == NULL)
+		return ret_error;
+
+	/* Watch the fd poll
+	 */		
+	re = cherokee_fdpoll_watch (fdpoll, WATCH_SLEEP);
+	TRACE(ENTRIES, "watch = %d\n", re);
+	if (re <= 0)
+		return ret_eagain;
+
+	/* Check whether we are reading or writting
+	 */
+	if (down->phase <= downloader_phase_send_post) 
+		rw = FDPOLL_MODE_WRITE;
+
+	TRACE(ENTRIES, "rw = %d\n", rw);
+
+	/* Check the downloader fd
+	 */
+	fd = down->socket.socket;
+
+	re = cherokee_fdpoll_check (fdpoll, fd, rw);
+	switch (re) {
+	case -1:
+		PRINT_ERROR("Error polling fd=%d rw=%d\n", fd, rw);
+		return ret_error;
+	case 0:
+ 		TRACE(ENTRIES, "fd=%d rw=%d, not ready\n", fd, rw); 
+//		return ret_eagain;
+	}
+
+	/* If there's something to do, go for it..
+	 */
+	TRACE(ENTRIES, "fd=%d rw=%d is active\n", fd, rw); 
+	return cherokee_downloader_step (down, NULL, NULL);
+}

Added: cherokee/trunk/cherokee/downloader_async.h
===================================================================
--- cherokee/trunk/cherokee/downloader_async.h	                        (rev 0)
+++ cherokee/trunk/cherokee/downloader_async.h	2007-12-04 16:32:06 UTC (rev 948)
@@ -0,0 +1,51 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/* Cherokee
+ *
+ * Authors:
+ *      Alvaro Lopez Ortega <alvaro at alobbs.com>
+ *
+ * Copyright (C) 2001-2007 Alvaro Lopez Ortega
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#if !defined (CHEROKEE_INSIDE_CHEROKEE_H) && !defined (CHEROKEE_COMPILATION)
+# error "Only <cherokee/cherokee.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef CHEROKEE_ASYNC_DOWNLOADER__H
+#define CHEROKEE_ASYNC_DOWNLOADER_H
+
+#include <cherokee/common.h>
+#include <cherokee/downloader.h>
+
+CHEROKEE_BEGIN_DECLS
+
+typedef struct cherokee_downloader_async cherokee_downloader_async_t;
+#define DOWNLOADER_ASYNC(d) ((cherokee_downloader_async_t *)(d))
+
+ret_t cherokee_downloader_async_new        (cherokee_downloader_async_t **downloader);
+ret_t cherokee_downloader_async_free       (cherokee_downloader_async_t  *downloader);
+ret_t cherokee_downloader_async_init       (cherokee_downloader_async_t  *downloader);
+ret_t cherokee_downloader_async_mrproper   (cherokee_downloader_async_t  *downloader);
+
+ret_t cherokee_downloader_async_set_fdpoll (cherokee_downloader_async_t  *downloader, cherokee_fdpoll_t *fdpoll);
+ret_t cherokee_downloader_async_connect    (cherokee_downloader_async_t  *downloader);
+ret_t cherokee_downloader_async_step       (cherokee_downloader_async_t  *downloader);
+
+CHEROKEE_END_DECLS
+
+#endif /* CHEROKEE_ASYNC_DOWNLOADER_H */

Modified: cherokee/trunk/cherokee/fcgi_manager.c
===================================================================
--- cherokee/trunk/cherokee/fcgi_manager.c	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/fcgi_manager.c	2007-12-04 16:32:06 UTC (rev 948)
@@ -90,7 +90,7 @@
 
 
 static void
-update_conn_list_lenght (cherokee_fcgi_manager_t *mgr, cuint_t id)
+update_conn_list_length (cherokee_fcgi_manager_t *mgr, cuint_t id)
 {
 	if (mgr->conn.id2conn[id].conn == NULL) {
 		/* There is room of one connection, notify it
@@ -312,7 +312,7 @@
 		HDL_CGI_BASE(hdl)->got_eof    = true;
 		mgr->conn.id2conn[id].eof = true;
 
-		update_conn_list_lenght (mgr, id);
+		update_conn_list_length (mgr, id);
 
 /* 		printf ("READ:END id=%d gen=%d", id, hdl->generation); */
 		break;
@@ -422,7 +422,7 @@
 	}
 
 	mgr->conn.id2conn[hdl->id].conn = NULL;       
-	update_conn_list_lenght (mgr, hdl->id);
+	update_conn_list_length (mgr, hdl->id);
 
 	return ret_ok;
 }

Modified: cherokee/trunk/cherokee/fdpoll-kqueue.c
===================================================================
--- cherokee/trunk/cherokee/fdpoll-kqueue.c	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/fdpoll-kqueue.c	2007-12-04 16:32:06 UTC (rev 948)
@@ -156,7 +156,7 @@
 _watch (cherokee_fdpoll_kqueue_t *fdp, int timeout_msecs)
 {
 	struct timespec  timeout;
-	int              i, re, fd;
+	int              i;
 	int              n_events;
 
 

Modified: cherokee/trunk/cherokee/handler_admin.c
===================================================================
--- cherokee/trunk/cherokee/handler_admin.c	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/handler_admin.c	2007-12-04 16:32:06 UTC (rev 948)
@@ -87,16 +87,16 @@
 {
 #define COMP(str,sub) strncmp(str, sub, sizeof(sub)-1)
 	
-	if (!COMP (line->buf, "get server.port"))
+	if (!COMP (line->buf, "get server.port_tls"))
+		return cherokee_admin_server_reply_get_port_tls (ahdl, line, &ahdl->reply);
+	else if (!COMP (line->buf, "set server.port_tls"))
+		return cherokee_admin_server_reply_set_port_tls (ahdl, line, &ahdl->reply);
+
+	else if (!COMP (line->buf, "get server.port"))
 		return cherokee_admin_server_reply_get_port (ahdl, line, &ahdl->reply);
 	else if (!COMP (line->buf, "set server.port"))
 		return cherokee_admin_server_reply_set_port (ahdl, line, &ahdl->reply);
 
-	else if (!COMP (line->buf, "get server.port_tls"))
-		return cherokee_admin_server_reply_get_port_tls (ahdl, line, &ahdl->reply);
-	else if (!COMP (line->buf, "set server.port_tls"))
-		return cherokee_admin_server_reply_set_port_tls (ahdl, line, &ahdl->reply);
-
 	else if (!COMP (line->buf, "get server.rx"))
 		return cherokee_admin_server_reply_get_rx (ahdl, line, &ahdl->reply);
 	else if (!COMP (line->buf, "get server.tx"))
@@ -114,6 +114,11 @@
 	else if (!COMP (line->buf, "set server.backup_mode")) 
 		return cherokee_admin_server_reply_set_backup_mode (ahdl, line, &ahdl->reply);
 
+	else if (!COMP (line->buf, "set server.trace")) 
+		return cherokee_admin_server_reply_set_trace (ahdl, line, &ahdl->reply);
+	else if (!COMP (line->buf, "get server.trace")) 
+		return cherokee_admin_server_reply_get_trace (ahdl, line, &ahdl->reply);
+
 	SHOULDNT_HAPPEN;
 	return ret_error;
 }

Modified: cherokee/trunk/cherokee/handler_cgi_base.c
===================================================================
--- cherokee/trunk/cherokee/handler_cgi_base.c	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/handler_cgi_base.c	2007-12-04 16:32:06 UTC (rev 948)
@@ -302,7 +302,7 @@
 		}
 	}
 
-	/* Content-Type and Content-Lenght (if available) 
+	/* Content-Type and Content-Length (if available) 
 	 */
 	cherokee_buffer_clean (tmp);
 	ret = cherokee_header_copy_unknown (&conn->header, "Content-Type", 12, tmp);

Modified: cherokee/trunk/cherokee/header-protected.h
===================================================================
--- cherokee/trunk/cherokee/header-protected.h	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/header-protected.h	2007-12-04 16:32:06 UTC (rev 948)
@@ -56,6 +56,7 @@
 
 	/* Properties
 	 */
+	cherokee_header_type_t  type;
 	cherokee_http_version_t version;
 	cherokee_http_method_t  method;
 	cherokee_http_t         response;

Modified: cherokee/trunk/cherokee/header.c
===================================================================
--- cherokee/trunk/cherokee/header.c	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/header.c	2007-12-04 16:32:06 UTC (rev 948)
@@ -84,17 +84,12 @@
 }
 
 
-/* Implements _new() and _free() 
- */
-CHEROKEE_ADD_FUNC_NEW  (header);
-CHEROKEE_ADD_FUNC_FREE (header);
-
-
 ret_t 
-cherokee_header_init (cherokee_header_t *hdr)
+cherokee_header_init (cherokee_header_t *hdr, cherokee_header_type_t type)
 {
 	/* Known headers
 	 */
+	hdr->type = type;
 	clean_known_headers (hdr);
 
 	/* Unknown headers
@@ -135,7 +130,22 @@
 	return ret_ok;
 }
 
+ret_t 
+cherokee_header_new (cherokee_header_t **hdr, cherokee_header_type_t type)
+{
+	ret_t ret;
+	CHEROKEE_NEW_STRUCT (n, header);
 
+	ret = cherokee_header_init (n, type);
+	if (unlikely (ret != ret_ok)) return ret;
+
+	*hdr = n;
+	return ret_ok;
+}
+
+CHEROKEE_ADD_FUNC_FREE (header);
+
+
 ret_t 
 cherokee_header_clean (cherokee_header_t *hdr)
 {
@@ -529,242 +539,6 @@
 
 
 ret_t 
-cherokee_header_parse (cherokee_header_t *hdr, cherokee_buffer_t *buffer, cherokee_type_header_t type, cherokee_http_t *error_code)
-{
-	ret_t  ret;
-	char  *begin = buffer->buf;
-	char  *end   = NULL;
-	char  *val_beg;
-	char  *val_end;
-	char  *header_end;
-	char  chr_header_end;
-
-	/* Set default error code.
-	 */
-	*error_code = http_bad_request;
-
-	/* Check the buffer content
-	 */
-	if ((buffer->buf == NULL) || (buffer->len < 5)) {
-		PRINT_ERROR_S ("ERROR: Calling cherokee_header_parse() with an empty header\n");
-		return ret_error;
-	}
-
-	/* Set the header buffer
-	 */
-	hdr->input_buffer = buffer;
-
-#ifdef HEADER_INTERNAL_DEBUG
-	hdr->input_buffer_crc = cherokee_buffer_crc32 (buffer);
-#endif
-
-	/* header_len should have already been set by a previous call
-	 * to cherokee_header_has_header() but if not we call it now.
-	 */
-	if (unlikely (hdr->input_header_len < 1)) {
-		/* Strange, anyway go on and look for EOH 
-		 */
-		ret = cherokee_header_has_header(hdr, buffer, buffer->len);
-		if (ret != ret_ok) {
-			if (ret == ret_not_found)
-				PRINT_ERROR("ERROR: EOH not found:\n===\n%s===\n", buffer->buf);
-			else
-				PRINT_ERROR("ERROR: Too many initial CRLF:\n===\n%s===\n", buffer->buf);
-			return ret_error;
-		}
-	}
-	header_end = &(buffer->buf[hdr->input_header_len]);
-
-	/* Terminate current request space (there may be other
-	 * pipelined requests in the buffer) after the EOH.
-	 */
-	chr_header_end = *header_end;
-	*header_end = '\0';
-
-	/* Parse the special first line
-	 */
-	switch (type) {
-	case header_type_request:
-		/* Parse request. Something like this:
-		 * GET /icons/compressed.png HTTP/1.1CRLF
-		 */
-		ret = parse_request_first_line (hdr, buffer, &begin, error_code);
-		if (unlikely(ret < ret_ok)) {
-			PRINT_DEBUG ("ERROR: Failed to parse header_type_request:\n===\n%s===\n", buffer->buf);
-			*header_end = chr_header_end;
-			return ret;
-		}
-		break;
-
-	case header_type_response:
-		ret = parse_response_first_line (hdr, buffer, &begin, error_code);
-		if (unlikely(ret < ret_ok)) {
-			PRINT_DEBUG ("ERROR: Failed to parse header_type_response:\n===\n%s===\n", buffer->buf);
-			*header_end = chr_header_end;
-			return ret;
-		}
-		break;
-
-	case header_type_basic:
-		/* Don't do anything
-		 */
-		break;
-
-	default:
-		*header_end = chr_header_end;
-		SHOULDNT_HAPPEN;
-	}
-
-
-	/* Parse the rest of headers
-	 */
-	while ((begin < header_end) && (end = get_new_line(begin)) != NULL) {
-		cuint_t header_len;
-		int		val_offs;
-		int		val_len;
-		char    first_char;
-		char    chr_end    = *end;
-
-		*end = '\0';
-
-		/* Current line may have embedded CR+SP or CRLF+SP 
-		 */
-		val_beg = strchr (begin, ':');
-		if (unlikely (val_beg == NULL))
-			goto next;
-
-		/* Header name must be at least 1 character long.
-		 */
-		if (unlikely (val_beg == begin))
-			goto next;
-
-		/* Empty values are skipped.
-		 */
-		if (unlikely (end <= val_beg + 1))
-			goto next;
-
-		header_len = val_beg - begin;
-
-		/* Trim heading and leading spaces from header value.
-		 */
-		++val_beg;
-		val_beg += strspn(val_beg, LWS);
-		val_end = end - 1;
-		while (val_end > val_beg && isspace(*val_end)) {
-			val_end--;
-		}
-		val_end++;
-
-		val_offs = val_beg - buffer->buf;
-		val_len  = val_end - val_beg;
-		if (unlikely (val_len < 1))
-			goto next;
-
-		first_char = *begin;
-		if (first_char > 'Z')
-			first_char -=  'a' - 'A';
-
-
-#define header_equals(str,hdr_enum,begin,len) ((len == (sizeof(str)-1)) && \
-					       (hdr->header[hdr_enum].info_off == 0) && \
-					       (strncasecmp (begin, str, sizeof(str)-1) == 0))
-
-		switch (first_char) {
-		case 'A':
-			if (header_equals ("Accept-Encoding", header_accept_encoding, begin, header_len)) {
-				ret = add_known_header (hdr, header_accept_encoding, val_offs, val_len);
-			} else if (header_equals ("Accept-Charset", header_accept_charset, begin, header_len)) {
-				ret = add_known_header (hdr, header_accept_charset, val_offs, val_len);
-			} else if (header_equals ("Accept-Language", header_accept_language, begin, header_len)) {
-				ret = add_known_header (hdr, header_accept_language, val_offs, val_len);
-			} else if (header_equals ("Accept", header_accept, begin, header_len)) {
-				ret = add_known_header (hdr, header_accept, val_offs, val_len);
-			} else if (header_equals ("Authorization", header_authorization, begin, header_len)) {
-				ret = add_known_header (hdr, header_authorization, val_offs, val_len);
-			} else
-				goto unknown; 
-			break;
-		case 'C':
-			if (header_equals ("Connection", header_connection, begin, header_len)) {
-				ret = add_known_header (hdr, header_connection, val_offs, val_len);
-			} else if (header_equals ("Content-Length", header_content_length, begin, header_len)) {
-				ret = add_known_header (hdr, header_content_length, val_offs, val_len);
-			} else if (header_equals ("Cookie", header_cookie, begin, header_len)) {
-				ret = add_known_header (hdr, header_cookie, val_offs, val_len);
-			} else
-				goto unknown;
-			break;
-		case 'H':
-			if (header_equals ("Host", header_host, begin, header_len)) {
-				ret = add_known_header (hdr, header_host, val_offs, val_len);
-			} else
-				goto unknown;
-			break;
-		case 'I':
-			if (header_equals ("If-Modified-Since", header_if_modified_since, begin, header_len)) {
-				ret = add_known_header (hdr, header_if_modified_since, val_offs, val_len);
-			} else if (header_equals ("If-None-Match", header_if_none_match, begin, header_len)) {
-				ret = add_known_header (hdr, header_if_none_match, val_offs, val_len);
-			} else if (header_equals ("If-Range", header_if_range, begin, header_len)) {
-				ret = add_known_header (hdr, header_if_range, val_offs, val_len);
-			} else
-				goto unknown;
-			break;
-		case 'K':
-			if (header_equals ("Keep-Alive", header_keepalive, begin, header_len)) {
-				ret = add_known_header (hdr, header_keepalive, val_offs, val_len);
-			} else
-				goto unknown;
-			break;
-		case 'L':
-			if (header_equals ("Location", header_location, begin, header_len)) {
-				ret = add_known_header (hdr, header_location, val_offs, val_len);
-			} else
-				goto unknown;
-			break;
-		case 'R':
-			if (header_equals ("Range", header_range, begin, header_len)) {
-				ret = add_known_header (hdr, header_range, val_offs, val_len);
-			} else if (header_equals ("Referer", header_referer, begin, header_len)) {
-				ret = add_known_header (hdr, header_referer, val_offs, val_len);
-			} else
-				goto unknown;
-			break;
-		case 'U':
-			if (header_equals ("Upgrade", header_upgrade, begin, header_len)) {
-				ret = add_known_header (hdr, header_upgrade, val_offs, val_len);
-			} else if (header_equals ("User-Agent", header_user_agent, begin, header_len)) {
-				ret = add_known_header (hdr, header_user_agent, val_offs, val_len);
-			} else
-				goto unknown;
-			break;
-		default:
-		unknown:
-			/* Add a unknown header
-			 */
-			ret = add_unknown_header (hdr, begin-buffer->buf, val_offs, val_len);
-		}
-
-		if (ret < ret_ok) {
-			PRINT_ERROR_S ("ERROR: Failed to add_(un)known_header()\n");
-			*header_end = chr_header_end;
-			return ret;
-		}
-
-	next:
-		*end = chr_end;
-
-		while ((*end == CHR_CR) || (*end == CHR_LF))
-			end++;
-		begin = end;
-	}
-
-	*header_end = chr_header_end;
-	return ret_ok;
-}
-
-
-ret_t 
 cherokee_header_get_length (cherokee_header_t *hdr, cuint_t *len)
 {
 	*len = hdr->input_header_len;
@@ -953,9 +727,25 @@
 }
 
 
-ret_t 
-cherokee_header_has_header (cherokee_header_t *hdr, cherokee_buffer_t *buffer, int tail_len)
+static ret_t 
+has_header_response (cherokee_header_t *hdr, cherokee_buffer_t *buffer, int tail_len)
 {
+	char *tmp;
+
+	tmp = strstr (buffer->buf, CRLF_CRLF);
+	if (tmp == NULL) 
+		return ret_not_found;
+
+	/* Content until CRLF_CRLF plus two of the last line CRLF
+	 */
+	hdr->input_header_len = (tmp - buffer->buf) + 2;
+	return ret_ok;
+}
+
+
+static ret_t 
+has_header_request (cherokee_header_t *hdr, cherokee_buffer_t *buffer, int tail_len)
+{
 	char   *start;
 	char   *end;
 	size_t  crlf_len = 0;
@@ -1022,6 +812,268 @@
 
 
 ret_t 
+cherokee_header_has_header (cherokee_header_t *hdr, cherokee_buffer_t *buffer, int tail_len)
+{
+	switch (hdr->type) {
+	case header_type_request:
+		return has_header_request (hdr, buffer, tail_len);
+
+	case header_type_response:
+	case header_type_basic:
+		return has_header_response (hdr, buffer, tail_len);
+
+	default:
+		SHOULDNT_HAPPEN;
+	}
+
+	return ret_error;
+}
+
+
+ret_t 
+cherokee_header_parse (cherokee_header_t *hdr, cherokee_buffer_t *buffer, cherokee_http_t *error_code)
+{
+	ret_t  ret;
+	char  *val_beg;
+	char  *val_end;
+	char  *header_end;
+	char  chr_header_end;
+	char  *begin           = buffer->buf;
+	char  *end             = NULL;
+
+	/* Set default error code.
+	 */
+	*error_code = http_bad_request;
+
+	/* Check the buffer content
+	 */
+	if ((buffer->buf == NULL) || (buffer->len < 5)) {
+		PRINT_ERROR_S ("ERROR: Calling cherokee_header_parse() with an empty header\n");
+		return ret_error;
+	}
+
+	/* Set the header buffer
+	 */
+	hdr->input_buffer = buffer;
+
+#ifdef HEADER_INTERNAL_DEBUG
+	hdr->input_buffer_crc = cherokee_buffer_crc32 (buffer);
+#endif
+
+	/* header_len should have already been set by a previous call
+	 * to cherokee_header_has_header() but if not we call it now.
+	 */
+	if (unlikely (hdr->input_header_len < 1)) {
+		/* Strange, anyway go on and look for EOH 
+		 */
+		ret = has_header_request (hdr, buffer, buffer->len);
+		if (ret != ret_ok) {
+			if (ret == ret_not_found)
+				PRINT_ERROR("ERROR: EOH not found:\n===\n%s===\n", buffer->buf);
+			else
+				PRINT_ERROR("ERROR: Too many initial CRLF:\n===\n%s===\n", buffer->buf);
+			return ret_error;
+		}
+	}
+	header_end = &(buffer->buf[hdr->input_header_len]);
+
+	/* Terminate current request space (there may be other
+	 * pipelined requests in the buffer) after the EOH.
+	 */
+	chr_header_end = *header_end;
+	*header_end = '\0';
+
+	/* Parse the special first line
+	 */
+	switch (hdr->type) {
+	case header_type_request:
+		/* Parse request. Something like this:
+		 * GET /icons/compressed.png HTTP/1.1CRLF
+		 */
+		ret = parse_request_first_line (hdr, buffer, &begin, error_code);
+		if (unlikely(ret < ret_ok)) {
+			PRINT_DEBUG ("ERROR: Failed to parse header_type_request:\n===\n%s===\n", buffer->buf);
+			*header_end = chr_header_end;
+			return ret;
+		}
+		break;
+
+	case header_type_response:
+		ret = parse_response_first_line (hdr, buffer, &begin, error_code);
+		if (unlikely(ret < ret_ok)) {
+			PRINT_DEBUG ("ERROR: Failed to parse header_type_response:\n===\n%s===\n", buffer->buf);
+			*header_end = chr_header_end;
+			return ret;
+		}
+		break;
+
+	case header_type_basic:
+		/* Don't do anything
+		 */
+		break;
+
+	default:
+		*header_end = chr_header_end;
+		SHOULDNT_HAPPEN;
+	}
+
+
+	/* Parse the rest of headers
+	 */
+	while ((begin < header_end)) {
+		cuint_t header_len;
+		int	val_offs;
+		int	val_len;
+		char    first_char;
+		char    chr_end;
+
+		/* Check where the line ends
+		 */
+		end = get_new_line(begin);
+		if (end == NULL)
+			break;
+
+		chr_end = *end;;
+		*end    = '\0';
+
+		/* Current line may have embedded CR+SP or CRLF+SP 
+		 */
+		val_beg = strchr (begin, ':');
+		if (unlikely (val_beg == NULL))
+			goto next;
+
+		/* Header name must be at least 1 character long.
+		 */
+		if (unlikely (val_beg == begin))
+			goto next;
+
+		/* Empty values are skipped.
+		 */
+		if (unlikely (end <= val_beg + 1))
+			goto next;
+
+		header_len = val_beg - begin;
+
+		/* Trim heading and leading spaces from header value.
+		 */
+		++val_beg;
+		val_beg += strspn(val_beg, LWS);
+		val_end = end - 1;
+		while (val_end > val_beg && isspace(*val_end)) {
+			val_end--;
+		}
+		val_end++;
+
+		val_offs = val_beg - buffer->buf;
+		val_len  = val_end - val_beg;
+		if (unlikely (val_len < 1))
+			goto next;
+
+		first_char = *begin;
+		if (first_char > 'Z')
+			first_char -=  'a' - 'A';
+
+
+#define header_equals(str,hdr_enum,begin,len) ((len == (sizeof(str)-1)) && \
+					       (hdr->header[hdr_enum].info_off == 0) && \
+					       (strncasecmp (begin, str, sizeof(str)-1) == 0))
+
+		switch (first_char) {
+		case 'A':
+			if (header_equals ("Accept-Encoding", header_accept_encoding, begin, header_len)) {
+				ret = add_known_header (hdr, header_accept_encoding, val_offs, val_len);
+			} else if (header_equals ("Accept-Charset", header_accept_charset, begin, header_len)) {
+				ret = add_known_header (hdr, header_accept_charset, val_offs, val_len);
+			} else if (header_equals ("Accept-Language", header_accept_language, begin, header_len)) {
+				ret = add_known_header (hdr, header_accept_language, val_offs, val_len);
+			} else if (header_equals ("Accept", header_accept, begin, header_len)) {
+				ret = add_known_header (hdr, header_accept, val_offs, val_len);
+			} else if (header_equals ("Authorization", header_authorization, begin, header_len)) {
+				ret = add_known_header (hdr, header_authorization, val_offs, val_len);
+			} else
+				goto unknown; 
+			break;
+		case 'C':
+			if (header_equals ("Connection", header_connection, begin, header_len)) {
+				ret = add_known_header (hdr, header_connection, val_offs, val_len);
+			} else if (header_equals ("Content-Length", header_content_length, begin, header_len)) {
+				ret = add_known_header (hdr, header_content_length, val_offs, val_len);
+			} else if (header_equals ("Cookie", header_cookie, begin, header_len)) {
+				ret = add_known_header (hdr, header_cookie, val_offs, val_len);
+			} else
+				goto unknown;
+			break;
+		case 'H':
+			if (header_equals ("Host", header_host, begin, header_len)) {
+				ret = add_known_header (hdr, header_host, val_offs, val_len);
+			} else
+				goto unknown;
+			break;
+		case 'I':
+			if (header_equals ("If-Modified-Since", header_if_modified_since, begin, header_len)) {
+				ret = add_known_header (hdr, header_if_modified_since, val_offs, val_len);
+			} else if (header_equals ("If-None-Match", header_if_none_match, begin, header_len)) {
+				ret = add_known_header (hdr, header_if_none_match, val_offs, val_len);
+			} else if (header_equals ("If-Range", header_if_range, begin, header_len)) {
+				ret = add_known_header (hdr, header_if_range, val_offs, val_len);
+			} else
+				goto unknown;
+			break;
+		case 'K':
+			if (header_equals ("Keep-Alive", header_keepalive, begin, header_len)) {
+				ret = add_known_header (hdr, header_keepalive, val_offs, val_len);
+			} else
+				goto unknown;
+			break;
+		case 'L':
+			if (header_equals ("Location", header_location, begin, header_len)) {
+				ret = add_known_header (hdr, header_location, val_offs, val_len);
+			} else
+				goto unknown;
+			break;
+		case 'R':
+			if (header_equals ("Range", header_range, begin, header_len)) {
+				ret = add_known_header (hdr, header_range, val_offs, val_len);
+			} else if (header_equals ("Referer", header_referer, begin, header_len)) {
+				ret = add_known_header (hdr, header_referer, val_offs, val_len);
+			} else
+				goto unknown;
+			break;
+		case 'U':
+			if (header_equals ("Upgrade", header_upgrade, begin, header_len)) {
+				ret = add_known_header (hdr, header_upgrade, val_offs, val_len);
+			} else if (header_equals ("User-Agent", header_user_agent, begin, header_len)) {
+				ret = add_known_header (hdr, header_user_agent, val_offs, val_len);
+			} else
+				goto unknown;
+			break;
+		default:
+		unknown:
+			/* Add a unknown header
+			 */
+			ret = add_unknown_header (hdr, begin-buffer->buf, val_offs, val_len);
+		}
+
+		if (ret < ret_ok) {
+			PRINT_ERROR_S ("ERROR: Failed to add_(un)known_header()\n");
+			*header_end = chr_header_end;
+			return ret;
+		}
+
+	next:
+		*end = chr_end;
+
+		while ((*end == CHR_CR) || (*end == CHR_LF))
+			end++;
+		begin = end;
+	}
+
+	*header_end = chr_header_end;
+	return ret_ok;
+}
+
+
+ret_t 
 cherokee_header_foreach_unknown (cherokee_header_t *hdr, cherokee_header_foreach_func_t func, void *data)
 {
 	int               i;

Modified: cherokee/trunk/cherokee/header.h
===================================================================
--- cherokee/trunk/cherokee/header.h	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/header.h	2007-12-04 16:32:06 UTC (rev 948)
@@ -66,7 +66,7 @@
 	header_type_request,
 	header_type_response, 
 	header_type_basic
-} cherokee_type_header_t;
+} cherokee_header_type_t;
 
 
 typedef struct cherokee_header cherokee_header_t;
@@ -75,13 +75,13 @@
 
 typedef ret_t (* cherokee_header_foreach_func_t) (cherokee_buffer_t *header, cherokee_buffer_t *content, void *data);
 
-ret_t cherokee_header_new                 (cherokee_header_t **hdr);
+ret_t cherokee_header_new                 (cherokee_header_t **hdr, cherokee_header_type_t type);
+ret_t cherokee_header_init                (cherokee_header_t  *hdr, cherokee_header_type_t type);
 ret_t cherokee_header_free                (cherokee_header_t  *hdr);
-ret_t cherokee_header_init                (cherokee_header_t  *hdr);
 ret_t cherokee_header_mrproper            (cherokee_header_t  *hdr);
 
 ret_t cherokee_header_clean               (cherokee_header_t *hdr);
-ret_t cherokee_header_parse               (cherokee_header_t *hdr, cherokee_buffer_t *buffer, cherokee_type_header_t type, cherokee_http_t *error_code);
+ret_t cherokee_header_parse               (cherokee_header_t *hdr, cherokee_buffer_t *buffer, cherokee_http_t *error_code);
 ret_t cherokee_header_has_header          (cherokee_header_t *hdr, cherokee_buffer_t *buffer, int tail_len);
 
 ret_t cherokee_header_get_length          (cherokee_header_t *hdr, cuint_t *len);

Modified: cherokee/trunk/cherokee/logger_ncsa.c
===================================================================
--- cherokee/trunk/cherokee/logger_ncsa.c	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/logger_ncsa.c	2007-12-04 16:32:06 UTC (rev 948)
@@ -338,7 +338,7 @@
 {
 	ret_t              ret;
 	cherokee_buffer_t *log;
-
+	
 	/* Get the buffer
 	 */
 	ret = cherokee_logger_writer_get_buf (&logger->writer_access, &log);

Added: cherokee/trunk/cherokee/main_tweak.c
===================================================================
--- cherokee/trunk/cherokee/main_tweak.c	                        (rev 0)
+++ cherokee/trunk/cherokee/main_tweak.c	2007-12-04 16:32:06 UTC (rev 948)
@@ -0,0 +1,435 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/* Cherokee
+ *
+ * Authors:
+ *      Alvaro Lopez Ortega <alvaro at alobbs.com>
+ *
+ * Copyright (C) 2001-2007 Alvaro Lopez Ortega
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_GETOPT_H
+# include <getopt.h>
+#endif
+
+#include <cherokee/cherokee.h>
+
+#define EXIT_OK     0
+#define EXIT_ERROR  1
+#define WATCH_SLEEP 1000
+#define ENTRIES     "tweak"
+
+#define GETOPT_OPT "hVc:a:l:t:u:p:"
+
+#define CHECK_ERROR(msg)                                          \
+	 if (ret != ret_ok) {                                     \
+	    const char      *error;                               \
+	    cherokee_http_t  code;                                \
+	    cherokee_admin_client_get_reply_code (client, &code); \
+            if (code != http_ok) {                                \
+                cherokee_http_code_to_string (code, &error);	  \
+                printf ("ERROR %s\n", error);                     \
+            } else {                                              \
+		PRINT_ERROR ("ERROR: " msg " ret=%d\n", ret);	  \
+            }                                                     \
+   	    return ret;                                           \
+         }
+
+
+static void
+print_help (void)
+{
+	printf ("Cherokee Tweak\n"
+		"Usage: cherokee_tweak -c command -u url [options]\n\n"
+		"  -h                   Print this help\n"
+		"  -V                   Print version and exit\n\n"
+		" Secutiry:\n"
+		"  -u STRING            User name\n"
+		"  -p STRING            Password\n\n"
+		" Required:\n"
+		"  -c STRING            Command: logrotate, trace, info\n"
+		"  -a URL               URL to the admin interface\n\n"
+		" Logrotate:\n"
+		"  -l PATH              Log file to be rotated\n\n"
+		" Trace:\n"
+		"  -t STRING            Modules to be traced\n"
+		"\n"
+		"Report bugs to cherokee at cherokee-project.org\n");
+}
+
+static void
+print_usage (void)
+{
+	printf ("Cherokee Tweak\n"
+		"Usage: cherokee_tweak -c command -u url [options]\n\n"
+		"Try `cherokee_tweak --help' for more options.\n");
+}
+
+static ret_t
+client_new (cherokee_admin_client_t **client_ret, 
+	    cherokee_fdpoll_t       **fdpoll_ret, 
+	    cherokee_buffer_t        *url,
+	    cherokee_buffer_t        *user,
+	    cherokee_buffer_t        *password)
+{
+	ret_t                    ret;
+	cuint_t                  fds_num;
+	cherokee_fdpoll_t       *fdpoll;
+	cherokee_admin_client_t *client;
+
+	cherokee_sys_fdlimit_get (&fds_num);
+
+	ret = cherokee_fdpoll_best_new (&fdpoll, fds_num, fds_num);
+	if (ret != ret_ok) 
+		return ret;
+	   
+	ret = cherokee_admin_client_new (&client);
+	if (ret != ret_ok) 
+		return ret;
+
+	ret = cherokee_tls_init();
+	if (ret != ret_ok) 
+		return ret;
+
+	ret = cherokee_admin_client_prepare (client, fdpoll, url, user, password);
+ 	if (ret != ret_ok) {
+		PRINT_ERROR_S ("Client prepare failed\n");
+		return ret;
+	}
+
+	ret = cherokee_admin_client_connect (client);
+ 	if (ret != ret_ok) {
+		PRINT_ERROR_S ("Couldn't connect\n");
+		return ret;
+	}
+
+	TRACE(ENTRIES, "fdpoll=%p, client_admin=%p\n", fdpoll, client);
+
+	*fdpoll_ret = fdpoll;
+	*client_ret = client;
+	return ret_ok;
+}
+
+
+static ret_t
+do_trace (cherokee_buffer_t *url, 
+	  cherokee_buffer_t *user, 
+	  cherokee_buffer_t *pass, 
+	  cherokee_buffer_t *trace)
+{
+	ret_t                    ret;
+	cherokee_admin_client_t *client;
+	cherokee_fdpoll_t       *fdpoll;
+
+	ret = client_new (&client, &fdpoll, url, user, pass);
+	if (ret != ret_ok) return ret;
+
+	RUN_CLIENT1 (client, cherokee_admin_client_set_trace, trace);
+	CHECK_ERROR ("trace");
+
+	cherokee_admin_client_free (client);
+	return ret_ok;
+}
+
+
+static ret_t
+look_for_logname (cherokee_buffer_t *logfile, cherokee_buffer_t *logname)
+{
+	DIR               *dir; 
+	char              *tmp;
+	struct dirent     *file;
+	cuint_t            max     = 0;	
+	cherokee_buffer_t  dirname = CHEROKEE_BUF_INIT;
+
+	/* Build the directory name
+	 */
+	cherokee_buffer_add_buffer (&dirname, logfile);
+
+	tmp = strrchr (dirname.buf, '/');
+	if (tmp == NULL) {
+		PRINT_ERROR ("Bad filename '%s'\n", logfile->buf);
+		goto error;
+	}
+
+	cherokee_buffer_drop_endding (&dirname, (dirname.buf + dirname.len) - (tmp + 1));
+
+	/* Read files
+	 */
+	dir = opendir (dirname.buf);
+	if (dir == NULL) {
+		PRINT_ERROR ("Invalid directory '%s'\n", dirname.buf);
+		goto error;
+	}
+
+	while ((file = readdir (dir)) != NULL) {
+		cuint_t  val;
+		char    *numstr;
+		cuint_t d_name_len;
+
+		d_name_len = strlen(file->d_name);
+		cherokee_buffer_add (&dirname, file->d_name, d_name_len);
+
+		if (cherokee_buffer_cmp_buf (&dirname, logname)) {
+			cherokee_buffer_drop_endding (&dirname, d_name_len);
+			continue;
+		}
+		
+		if (dirname.len >= logfile->len + 2) {
+			numstr = dirname.buf + logfile->len + 1;
+			val = strtol (numstr, NULL, 10);
+			
+			if (val > max) 
+				max = val;
+		}
+
+		cherokee_buffer_drop_endding (&dirname, d_name_len);
+	}
+
+	/* Build the new filename
+	 */
+	cherokee_buffer_add_va (logname, "%s.%d", logfile->buf, max + 1);
+
+	cherokee_buffer_mrproper (&dirname);
+	return ret_ok;
+
+error:
+	cherokee_buffer_mrproper (&dirname);
+	return ret_error;	
+}
+
+
+static ret_t
+do_logrotate (cherokee_buffer_t *url, 
+	      cherokee_buffer_t *user, 
+	      cherokee_buffer_t *pass, 
+	      cherokee_buffer_t *log)
+{
+	int                      re;
+	ret_t                    ret;
+	cherokee_admin_client_t *client;
+	cherokee_fdpoll_t       *fdpoll;
+	cherokee_buffer_t        newname = CHEROKEE_BUF_INIT;
+
+	ret = client_new (&client, &fdpoll, url, user, pass);
+	if (ret != ret_ok) return ret;
+
+	/* Look for the log name
+	 */
+	ret = look_for_logname (log, &newname);
+	if (ret != ret_ok) return ret;
+
+	/* Set the server in to backup mode
+	 */
+	printf ("Setting backup mode.. ");
+	RUN_CLIENT1 (client, cherokee_admin_client_set_backup_mode, true);
+	CHECK_ERROR ("backup_mode");
+	printf ("OK\n");
+
+	/* Move logs
+	 */
+	re = rename (log->buf, newname.buf);
+	if (re != 0) {
+		PRINT_ERRNO (errno, "Could not move '%s' to '%s': '${errno}'", log->buf, newname.buf);
+	}
+	printf ("Log file '%s' moved to '%s' successfully\n", log->buf, newname.buf);
+	
+	/* Turn the backup mode off
+	 */
+	printf ("Restoring production mode.. ");
+	RUN_CLIENT1 (client, cherokee_admin_client_set_backup_mode, false);
+	CHECK_ERROR ("backup_mode");
+	printf ("OK\n");
+	
+	cherokee_admin_client_free (client);
+	cherokee_fdpoll_free (fdpoll);
+	return ret_ok;
+}
+
+static void
+print_entry (const char *str, char *format, ...)
+{
+	int i;
+	va_list ap;
+
+	printf ("%s", str);
+	for (i=0; i<20-strlen(str); i++) {
+		printf (" ");
+	}
+
+	va_start (ap, format);
+	vfprintf (stdout, format, ap);
+	va_end (ap);
+
+	printf ("\n");
+}
+
+static ret_t
+do_print_info (cherokee_buffer_t *url,
+	       cherokee_buffer_t *user, 
+	       cherokee_buffer_t *pass)
+{
+	ret_t                    ret;
+	cherokee_admin_client_t *client;
+	cherokee_fdpoll_t       *fdpoll;
+	cherokee_list_t         *i, *tmp;
+
+	cuint_t                  port;
+	cherokee_buffer_t        buf   = CHEROKEE_BUF_INIT;
+	cherokee_list_t          conns = LIST_HEAD_INIT(conns);
+
+	ret = client_new (&client, &fdpoll, url, user, pass);
+	if (ret != ret_ok) return ret;
+
+	RUN_CLIENT1 (client, cherokee_admin_client_ask_port, &port);
+	CHECK_ERROR ("port");
+	print_entry ("HTTP port", "%d", port);
+
+	RUN_CLIENT1 (client, cherokee_admin_client_ask_port_tls, &port);
+	CHECK_ERROR ("port_tls");
+	print_entry ("HTTPS port", "%d", port);
+
+	RUN_CLIENT1 (client, cherokee_admin_client_ask_thread_num, &buf);
+	CHECK_ERROR ("thread_num");
+	print_entry ("Threads", "%s", buf.buf);
+	cherokee_buffer_clean (&buf);
+	
+	RUN_CLIENT1 (client, cherokee_admin_client_ask_rx, &buf);
+	CHECK_ERROR ("rx");
+	print_entry ("Received", "%s", buf.buf);
+	cherokee_buffer_clean (&buf);
+
+	RUN_CLIENT1 (client, cherokee_admin_client_ask_tx, &buf);
+	CHECK_ERROR ("tx");
+	print_entry ("Transfered", "%s", buf.buf);
+
+	RUN_CLIENT1 (client, cherokee_admin_client_ask_connections, &conns);
+	CHECK_ERROR ("conns");
+
+	list_for_each (i, &conns) {
+		cherokee_connection_info_t *conn = CONN_INFO(i);
+		
+		printf ("Request: '%s', phase: '%s', rx: '%s', tx: '%s', size: '%s'\n", 
+			conn->request.buf, conn->phase.buf, conn->rx.buf, 
+			conn->tx.buf, conn->total_size.buf);
+	}
+	
+	list_for_each_safe (i, tmp, &conns) {
+		cherokee_connection_info_free (CONN_INFO(i));
+	}
+
+	/* Clean up
+	 */
+	cherokee_buffer_mrproper (&buf);
+	cherokee_admin_client_free (client);
+	cherokee_fdpoll_free (fdpoll);
+
+	return ret_ok;
+}
+
+
+int 
+main (int argc, char *argv[]) 
+{
+	int                c;
+	cherokee_buffer_t  command  = CHEROKEE_BUF_INIT;
+	cherokee_buffer_t  url      = CHEROKEE_BUF_INIT;
+	cherokee_buffer_t  trace    = CHEROKEE_BUF_INIT;
+	cherokee_buffer_t  log      = CHEROKEE_BUF_INIT;
+	cherokee_buffer_t  user     = CHEROKEE_BUF_INIT;
+	cherokee_buffer_t  password = CHEROKEE_BUF_INIT;
+
+	cherokee_trace_init();
+	TRACE(ENTRIES, "Starts %d args\n", argc-1);
+	
+	/* Parse the parameters
+	 */
+ 	while ((c = getopt(argc, argv, GETOPT_OPT)) != -1) {
+		switch(c) {
+		case 'V':
+			printf ("Cherokee Web Server %s\n"
+				"Copyright (C) 2001-2007 Alvaro Lopez Ortega <alvaro at gnu.org>.\n\n"
+				"This is free software; see the source for copying conditions.  There is NO\n"
+				"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
+				PACKAGE_VERSION);
+			exit(0);
+		case 'u':
+			cherokee_buffer_add (&user, optarg, strlen(optarg));
+			break;
+		case 'p':
+			cherokee_buffer_add (&password, optarg, strlen(optarg));
+			break;
+		case 'c':
+			cherokee_buffer_add (&command, optarg, strlen(optarg));
+			break;
+		case 't':
+			cherokee_buffer_add (&trace, optarg, strlen(optarg));
+			break;
+		case 'a':
+			cherokee_buffer_add (&url, optarg, strlen(optarg));
+			break;
+		case 'l':
+			cherokee_buffer_add (&log, optarg, strlen(optarg));
+			break;
+		case 'h':
+		case '?':
+		default:
+			print_help();
+			exit (EXIT_OK);
+		}
+	}
+
+	/* Ensure that there's a command
+	 */
+	if ((command.len <= 0) || (url.len <= 0)) {
+		PRINT_MSG ("ERROR: A command and the administration URL are needed\n\n");
+		print_usage();
+		exit (EXIT_ERROR);
+	}
+
+	/* Check the command and perform
+	 */
+	if (cherokee_buffer_cmp_str (&command, "trace") == 0) {
+		if (trace.len <= 0) {
+			PRINT_MSG ("ERROR: Trace needs a -t option\n\n");
+			print_usage();
+			exit (EXIT_ERROR);
+		}
+		do_trace (&url, &user, &password, &trace);
+
+	} else if (cherokee_buffer_cmp_str (&command, "logrotate") == 0) {
+		if (log.len <= 0) {
+			PRINT_MSG ("ERROR: Logrotate needs -u and -l options\n\n");
+			print_usage();
+			exit (EXIT_ERROR);
+		}
+		do_logrotate (&url, &user, &password, &log);
+
+	} else if (cherokee_buffer_cmp_str (&command, "info") == 0) {
+		do_print_info (&url, &user, &password);
+
+	} else {
+		PRINT_MSG ("ERROR: Command not recognized\n\n");
+		print_help();
+		exit (EXIT_ERROR);		
+	}
+
+	return EXIT_OK;
+}

Modified: cherokee/trunk/cherokee/post.c
===================================================================
--- cherokee/trunk/cherokee/post.c	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/post.c	2007-12-04 16:32:06 UTC (rev 948)
@@ -89,6 +89,8 @@
 	post->type = (len > POST_SIZE_TO_DISK) ? post_in_tmp_file : post_in_memory;
 	post->size = len;
 
+	TRACE(ENTRIES, "len=%d type=%d\n", len, post->type);
+
 	if (post->type == post_in_tmp_file) {
 		cherokee_buffer_add_str (&post->tmp_file, "/tmp/cherokee_post_XXXXXX");
 
@@ -126,6 +128,8 @@
 ret_t 
 cherokee_post_append (cherokee_post_t *post, char *str, size_t len)
 {
+	TRACE(ENTRIES, "appends=%d bytes\n", len);
+
 	cherokee_buffer_add (&post->info, str, len);
 	cherokee_post_commit_buf (post, len);
 	return ret_ok;
@@ -181,17 +185,22 @@
 ret_t 
 cherokee_post_walk_finished (cherokee_post_t *post)
 {
+	ret_t ret;
+
 	switch (post->type) {
 	case post_in_memory:
-		return (post->walk_offset >= post->info.len) ? ret_ok : ret_eagain;
+		ret = (post->walk_offset >= post->info.len) ? ret_ok : ret_eagain;
+		break;
 	case post_in_tmp_file:
-		return (post->walk_offset >= post->size) ? ret_ok : ret_eagain;
+		ret = (post->walk_offset >= post->size) ? ret_ok : ret_eagain;
+		break;
 	default:
+		ret = ret_error;
 		break;
 	}
 
-	SHOULDNT_HAPPEN;
-	return ret_error;
+	TRACE(ENTRIES, "ret=%d\n", ret);
+	return ret;
 }
 
 
@@ -220,7 +229,7 @@
 			return  ret_error; 			
 		}
 
-		TRACE(ENTRIES, "wrote %d\n", r);
+		TRACE(ENTRIES, "wrote %d bytes from memory\n", r);
 
 		post->walk_offset += r;
 		return cherokee_post_walk_finished (post);

Modified: cherokee/trunk/cherokee/request.c
===================================================================
--- cherokee/trunk/cherokee/request.c	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/request.c	2007-12-04 16:32:06 UTC (rev 948)
@@ -38,6 +38,7 @@
 	 */
 	request->method    = http_get;
 	request->version   = http_version_11;
+	request->auth      = http_auth_nothing;
 	request->proxy     = false;
 	request->keepalive = true;
 	request->pipeline  = 1;
@@ -47,6 +48,8 @@
 	if (unlikely(ret < ret_ok)) return ret;
 
 	cherokee_buffer_init (&request->extra_headers);
+	cherokee_buffer_init (&request->user);
+	cherokee_buffer_init (&request->password);
 	
 	return ret_ok;
 }
@@ -55,7 +58,10 @@
 ret_t 
 cherokee_request_header_mrproper (cherokee_request_header_t *request)
 {
+	cherokee_buffer_mrproper (&request->user);
+	cherokee_buffer_mrproper (&request->password);
 	cherokee_buffer_mrproper (&request->extra_headers);
+
 	cherokee_url_mrproper (&request->url);
 	return ret_ok;
 }
@@ -84,6 +90,13 @@
 
 
 ret_t 
+cherokee_request_header_parse_string (cherokee_request_header_t *request, cherokee_buffer_t *url_string)
+{
+	return cherokee_url_parse (&request->url, url_string, &request->user, &request->password);
+}
+
+
+ret_t 
 cherokee_request_header_build_string (cherokee_request_header_t *request, cherokee_buffer_t *buf, cherokee_buffer_t *tmp1, cherokee_buffer_t *tmp2)
 {
 	ret_t           ret;
@@ -140,9 +153,9 @@
 	if (request->post_len != 0) {
 		/* "Content-Length: " FMT_OFFSET CRLF, request->post_len;
 		 */
-		cherokee_buffer_add_str     (buf, "Content-Length: ");
-		cherokee_buffer_add_ullong10(buf, (cullong_t) request->post_len);
-		cherokee_buffer_add_str     (buf, CRLF);
+		cherokee_buffer_add_str      (buf, "Content-Length: ");
+		cherokee_buffer_add_ullong10 (buf, (cullong_t) request->post_len);
+		cherokee_buffer_add_str      (buf, CRLF);
 	}
 	
 	/* Add "Connection:" header
@@ -155,15 +168,14 @@
 
 	/* Authentication
 	 */
-	if (!cherokee_buffer_is_empty(&url->user) ||
-	    !cherokee_buffer_is_empty(&url->passwd)) {
-
+	if (! cherokee_buffer_is_empty (&request->user) ||
+	    ! cherokee_buffer_is_empty (&request->password)) {
 		cherokee_buffer_clean (tmp1);
 		cherokee_buffer_clean (tmp2);
 
-		cherokee_buffer_add_buffer (tmp1, &url->user);
+		cherokee_buffer_add_buffer (tmp1, &request->user);
 		cherokee_buffer_add_char   (tmp1, ':');
-		cherokee_buffer_add_buffer (tmp1, &url->passwd);
+		cherokee_buffer_add_buffer (tmp1, &request->password);
 
 		cherokee_buffer_encode_base64 (tmp1, tmp2);
 		
@@ -181,7 +193,24 @@
 	/* Finish the header
 	 */
 	cherokee_buffer_add_str (buf, CRLF);
+	return ret_ok;
+}
 
+
+ret_t
+cherokee_request_header_set_auth (cherokee_request_header_t *request, 
+				  cherokee_http_auth_t       auth,
+				  cherokee_buffer_t         *user,
+				  cherokee_buffer_t         *password)
+{
+	request->auth = auth;
+
+	cherokee_buffer_clean (&request->user);
+	cherokee_buffer_clean (&request->password);
+
+	cherokee_buffer_add_buffer (&request->user, user);
+	cherokee_buffer_add_buffer (&request->password, password);
+
 	return ret_ok;
 }
 

Modified: cherokee/trunk/cherokee/request.h
===================================================================
--- cherokee/trunk/cherokee/request.h	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/request.h	2007-12-04 16:32:06 UTC (rev 948)
@@ -43,6 +43,10 @@
 	cherokee_http_version_t version;
 	off_t                   post_len;
 	cherokee_buffer_t       extra_headers;
+
+	cherokee_http_auth_t    auth;
+	cherokee_buffer_t       user;
+	cherokee_buffer_t       password;
 } cherokee_request_header_t;
 
 
@@ -59,8 +63,11 @@
 ret_t cherokee_request_header_clean    (cherokee_request_header_t *request);
 ret_t cherokee_request_header_mrproper (cherokee_request_header_t *request);
 
+ret_t cherokee_request_header_parse_string (cherokee_request_header_t *request, cherokee_buffer_t *url_string);
+ret_t cherokee_request_header_build_string (cherokee_request_header_t *request, cherokee_buffer_t *buf, cherokee_buffer_t *tmp1, cherokee_buffer_t *tmp2);
+
 ret_t cherokee_request_header_uses_proxy   (cherokee_request_header_t *request, cherokee_boolean_t proxy);
 ret_t cherokee_request_header_add_header   (cherokee_request_header_t *request, char *ptr, cuint_t len);
-ret_t cherokee_request_header_build_string (cherokee_request_header_t *request, cherokee_buffer_t *buf, cherokee_buffer_t *tmp1, cherokee_buffer_t *tmp2);
+ret_t cherokee_request_header_set_auth     (cherokee_request_header_t *request, cherokee_http_auth_t auth, cherokee_buffer_t *user, cherokee_buffer_t *password);
 
 #endif /* CHEROKEE_REQUEST_H */

Modified: cherokee/trunk/cherokee/server.c
===================================================================
--- cherokee/trunk/cherokee/server.c	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/server.c	2007-12-04 16:32:06 UTC (rev 948)
@@ -1185,8 +1185,6 @@
 ret_t 
 cherokee_server_stop (cherokee_server_t *srv)
 {
-	ret_t                        ret;
-
 	if (srv == NULL)
 		return ret_ok;
 
@@ -2001,8 +1999,10 @@
 	ret_t            ret;
 	cherokee_list_t *i;
 
-	ret = cherokee_logger_set_backup_mode (srv->vserver_default->logger, active);
-	if (unlikely (ret != ret_ok)) return ret;
+	if (srv->vserver_default->logger) {
+		ret = cherokee_logger_set_backup_mode (srv->vserver_default->logger, active);
+		if (unlikely (ret != ret_ok)) return ret;
+	}
 
 	list_for_each (i, &srv->vservers) {
 		cherokee_logger_t *logger = VSERVER(i)->logger;
@@ -2025,8 +2025,10 @@
 
 	*active = false;
 
-	cherokee_logger_get_backup_mode (srv->vserver_default->logger, active);
-	if (*active == true) return ret_ok;
+	if (srv->vserver_default->logger) {
+		cherokee_logger_get_backup_mode (srv->vserver_default->logger, active);
+		if (*active == true) return ret_ok;
+	}
 
 	list_for_each (i, &srv->vservers) {
 		cherokee_logger_t *logger = VSERVER(i)->logger;

Modified: cherokee/trunk/cherokee/trace.c
===================================================================
--- cherokee/trunk/cherokee/trace.c	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/trace.c	2007-12-04 16:32:06 UTC (rev 948)
@@ -70,7 +70,10 @@
 	/* Store a copy of the modules
 	 */
 	cherokee_buffer_clean (&trace.modules);
-	cherokee_buffer_add_buffer (&trace.modules, modules);
+
+	if (cherokee_buffer_case_cmp_str (modules, "none") != 0) {
+		cherokee_buffer_add_buffer (&trace.modules, modules);
+	}
 	
 	/* Check where to log
 	 */
@@ -118,7 +121,7 @@
 				do_log = true;
 		}
 
-		if (lentry_end == NULL)
+		if ((lentry_end == NULL) || (do_log))
 			break;
 
 		lentry = lentry_end + 1;
@@ -155,3 +158,14 @@
 	cherokee_buffer_mrproper (&entries);
 	return ret_ok;
 }
+
+
+ret_t 
+cherokee_trace_get_trace (cherokee_buffer_t **buf_ref)
+{
+	if (buf_ref == NULL)
+		return ret_not_found;
+
+	*buf_ref = &trace.modules;
+	return ret_ok;
+}

Modified: cherokee/trunk/cherokee/trace.h
===================================================================
--- cherokee/trunk/cherokee/trace.h	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/trace.h	2007-12-04 16:32:06 UTC (rev 948)
@@ -37,6 +37,7 @@
 ret_t cherokee_trace_init        (void);
 ret_t cherokee_trace_set_modules (cherokee_buffer_t *modules);
 ret_t cherokee_trace_do_trace    (const char *entry, const char *file, int line, const char *func, const char *fmt, ...);
+ret_t cherokee_trace_get_trace   (cherokee_buffer_t **buf_ref);
 
 CHEROKEE_END_DECLS
 

Modified: cherokee/trunk/cherokee/url.c
===================================================================
--- cherokee/trunk/cherokee/url.c	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/url.c	2007-12-04 16:32:06 UTC (rev 948)
@@ -45,12 +45,6 @@
 	ret = cherokee_buffer_init (&url->request);
  	if (unlikely(ret < ret_ok)) return ret;
 
-	ret = cherokee_buffer_init (&url->user);
- 	if (unlikely(ret < ret_ok)) return ret;
-
-	ret = cherokee_buffer_init (&url->passwd);
- 	if (unlikely(ret < ret_ok)) return ret;
-	
 	/* Set default values
 	 */
 	url->port = 80;
@@ -63,9 +57,6 @@
 {
 	cherokee_buffer_mrproper (&url->host);
 	cherokee_buffer_mrproper (&url->request);
-	cherokee_buffer_mrproper (&url->user);
-	cherokee_buffer_mrproper (&url->passwd);
-
 	return ret_ok;
 }
 
@@ -77,8 +68,6 @@
 
 	cherokee_buffer_clean (&url->host);
 	cherokee_buffer_clean (&url->request);
-	cherokee_buffer_clean (&url->user);
-	cherokee_buffer_clean (&url->passwd);
 
 	return ret_ok;
 }
@@ -112,7 +101,10 @@
 
 
 static ret_t 
-cherokee_url_parse_ptr (cherokee_url_t *url, char *url_string)
+cherokee_url_parse_guts (cherokee_url_t    *url, 
+			 cherokee_buffer_t *url_buf,
+			 cherokee_buffer_t *user_ret, 
+			 cherokee_buffer_t *password_ret)
 {
 	ret_t    ret;
 	cuint_t  len = 0 ;
@@ -124,10 +116,10 @@
 	
 	/* Drop protocol, if exists..
 	 */
-	ret = parse_protocol (url, url_string, &len);
+	ret = parse_protocol (url, url_buf->buf, &len);
 	if (unlikely(ret < ret_ok)) return ret_error;
 	
-	tmp = url_string + len;
+	tmp = url_buf->buf + len;
 
 	/* User (and password)
 	 */
@@ -137,11 +129,14 @@
 
 		sep = strchr (tmp, ':');
 		if (sep == NULL) {
-			cherokee_buffer_add (&url->user, tmp, arroba - tmp);
+			cherokee_buffer_clean (user_ret);
+			cherokee_buffer_add (user_ret, tmp, arroba - tmp);
 		} else {
-			cherokee_buffer_add (&url->user, tmp, sep - tmp);
+			cherokee_buffer_clean (user_ret);
+			cherokee_buffer_add (user_ret, tmp, sep - tmp);
 			sep++;
-			cherokee_buffer_add (&url->passwd, sep, arroba - sep);
+			cherokee_buffer_clean (password_ret);
+			cherokee_buffer_add (password_ret, sep, arroba - sep);
 		}
 
 		tmp = arroba + 1;
@@ -186,14 +181,17 @@
 }
 
 
-ret_t 
-cherokee_url_parse (cherokee_url_t *url, cherokee_buffer_t *string)
+ret_t
+cherokee_url_parse (cherokee_url_t    *url, 
+		    cherokee_buffer_t *string,
+		    cherokee_buffer_t *user_ret, 
+		    cherokee_buffer_t *password_ret)
 {
-	if (cherokee_buffer_is_empty(string)) {
+	if (cherokee_buffer_is_empty (string)) {
 		return ret_error;
 	}
 
-	return cherokee_url_parse_ptr (url, string->buf);
+	return cherokee_url_parse_guts (url, string, user_ret, password_ret);
 }
 
 
@@ -220,8 +218,5 @@
 	printf ("Host:    %s\n", url->host.buf);
 	printf ("Request: %s\n", url->request.buf);
 	printf ("Port:    %d\n", url->port);
-	printf ("User:    %s\n", url->user.buf);
-	printf ("Pass:    %s\n", url->passwd.buf);
-
 	return ret_ok;
 }

Modified: cherokee/trunk/cherokee/url.h
===================================================================
--- cherokee/trunk/cherokee/url.h	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/url.h	2007-12-04 16:32:06 UTC (rev 948)
@@ -38,9 +38,6 @@
 
 
 typedef struct {	
-	cherokee_buffer_t  user;
-	cherokee_buffer_t  passwd;
-
 	cherokee_buffer_t  host;
 	cuint_t            port;
 	cherokee_buffer_t  request;
@@ -62,7 +59,7 @@
 ret_t cherokee_url_clean    (cherokee_url_t *url);
 ret_t cherokee_url_mrproper (cherokee_url_t *url);
 
-ret_t cherokee_url_parse        (cherokee_url_t *url, cherokee_buffer_t *string);
+ret_t cherokee_url_parse        (cherokee_url_t *url, cherokee_buffer_t *string, cherokee_buffer_t *user_ret, cherokee_buffer_t *password_ret);
 ret_t cherokee_url_build_string (cherokee_url_t *url, cherokee_buffer_t *buf);
 
 ret_t cherokee_url_print (cherokee_url_t *url);

Modified: cherokee/trunk/cherokee/validator.c
===================================================================
--- cherokee/trunk/cherokee/validator.c	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/cherokee/validator.c	2007-12-04 16:32:06 UTC (rev 948)
@@ -292,7 +292,7 @@
 	ret_t              ret;
 	cherokee_buffer_t a2 = CHEROKEE_BUF_INIT;
 
-	/* A1 has to be in string of lenght 32:
+	/* A1 has to be in string of length 32:
 	 * MD5_digest(user":"realm":"passwd)
 	 */
 

Modified: cherokee/trunk/mods-icons.conf.sample
===================================================================
--- cherokee/trunk/mods-icons.conf.sample	2007-11-07 20:26:30 UTC (rev 947)
+++ cherokee/trunk/mods-icons.conf.sample	2007-12-04 16:32:06 UTC (rev 948)
@@ -4,7 +4,7 @@
 icons!directory = folder.png
 icons!parent_directory = back.png
 
-icons!file!core = core
+Icons!file!core = core
 icons!file!*README* = readme.png
 
 icons!suffix!text.png = txt,text




More information about the Cherokee-commits mailing list