OSDN Git Service

* Changed Feature
[modchxj/mod_chxj.git] / src / chxj_cookie.c
index 9319221..f212eec 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005-2008 Atsushi Konno All rights reserved.
+ * Copyright (C) 2005-2009 Atsushi Konno All rights reserved.
  * Copyright (C) 2005 QSDN,Inc. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
 #endif
 #include "chxj_dbm.h"
 
+#define DUMP_HEADERS(X) do { \
+  int __ii; \
+  apr_array_header_t  *__headers = (apr_array_header_t*)apr_table_elts((X)); \
+  apr_table_entry_t   *__hentryp = (apr_table_entry_t*)__headers->elts; \
+  for (__ii=0; __ii<__headers->nelts; __ii++) { \
+    DBG(r, "key:[%s] val:[%s]", __hentryp[__ii].key, __hentryp[__ii].val); \
+  } \
+} while (0) 
+
+
 
 static char* s_get_hostname_from_url(request_rec* r, char* value);
 static char* s_cut_until_end_hostname(request_rec*, char* value);
@@ -49,6 +59,7 @@ static int valid_path(request_rec *r, const char *value);
 static int valid_expires(request_rec *r, const char *value);
 static int valid_secure(request_rec *r, const char *value);
 static int check_valid_cookie_attribute(request_rec *r, const char *pair);
+static int check_valid_cookie_attribute_expires_only(request_rec *r, const char *value);
 
 apr_proc_mutex_t *global_cookie_mutex;
 
@@ -112,11 +123,14 @@ chxj_save_cookie(request_rec *r)
   char                *refer_string;
   apr_uri_t           parsed_uri;
   int                 has_refer;
+  apr_pool_t          *pool;
 
 
   DBG(r, "start chxj_save_cookie()");
 
-  cookie = (cookie_t*)apr_palloc(r->pool, sizeof(cookie_t));
+  apr_pool_create(&pool, r->pool);
+
+  cookie = (cookie_t*)apr_palloc(pool, sizeof(cookie_t));
   cookie->cookie_id = NULL;
 
   has_cookie = 0;
@@ -141,70 +155,66 @@ chxj_save_cookie(request_rec *r)
   err_hentryp = (apr_table_entry_t*)err_headers->elts;
 
 
-  new_cookie_table = apr_table_make(r->pool, 0);
+  new_cookie_table = apr_table_make(pool, 0);
 
   for (ii=0; ii<headers->nelts; ii++) {
     if (strcasecmp(hentryp[ii].key, "Set-Cookie") == 0) {
-      DBG(r, "=====================================");
-      DBG(r, "cookie=[%s:%s]", hentryp[ii].key, hentryp[ii].val);
+      DBG(r, "REQ[%X] cookie=[%s:%s]", TO_ADDR(r), hentryp[ii].key, hentryp[ii].val);
 
       char* key;
       char* val;
       char* buff;
 
-
-      buff = apr_pstrdup(r->pool, hentryp[ii].val);
-      val = strchr(buff, '=');
-      if (val) {
-        key = buff;
-        *val++ = 0;
-        apr_table_add(new_cookie_table, key, val);
-        if (strcasecmp(REFERER_COOKIE_KEY, key) == 0) has_refer++;
-        
+      char *pair = apr_psprintf(pool, "%s:%s", hentryp[ii].key, hentryp[ii].val);
+      if (check_valid_cookie_attribute_expires_only(r, pair)) {
+        buff = apr_pstrdup(pool, hentryp[ii].val);
+        val = strchr(buff, '=');
+        if (val) {
+          key = buff;
+          *val++ = 0;
+          apr_table_set(new_cookie_table, apr_pstrdup(pool, key), apr_pstrdup(pool, val));
+          if (strcasecmp(REFERER_COOKIE_KEY, key) == 0) has_refer++;
+        }
+        has_cookie = 1;
       }
-
-      has_cookie = 1;
-      DBG(r, "=====================================");
     }
   }
   for (ii=0; ii<err_headers->nelts; ii++) {
     if (strcasecmp(err_hentryp[ii].key, "Set-Cookie") == 0) {
-      DBG(r, "=====================================");
-      DBG(r, "cookie=[%s:%s]", err_hentryp[ii].key, err_hentryp[ii].val);
+      DBG(r, "REQ[%X] cookie=[%s:%s]", TO_ADDR(r), err_hentryp[ii].key, err_hentryp[ii].val);
 
       char* key;
       char* val;
       char* buff;
 
-
-      buff = apr_pstrdup(r->pool, err_hentryp[ii].val);
-      val = strchr(buff, '=');
-      if (val) {
-        key = buff;
-        *val++ = 0;
-        apr_table_add(new_cookie_table, key, val);
-        if (strcasecmp(REFERER_COOKIE_KEY, key) == 0) has_refer++;
-        
+      char *pair = apr_psprintf(pool, "%s:%s", err_hentryp[ii].key, err_hentryp[ii].val);
+      if (check_valid_cookie_attribute_expires_only(r, pair)) {
+        buff = apr_pstrdup(pool, err_hentryp[ii].val);
+        val = strchr(buff, '=');
+        if (val) {
+          key = buff;
+          *val++ = 0;
+          apr_table_set(new_cookie_table, apr_pstrdup(pool, key), apr_pstrdup(pool, val));
+          if (strcasecmp(REFERER_COOKIE_KEY, key) == 0) has_refer++;
+        }
+        has_cookie = 1;
       }
-
-      has_cookie = 1;
-      DBG(r, "=====================================");
     }
   }
   apr_table_unset(r->headers_out, "Set-Cookie");
   apr_table_unset(r->err_headers_out, "Set-Cookie");
 
   if (! has_refer) {
-    apr_uri_parse(r->pool,r->uri, &parsed_uri);
-    refer_string = apr_psprintf(r->pool, 
+    apr_uri_parse(pool,r->uri, &parsed_uri);
+    refer_string = apr_psprintf(pool, 
                                 "%s://%s%s", 
                                 chxj_run_http_scheme(r),
                                 r->hostname,
-                                apr_uri_unparse(r->pool,
+                                apr_uri_unparse(pool,
                                                 &parsed_uri,
                                                 APR_URI_UNP_OMITSITEPART));
     if (r->args && strlen(r->args)) {
-      refer_string = apr_pstrcat(r->pool, refer_string, "?", r->args, NULL);
+      refer_string = apr_pstrcat(pool, refer_string, "?", r->args, NULL);
     }
     apr_table_setn(new_cookie_table, REFERER_COOKIE_KEY, refer_string);
     DBG(r, "ADD REFER[%s]", refer_string);
@@ -222,18 +232,20 @@ chxj_save_cookie(request_rec *r)
       hentryp = (apr_table_entry_t*)old_cookie->cookie_headers->elts;
       for (ii=0; ii<old_cookie->cookie_headers->nelts; ii++) {
         if (hentryp && apr_table_get(new_cookie_table, hentryp[ii].key) == NULL) {
-          apr_table_add(new_cookie_table, hentryp[ii].key, hentryp[ii].val);
-          has_cookie = 1;
+          apr_table_add(new_cookie_table, apr_pstrdup(pool, hentryp[ii].key), apr_pstrdup(pool, hentryp[ii].val));
         }
       }
-      chxj_delete_cookie(r,        old_cookie_id);
-      chxj_delete_cookie_expire(r, old_cookie_id);
+      if (has_cookie) {
+        chxj_delete_cookie(r,        old_cookie_id);
+        chxj_delete_cookie_expire(r, old_cookie_id);
+      }
     }
   }
 
+
+
   if (! has_cookie) {
-    DBG(r, "no cookie");
-    DBG(r, "end chxj_save_cookie()");
+    DBG(r, "REQ[%X] end chxj_save_cookie() (no cookie)", (unsigned int)(apr_size_t)r);
     return NULL;
   }
 
@@ -241,33 +253,46 @@ chxj_save_cookie(request_rec *r)
    * create val
    */
   cookie->cookie_headers = (apr_array_header_t*)apr_table_elts(new_cookie_table);
-  store_string = apr_palloc(r->pool, 1);
-  store_string[0] = 0;
   hentryp = (apr_table_entry_t*)cookie->cookie_headers->elts;
-
+  apr_size_t store_string_len = 0;
   for (ii=0; ii<cookie->cookie_headers->nelts; ii++) {
-    if (ii) store_string = apr_pstrcat(r->pool,
-                               store_string, 
-                               "\n",
-                               NULL);
+    if (ii) store_string_len++;
+    store_string_len += (strlen(hentryp[ii].key) + strlen(hentryp[ii].val) + 1);
+  }
+  store_string = apr_palloc(pool, store_string_len + 1);
+  memset(store_string, 0, store_string_len + 1);
+  apr_size_t npos = 0;
 
-    store_string = apr_pstrcat(r->pool, 
-                               store_string, 
-                               hentryp[ii].key, 
-                               "=",
-                               hentryp[ii].val, 
-                               NULL);
+  for (ii=0; ii<cookie->cookie_headers->nelts; ii++) {
+    if (ii) store_string[npos++] = '\n';
+    memcpy(&store_string[npos], hentryp[ii].key, strlen(hentryp[ii].key));
+    npos += strlen(hentryp[ii].key);
+    store_string[npos++] = '=';
+    memcpy(&store_string[npos], hentryp[ii].val, strlen(hentryp[ii].val));
+    npos += strlen(hentryp[ii].val);
   }
 
   if (old_cookie_id && IS_COOKIE_LAZY(dconf)) {
-    DBG(r, "LAZY COOKIE save");
+    DBG(r, "REQ[%X] LAZY COOKIE save",(unsigned int)(apr_size_t)r);
+    cookie->cookie_id = apr_pstrdup(r->pool, old_cookie_id);
+  }
+  else if (old_cookie_id && apr_table_get(r->headers_in, "X-Chxj-Cookie-No-Update")) {
+    DBG(r, "REQ[%X] NO UPDATE MODE",(unsigned int)(apr_size_t)r);
     cookie->cookie_id = apr_pstrdup(r->pool, old_cookie_id);
   }
   else {
-    DBG(r, "NO LAZY COOKIE save. old_cookie_id:[%s] LAZY:[%d]", old_cookie_id,IS_COOKIE_LAZY(dconf));
-    cookie->cookie_id = alloc_cookie_id(r);
+    if (old_cookie_id && apr_table_get(r->headers_in, "X-Chxj-Forward")) {
+      DBG(r, "REQ[%X] NO LAZY COOKIE(X-Chxj-Forward)  save",(unsigned int)(apr_size_t)r);
+      cookie->cookie_id = apr_pstrdup(r->pool, old_cookie_id);
+    }
+    else {
+      DBG(r, "REQ[%X] NO LAZY COOKIE save",(unsigned int)(apr_size_t)r);
+      cookie->cookie_id = alloc_cookie_id(r);
+    }
   }
 
+  DBG(r, "REQ[%X] TYPE:[%d]", (unsigned int)(apr_size_t)r, dconf->cookie_store_type);
+
   {
     int done_proc = 0;
 #if defined(USE_MYSQL_COOKIE)
@@ -298,6 +323,8 @@ chxj_save_cookie(request_rec *r)
       }
     }
   }
+  apr_table_unset(r->headers_out, "Set-Cookie");
+  apr_table_unset(r->err_headers_out, "Set-Cookie");
 
   if (cookie) {
     chxj_save_cookie_expire(r, cookie);
@@ -438,21 +465,23 @@ chxj_load_cookie(request_rec *r, char *cookie_id)
   char                    *pair;
   char                    *header_cookie;
 
-  DBG(r, "start chxj_load_cookie() cookie_id=[%s]", cookie_id);
+  DBG(r, "REQ[%X] start chxj_load_cookie() cookie_id=[%s]", TO_ADDR(r), cookie_id);
   chxj_cookie_expire_gc(r);
 
   cookie = (cookie_t*)apr_palloc(r->pool, sizeof(cookie_t));
   cookie->cookie_headers = NULL;
-  cookie->cookie_id = apr_pstrdup(r->pool, cookie_id);
+  cookie->cookie_id = chxj_url_decode(r->pool, apr_pstrdup(r->pool, cookie_id));
+  cookie->cookie_id = chxj_url_encode(r->pool, cookie->cookie_id);
+
 
   dconf = chxj_get_module_config(r->per_dir_config, &chxj_module);
   entryp = chxj_apply_convrule(r, dconf->convrules);
   if (! entryp) {
-    DBG(r, "end chxj_load_cookie() no pattern");
+    DBG(r, "REQ[%X] end chxj_load_cookie() no pattern", TO_ADDR(r));
     goto on_error0;
   }
   if (! (entryp->action & CONVRULE_COOKIE_ON_BIT)) {
-    DBG(r, "end chxj_load_cookie() CookieOff");
+    DBG(r, "REQ[%X] end chxj_load_cookie() CookieOff", TO_ADDR(r));
     goto on_error0;
   }
   load_cookie_table = apr_table_make(r->pool, 0);
@@ -486,7 +515,7 @@ chxj_load_cookie(request_rec *r, char *cookie_id)
   }
 
   if (load_string) {
-    DBG(r, "load_string=[%s]", load_string);
+    DBG(r, "REQ[%X] load_string=[%s]", TO_ADDR(r), load_string);
     header_cookie = apr_palloc(r->pool, 1);
     header_cookie[0] = 0;
     for (;;) {
@@ -496,7 +525,7 @@ chxj_load_cookie(request_rec *r, char *cookie_id)
       load_string = NULL;
       if (!pair) break;
 
-      DBG(r, "Cookie:[%s]", pair);
+      DBG(r, "REQ[%X] Cookie:[%s]", TO_ADDR(r), pair);
 
       tmp_pair = apr_pstrdup(r->pool, pair);
       val = strchr(tmp_pair, '=');
@@ -504,7 +533,7 @@ chxj_load_cookie(request_rec *r, char *cookie_id)
         key = tmp_pair;
         *val++ = 0;
         apr_table_add(load_cookie_table, key, val);
-        DBG(r, "ADD key:[%s] val:[%s]", key, val);
+        DBG(r, "REQ[%X] ADD key:[%s] val:[%s]", TO_ADDR(r), key, val);
       }
       tmp_pair = apr_pstrdup(r->pool, pair);
       tmp_sem = strchr(tmp_pair, ';'); 
@@ -519,7 +548,7 @@ chxj_load_cookie(request_rec *r, char *cookie_id)
       }
     }
     if (strlen(header_cookie)) {
-      DBG(r, "ADD COOKIE to REQUEST HEADER:[%s]", header_cookie);
+      DBG(r, "REQ[%X] ADD COOKIE to REQUEST HEADER:[%s]", TO_ADDR(r), header_cookie);
       apr_table_add(r->headers_in, "Cookie", header_cookie);
     }
   
@@ -537,13 +566,13 @@ chxj_load_cookie(request_rec *r, char *cookie_id)
     apr_table_setn(r->headers_in, "CHXJ_COOKIE_ID", cookie->cookie_id);
   }
 
-  DBG(r, "end   chxj_load_cookie()");
+  DBG(r, "REQ[%X] end   chxj_load_cookie()", TO_ADDR(r));
   return cookie;
 
 
 on_error0:
 
-  DBG(r, "end   chxj_load_cookie()");
+  DBG(r, "REQ[%X] end   chxj_load_cookie()", TO_ADDR(r));
   return NULL;
 }
 
@@ -615,6 +644,43 @@ check_valid_cookie_attribute(request_rec *r, const char *value)
 
 
 static int
+check_valid_cookie_attribute_expires_only(request_rec *r, const char *value)
+{
+  char *pstat;
+  char *pair;
+  char *first_pair;
+  char *expire_pair = NULL;
+  char *p;
+
+  DBG(r, "REQ[%X] start check_valid_cookie_attribute_expires_only() value:[%s]", (unsigned int)(apr_size_t)r, value);
+
+  expire_pair = NULL;
+  p = apr_pstrdup(r->pool, value);
+
+  /* pass first pair */
+  first_pair = apr_strtok(p, ";", &pstat);
+
+  for (;;) {
+    pair = apr_strtok(NULL, ";", &pstat);
+    if (! pair) break;
+    pair = qs_trim_string(r->pool, pair);
+    if (STRNCASEEQ('e','E',"expires", pair, sizeof("expires")-1)) {
+      expire_pair = apr_pstrdup(r->pool, pair);
+    }
+  }
+
+  if (expire_pair) {
+    if (!valid_expires(r, expire_pair)) {
+      DBG(r, "REQ[%X] invalid expire. expire_pair:[%s]", (unsigned int)(apr_size_t)r, expire_pair);
+      return CHXJ_FALSE;
+    }
+  }
+  DBG(r, "REQ[%X] end check_valid_cookie_attribute_expires_only() value:[%s]", (unsigned int)(apr_size_t)r, value);
+  return CHXJ_TRUE;
+}
+
+
+static int
 valid_domain(request_rec *r, const char *value)
 {
   int  len;
@@ -622,12 +688,16 @@ valid_domain(request_rec *r, const char *value)
   char *val;
   char *pstat;
   char *p = apr_pstrdup(r->pool, value);
-  const char *host = apr_table_get(r->headers_in, HTTP_HOST);
+  char *host = (char *)apr_table_get(r->headers_in, HTTP_HOST);
 
-  DBG(r, "start valid_domain() value:[%s]", value);
-  DBG(r, "host:[%s]", host);
-  if (!host)
+  DBG(r, "REQ[%X] start valid_domain() value:[%s]", TO_ADDR(r), value);
+  if (!host) {
+    DBG(r, "REQ[%X] end valid_domain() value:[%s]", TO_ADDR(r), value);
     return CHXJ_TRUE;
+  }
+  DBG(r, "REQ[%X] host:[%s]", TO_ADDR(r), host);
+  host = s_cut_until_end_hostname(r, apr_pstrdup(r->pool, host));
+  DBG(r, "REQ[%X] host:[%s](after s_cut_until_end_hostname())", TO_ADDR(r), host);
 
   name = apr_strtok(p,"=", &pstat);
   name = qs_trim_string(r->pool, name);
@@ -636,11 +706,12 @@ valid_domain(request_rec *r, const char *value)
   len = strlen(host);
   if (len) {
     if (chxj_strcasenrcmp(r->pool, host, val, strlen(val))) {
-      DBG(r, "not match domain. host domain:[%s] vs value:[%s]", host, val);
+      DBG(r, "REQ[%X] not match domain. host domain:[%s] vs value:[%s]", TO_ADDR(r), host, val);
+      DBG(r, "REQ[%X] end valid_domain() value:[%s]", TO_ADDR(r), value);
       return CHXJ_FALSE;
     }
   }
-  DBG(r, "end valid_domain() value:[%s]", value);
+  DBG(r, "REQ[%X] end valid_domain() value:[%s]", TO_ADDR(r), value);
   return CHXJ_TRUE;
 }
 
@@ -741,8 +812,9 @@ chxj_add_cookie_parameter(request_rec *r, char *value, cookie_t *cookie)
 {
   char *qs;
   char *dst;
+  char *name = "";
 
-  DBG(r, "start chxj_add_cookie_parameter() cookie_id=[%s]", (cookie) ? cookie->cookie_id : NULL);
+  DBG(r, "REQ[%X] start chxj_add_cookie_parameter() cookie_id=[%s]", TO_ADDR(r), (cookie) ? cookie->cookie_id : NULL);
 
   dst = apr_pstrdup(r->pool, value);
 
@@ -753,24 +825,75 @@ chxj_add_cookie_parameter(request_rec *r, char *value, cookie_t *cookie)
     goto on_error;
 
   if (chxj_cookie_check_host(r, value) != 0) {
-    DBG(r, "end chxj_add_cookie_parameter()(check host)");
+    DBG(r, "REQ[%X] end chxj_add_cookie_parameter()(check host)", TO_ADDR(r));
     goto on_error;
   }
 
+  qs = strchr(dst, '#');
+  if (qs) {
+    name = apr_pstrdup(r->pool, qs);
+    *qs = 0;
+  }
+
   qs = strchr(dst, '?');
   if (qs) {
-    dst = apr_psprintf(r->pool, "%s&%s=%s", dst, CHXJ_COOKIE_PARAM, cookie->cookie_id);
+    char *sv_qs = qs;
+    qs = chxj_delete_chxj_cc_param(r, ++qs);
+    DBG(r, "REQ[%X] qs:[%s]",TO_ADDR(r), qs);
+    *sv_qs = 0;
+    if (qs && strlen(qs)) {
+      dst = apr_psprintf(r->pool, "%s?%s", dst, qs);
+    }
+  }
+  if (qs) {
+    dst = apr_psprintf(r->pool, "%s&%s=%s%s", dst, CHXJ_COOKIE_PARAM, cookie->cookie_id, name);
   }
   else {
-    dst = apr_psprintf(r->pool, "%s?%s=%s", dst, CHXJ_COOKIE_PARAM, cookie->cookie_id);
+    dst = apr_psprintf(r->pool, "%s?%s=%s%s", dst, CHXJ_COOKIE_PARAM, cookie->cookie_id, name);
+  }
+
+  DBG(r, "REQ[%X] end   chxj_add_cookie_parameter() dst=[%s]", TO_ADDR(r), dst);
+
+  return dst;
+
+on_error:
+  DBG(r, "REQ[%X] end   chxj_add_cookie_parameter() (on_error)", TO_ADDR(r));
+  return dst;
+}
+
+
+char *
+chxj_add_cookie_no_update_parameter(request_rec *r, char *value)
+{
+  char *qs;
+  char *dst;
+  char *name = "";
+
+  DBG(r, "REQ[%X] start chxj_add_cookie_no_update_parameter()", (unsigned int)(apr_size_t)r);
+
+  if (! value || ! *value) {
+    DBG(r, "REQ[%X] end chxj_add_cookie_parameter()(void value)", (unsigned int)(apr_size_t)r);
+    return apr_pstrdup(r->pool, "");
   }
 
-  DBG(r, "end   chxj_add_cookie_parameter() dst=[%s]", dst);
+  dst = apr_pstrdup(r->pool, value);
+
+  if (chxj_cookie_check_host(r, value) != 0) {
+    DBG(r, "REQ[%X] end chxj_add_cookie_parameter()(check host)", (unsigned int)(apr_size_t)r);
+    goto on_error;
+  }
 
+  qs = strchr(dst, '#');
+  if (qs) {
+    name = apr_pstrdup(r->pool, qs);
+    *qs = 0;
+  }
+  dst = apr_psprintf(r->pool, "%s%c%s=true%s", dst, (strchr(dst,'?')) ? '&' : '?',CHXJ_COOKIE_NOUPDATE_PARAM, name);
+  DBG(r, "REQ[%X] end   chxj_add_cookie_no_update_parameter() dst=[%s]", (unsigned int)(apr_size_t)r, dst);
   return dst;
 
 on_error:
-  DBG(r, "end   chxj_add_cookie_parameter() (on_error)");
+  DBG(r, "REQ[%X] end   chxj_add_cookie_no_update_parameter() (on_error)", (unsigned int)(apr_size_t)r);
   return dst;
 }
 
@@ -779,16 +902,38 @@ int
 chxj_cookie_check_host(request_rec *r, char *value) 
 {
   char *hostnm;
+  mod_chxj_config *dconf;
 
-  DBG(r, "hostname=[%s]", r->hostname);
+  DBG(r, "REQ[%X] start chxj_cookie_check_host()", (unsigned int)(apr_size_t)r);
+  DBG(r, "REQ[%X] hostname=[%s] vs Location:[%s]", (unsigned int)(apr_size_t)r, r->hostname, value);
+
+  dconf = chxj_get_module_config(r->per_dir_config, &chxj_module);
 
   hostnm = s_get_hostname_from_url(r, value);
   if (hostnm) {
-    if (strcasecmp(hostnm, r->hostname) == 0)
-      return 0;
-    else
-      return 1;
+    if (dconf->allowed_cookie_domain) {
+      DBG(r, "REQ[%X] allowed_domain[%s] vs Location:[%s]", (unsigned int)(apr_size_t)r, dconf->allowed_cookie_domain, value);
+      if (chxj_strcasenrcmp(r->pool, hostnm, dconf->allowed_cookie_domain, strlen(dconf->allowed_cookie_domain))) {
+        DBG(r, "REQ[%X] end chxj_cookie_check_host() (false/allowed_domain)", (unsigned int)(apr_size_t)r);
+        return 1;
+      }
+      else {
+        DBG(r, "REQ[%X] end chxj_cookie_check_host() (true/allowed_domain)", (unsigned int)(apr_size_t)r);
+        return 0;
+      }
+    }
+    else {
+      if (strcasecmp(hostnm, r->hostname) == 0) {
+        DBG(r, "REQ[%X] end chxj_cookie_check_host() (true)", (unsigned int)(apr_size_t)r);
+        return 0;
+      }
+      else {
+        DBG(r, "REQ[%X] end chxj_cookie_check_host() (false)", (unsigned int)(apr_size_t)r);
+        return 1;
+      }
+    }
   }
+  DBG(r, "REQ[%X] end chxj_cookie_check_host() (true)", (unsigned int)(apr_size_t)r);
   return 0;
 }
 
@@ -817,7 +962,7 @@ s_cut_until_end_hostname(request_rec *r, char *value)
 
   hostnm = sp = apr_pstrdup(r->pool, value);
   for (;*sp; sp++) {
-    if (*sp == '/'|| *sp == '?') {
+    if (*sp == '/'|| *sp == '?' || *sp == ':') {
       *sp = '\0';
       break;
     }
@@ -1008,58 +1153,64 @@ chxj_parse_cookie_expires(const char *s)
 }
 
 
-int
-chxj_cookie_lock(request_rec *r)
+cookie_lock_t *
+__chxj_cookie_lock(request_rec *r, const char *filename, int line)
 {
   mod_chxj_config *dconf;
   apr_status_t rv;
   int done_proc = 0;
+  cookie_lock_t *ret = NULL;
 
-  DBG(r, "start chxj_cookie_lock()");
+  DBG(r, "start chxj_cookie_lock() call from %s:%d", filename, line);
   if ((rv = apr_proc_mutex_lock(global_cookie_mutex)) != APR_SUCCESS) {
     char errstr[255];
     ERR(r, "%s:%d apr_proc_mutex_lock failure.(%d:%s)", APLOG_MARK, rv, apr_strerror(rv, errstr, 255));
-    return 0;
+    return NULL;
   }
   dconf = chxj_get_module_config(r->per_dir_config, &chxj_module);
 #if defined(USE_MYSQL_COOKIE)
   if (IS_COOKIE_STORE_MYSQL(dconf->cookie_store_type)) {
     if (! chxj_cookie_lock_mysql(r, dconf)) {
       ERR(r, "%s:%d end chxj_cookie_lock(): failed: chxj_cookie_lock_mysql()", APLOG_MARK);
-      return 0;
+      return NULL;
     }
     done_proc = 1;
-  } 
+    ret = apr_palloc(r->pool, sizeof(*ret));
+    memset(ret, 0, sizeof(*ret));
+  }
 #endif
 #if defined(USE_MEMCACHE_COOKIE)
   if (IS_COOKIE_STORE_MEMCACHE(dconf->cookie_store_type)) {
     if (! chxj_cookie_lock_memcache(r, dconf)) {
       ERR(r, "%s:%d end chxj_cookie_lock(): failed: chxj_cookie_lock_memcache()", APLOG_MARK);
-      return 0;
+      return NULL;
     }
     done_proc = 1;
-  } 
+    ret = apr_palloc(r->pool, sizeof(*ret));
+    memset(ret, 0, sizeof(*ret));
+  }
 #endif
   if (!done_proc) {
-    if (! chxj_cookie_lock_dbm(r, dconf)) {
+    if (!(ret = chxj_cookie_lock_dbm(r, dconf))) {
       ERR(r, "%s:%d end chxj_cookie_lock(): failed: chxj_cookie_lock_dbm()", APLOG_MARK);
-      return 0;
+      DBG(r, "end chxj_cookie_lock() call from %s:%d", filename, line);
+      return NULL;
     }
   }
-  DBG(r, "end   chxj_cookie_lock()");
-  return 1;
+  DBG(r, "REQ:[%X] end chxj_cookie_lock() call from %s:%d", (unsigned int)(apr_size_t)r, filename, line);
+  return ret;
 }
 
 
 int
-chxj_cookie_unlock(request_rec *r)
+__chxj_cookie_unlock(request_rec *r, cookie_lock_t *lock, const char *filename, int line)
 {
   mod_chxj_config *dconf;
   int done_proc = 0;
   apr_status_t rv;
   int rtn = 1;
 
-  DBG(r, "start chxj_cookie_unlock()");
+  DBG(r, "start chxj_cookie_unlock() call from %s:%d", filename, line);
 
   dconf = chxj_get_module_config(r->per_dir_config, &chxj_module);
 #if defined(USE_MYSQL_COOKIE)
@@ -1070,7 +1221,7 @@ chxj_cookie_unlock(request_rec *r)
       goto end_chxj_cookie_unlock;
     }
     done_proc = 1;
-  } 
+  }
 #endif
 #if defined(USE_MEMCACHE_COOKIE)
   if (IS_COOKIE_STORE_MEMCACHE(dconf->cookie_store_type)) {
@@ -1080,10 +1231,10 @@ chxj_cookie_unlock(request_rec *r)
       goto end_chxj_cookie_unlock;
     }
     done_proc = 1;
-  } 
+  }
 #endif
   if (!done_proc) {
-    if (! chxj_cookie_unlock_dbm(r, dconf)) {
+    if (! chxj_cookie_unlock_dbm(r, lock, dconf)) {
       ERR(r, "failed: chxj_cookie_unlock_dbm()");
       rtn = 0;
       goto end_chxj_cookie_unlock;
@@ -1093,9 +1244,10 @@ end_chxj_cookie_unlock:
   if ((rv = apr_proc_mutex_unlock(global_cookie_mutex)) != APR_SUCCESS) {
     char errstr[255];
     ERR(r, "%s:%d apr_proc_mutex_unlock failure.(%d:%s)", APLOG_MARK, rv, apr_strerror(rv, errstr, 255));
+    DBG(r, "end chxj_cookie_unlock() call from %s:%d", filename, line);
     return 0;
   }
-  DBG(r, "end   chxj_cookie_unlock()");
+  DBG(r, "end chxj_cookie_unlock() call from %s:%d", filename, line);
 
   return rtn;
 }