/*
+ * Copyright (C) 2005-2009 Atsushi Konno All rights reserved.
* Copyright (C) 2005 QSDN,Inc. All rights reserved.
- * Copyright (C) 2005 Atsushi Konno All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include "chxj_cookie.h"
#include "chxj_url_encode.h"
#include "chxj_apply_convrule.h"
+#include "chxj_str_util.h"
+
+#include "ap_release.h"
#include "apu.h"
#include "apr_dbm.h"
#include "apr_md5.h"
#include "apr_base64.h"
#include "apr_uri.h"
+#include "apr_time.h"
+#include "apr_date.h"
+
+#if defined(USE_MYSQL_COOKIE)
+# include "chxj_mysql.h"
+#endif
+#if defined(USE_MEMCACHE_COOKIE)
+# include "chxj_memcache.h"
+#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);
+static int valid_domain(request_rec *r, const char *value);
+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;
+
+static char *
+alloc_cookie_id(request_rec *r)
+{
+ char *cookie_id;
+ char *uuid_string;
+ unsigned char *md5_value;
+ apr_uuid_t uuid;
+ apr_status_t retval;
+
+ apr_uuid_get(&uuid);
+ uuid_string = apr_palloc(r->pool, APR_UUID_FORMATTED_LENGTH + 1);
+ memset(uuid_string, 0, APR_UUID_FORMATTED_LENGTH + 1);
+ apr_uuid_format(uuid_string, &uuid);;
+
+ md5_value = (unsigned char*)apr_palloc(r->pool, APR_MD5_DIGESTSIZE + 1);
+ memset(md5_value, 0, APR_MD5_DIGESTSIZE + 1);
+
+ retval = apr_md5(md5_value,
+ (const char*)uuid_string,
+ APR_UUID_FORMATTED_LENGTH);
+ if (retval != APR_SUCCESS) {
+ ERR(r, "md5 failed.");
+ return NULL;
+ }
+
+ cookie_id = apr_palloc(r->pool, apr_base64_encode_len(APR_MD5_DIGESTSIZE)+1);
+ memset(cookie_id, 0, APR_MD5_DIGESTSIZE+1);
+ apr_base64_encode(cookie_id, (char*)md5_value, APR_MD5_DIGESTSIZE);
+
+ DBG(r, "cookie_id=[%s]", cookie_id);
+
+ cookie_id = chxj_url_encode(r->pool,cookie_id);
+
+ DBG(r, "cookie_id=[%s]", cookie_id);
+ return cookie_id;
+}
+
/*
*
*/
-cookie_t*
-chxj_save_cookie(request_rec* r)
+cookie_t *
+chxj_save_cookie(request_rec *r)
{
int ii;
- apr_array_header_t* headers;
- apr_table_entry_t* hentryp;
- apr_status_t retval;
- apr_datum_t dbmkey;
- apr_datum_t dbmval;
- apr_dbm_t* f;
- apr_uuid_t uuid;
- char* uuid_string;
- unsigned char* md5_value;
- char* old_cookie_id;
- char* store_string;
- mod_chxj_config* dconf;
- chxjconvrule_entry* entryp;
- apr_file_t* file;
- apr_table_t* new_cookie_table;
+ apr_array_header_t *headers;
+ apr_table_entry_t *hentryp;
+ apr_array_header_t *err_headers;
+ apr_table_entry_t *err_hentryp;
+ char *old_cookie_id;
+ char *store_string;
+ mod_chxj_config *dconf;
+ chxjconvrule_entry *entryp;
+ apr_table_t *new_cookie_table;
int has_cookie = 0;
- cookie_t* cookie;
- cookie_t* old_cookie;
- char* refer_string;
+ cookie_t *cookie;
+ cookie_t *old_cookie;
+ 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;
has_refer = 0;
- dconf = ap_get_module_config(r->per_dir_config, &chxj_module);
+ dconf = chxj_get_module_config(r->per_dir_config, &chxj_module);
entryp = chxj_apply_convrule(r, dconf->convrules);
if (! entryp) {
DBG(r, "end chxj_save_cookie() no pattern");
headers = (apr_array_header_t*)apr_table_elts(r->headers_out);
hentryp = (apr_table_entry_t*)headers->elts;
+ err_headers = (apr_array_header_t*)apr_table_elts(r->err_headers_out);
+ 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, "=====================================");
- DBG2(r, "cookie=[%s:%s]", hentryp[ii].key, hentryp[ii].val);
+ DBG(r, "REQ[%X] cookie=[%s:%s]", (unsigned int)(apr_size_t)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;
}
+ }
+ }
+ for (ii=0; ii<err_headers->nelts; ii++) {
+ if (strcasecmp(err_hentryp[ii].key, "Set-Cookie") == 0) {
+ DBG(r, "REQ[%X] cookie=[%s:%s]", (unsigned int)(apr_size_t)r, err_hentryp[ii].key, err_hentryp[ii].val);
- has_cookie = 1;
- DBG(r, "=====================================");
+ char* key;
+ char* val;
+ char* buff;
+
+ 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;
+ }
}
}
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",
- ap_run_http_method(r),
+ 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);
- DBG1(r, "ADD REFER[%s]", refer_string);
+ DBG(r, "ADD REFER[%s]", refer_string);
has_cookie++;
}
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()");
- return NULL;
- }
-
- file = chxj_cookie_db_lock(r);
- if (! file) {
- ERR(r, "mod_chxj: Can't lock cookie db");
- DBG(r, "end chxj_save_cookie()");
- return NULL;
- }
- DBG(r, " ");
- retval = apr_dbm_open_ex(&f,
- "default",
- chxj_cookie_db_name_create(r, dconf->cookie_db_dir),
- APR_DBM_RWCREATE,
- APR_OS_DEFAULT,
- r->pool);
- if (retval != APR_SUCCESS) {
- DBG(r, "end chxj_save_cookie()");
- ERR2(r, "could not open dbm (type %s) auth file: %s",
- "default",
- chxj_cookie_db_name_create(r,dconf->cookie_db_dir));
- chxj_cookie_db_unlock(r, file);
+ if (! has_cookie) {
+ DBG(r, "REQ[%X] end chxj_save_cookie() (no cookie)", (unsigned int)(apr_size_t)r);
return NULL;
}
- apr_uuid_get(&uuid);
- uuid_string = apr_palloc(r->pool, APR_UUID_FORMATTED_LENGTH + 1);
- memset(uuid_string, 0, APR_UUID_FORMATTED_LENGTH + 1);
- apr_uuid_format(uuid_string, &uuid);;
-
- md5_value = (unsigned char*)apr_palloc(r->pool, APR_MD5_DIGESTSIZE + 1);
- memset(md5_value, 0, APR_MD5_DIGESTSIZE + 1);
-
- retval = apr_md5(md5_value,
- (const char*)uuid_string,
- (apr_size_t)APR_UUID_FORMATTED_LENGTH);
- if (retval != APR_SUCCESS) {
- ERR(r, "md5 failed.");
- goto on_error;
- }
-
- cookie->cookie_id = apr_palloc(r->pool, apr_base64_encode_len(APR_MD5_DIGESTSIZE)+1);
- memset(cookie->cookie_id, 0, APR_MD5_DIGESTSIZE+1);
- apr_base64_encode(cookie->cookie_id, (char*)md5_value, APR_MD5_DIGESTSIZE);
-
- DBG1(r, "cookie->cookie_id=[%s]", cookie->cookie_id);
-
- cookie->cookie_id = chxj_url_encode(r,cookie->cookie_id);
-
- DBG1(r, "cookie->cookie_id=[%s]", cookie->cookie_id);
-
- /*
- * create key
- */
-
- dbmkey.dptr = cookie->cookie_id;
- dbmkey.dsize = strlen(cookie->cookie_id);
-
/*
* 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);
}
- dbmval.dptr = store_string;
- dbmval.dsize = strlen(store_string);
- /*
- * store to db
- */
- retval = apr_dbm_store(f, dbmkey, dbmval);
- if (retval != APR_SUCCESS) {
- ERR1(r, "Cannot store Cookie data to DBM file `%s'",
- chxj_cookie_db_name_create(r, dconf->cookie_db_dir));
- goto on_error;
+ if (old_cookie_id && IS_COOKIE_LAZY(dconf)) {
+ 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 {
+ 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);
+ }
}
- chxj_save_cookie_expire(r, cookie);
+ 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)
+ if (IS_COOKIE_STORE_MYSQL(dconf->cookie_store_type)) {
+ if (! chxj_save_cookie_mysql(r, dconf, cookie->cookie_id, store_string)) {
+ ERR(r, "%s:%d faild: chxj_save_cookie_mysql() cookie_id:[%s]", APLOG_MARK,cookie->cookie_id);
+ cookie = NULL;
+ goto on_error;
+ }
+ done_proc = 1;
+ }
+#endif
+#if defined(USE_MEMCACHE_COOKIE)
+ if (IS_COOKIE_STORE_MEMCACHE(dconf->cookie_store_type)) {
+ if (! chxj_save_cookie_memcache(r, dconf, cookie->cookie_id, store_string)) {
+ ERR(r, "%s:%d failed: chxj_save_cookie_memcache() cookie_id:[%s]", APLOG_MARK, cookie->cookie_id);
+ cookie = NULL;
+ goto on_error;
+ }
+ done_proc = 1;
+ }
+#endif
+ if (IS_COOKIE_STORE_DBM(dconf->cookie_store_type) || ! done_proc) {
+ if (! chxj_save_cookie_dbm(r, dconf, cookie->cookie_id, store_string)) {
+ ERR(r, "%s:%d failed: chxj_save_cookie_dbm() cookie_id:[%s]", APLOG_MARK, cookie->cookie_id);
+ cookie = NULL;
+ goto on_error;
+ }
+ }
+ }
+ 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);
+ }
on_error:
- apr_dbm_close(f);
- chxj_cookie_db_unlock(r, file);
-
DBG(r, "end chxj_save_cookie()");
return cookie;
}
+
+
/*
*
*/
-cookie_t*
-chxj_update_cookie(request_rec* r, cookie_t* old_cookie)
+cookie_t *
+chxj_update_cookie(request_rec *r, cookie_t *old_cookie)
{
int ii;
- apr_array_header_t* headers;
- apr_table_entry_t* hentryp;
- apr_status_t retval;
- apr_datum_t dbmkey;
- apr_datum_t dbmval;
- apr_dbm_t* f;
- apr_uuid_t uuid;
- char* uuid_string;
- unsigned char* md5_value;
- char* store_string;
- mod_chxj_config* dconf;
- chxjconvrule_entry* entryp;
- apr_file_t* file;
- cookie_t* cookie;
+ apr_array_header_t *headers;
+ apr_table_entry_t *hentryp;
+ char *store_string;
+ mod_chxj_config *dconf;
+ chxjconvrule_entry *entryp;
+ cookie_t *cookie;
DBG(r, "start chxj_update_cookie()");
return NULL;
}
- cookie = (cookie_t*)apr_palloc(r->pool, sizeof(cookie_t));
+ cookie = (cookie_t *)apr_palloc(r->pool, sizeof(cookie_t));
cookie->cookie_id = NULL;
-
- dconf = ap_get_module_config(r->per_dir_config, &chxj_module);
+ dconf = chxj_get_module_config(r->per_dir_config, &chxj_module);
entryp = chxj_apply_convrule(r, dconf->convrules);
if (! entryp) {
DBG(r, "end chxj_update_cookie() no pattern");
return NULL;
}
-
headers = (apr_array_header_t*)apr_table_elts(r->headers_out);
hentryp = (apr_table_entry_t*)headers->elts;
-
chxj_delete_cookie(r, old_cookie->cookie_id);
chxj_delete_cookie_expire(r, old_cookie->cookie_id);
- file = chxj_cookie_db_lock(r);
- if (! file) {
- ERR(r, "mod_chxj: Can't lock cookie db");
- return NULL;
+ if (IS_COOKIE_LAZY(dconf)) {
+ DBG(r, "LAZY MODE");
+ cookie->cookie_id = apr_pstrdup(r->pool, old_cookie->cookie_id);
}
-
- DBG(r, " ");
-
- retval = apr_dbm_open_ex(&f,
- "default",
- chxj_cookie_db_name_create(r, dconf->cookie_db_dir),
- APR_DBM_RWCREATE,
- APR_OS_DEFAULT,
- r->pool);
- if (retval != APR_SUCCESS) {
- ERR2(r, "could not open dbm (type %s) auth file: %s",
- "default",
- chxj_cookie_db_name_create(r,dconf->cookie_db_dir));
- chxj_cookie_db_unlock(r, file);
- return NULL;
- }
- DBG(r, " ");
-
- apr_uuid_get(&uuid);
- uuid_string = apr_palloc(r->pool, APR_UUID_FORMATTED_LENGTH + 1);
- memset(uuid_string, 0, APR_UUID_FORMATTED_LENGTH + 1);
- apr_uuid_format(uuid_string, &uuid);;
-
- md5_value = (unsigned char*)apr_palloc(r->pool, APR_MD5_DIGESTSIZE + 1);
- memset(md5_value, 0, APR_MD5_DIGESTSIZE + 1);
-
- retval = apr_md5(md5_value,
- (const char*)uuid_string,
- (apr_size_t)APR_UUID_FORMATTED_LENGTH);
- if (retval != APR_SUCCESS) {
- ERR(r, "md5 failed.");
- goto on_error;
+ else {
+ DBG(r, "NO LAZY MODE");
+ cookie->cookie_id = alloc_cookie_id(r);
}
- DBG(r, " ");
- cookie->cookie_id = apr_palloc(r->pool, apr_base64_encode_len(APR_MD5_DIGESTSIZE)+1);
- memset(cookie->cookie_id, 0, APR_MD5_DIGESTSIZE+1);
- apr_base64_encode(cookie->cookie_id, (char*)md5_value, APR_MD5_DIGESTSIZE);
-
- cookie->cookie_id = chxj_url_encode(r,cookie->cookie_id);
-
- DBG(r, " ");
-
- /*
- * create key
- */
-
- dbmkey.dptr = cookie->cookie_id;
- dbmkey.dsize = strlen(cookie->cookie_id);
-
- /*
- * create val
- */
cookie->cookie_headers = old_cookie->cookie_headers;
store_string = apr_palloc(r->pool, 1);
store_string[0] = 0;
"\n",
NULL);
- DBG2(r, "OLD COOKIE VALUE=[%s][%s]", hentryp[ii].key, hentryp[ii].val);
+ DBG(r, "OLD COOKIE VALUE=[%s][%s]", hentryp[ii].key, hentryp[ii].val);
store_string = apr_pstrcat(r->pool,
store_string,
hentryp[ii].key,
hentryp[ii].val,
NULL);
}
- dbmval.dptr = store_string;
- dbmval.dsize = strlen(store_string);
- /*
- * store to db
- */
- retval = apr_dbm_store(f, dbmkey, dbmval);
- if (retval != APR_SUCCESS) {
- ERR1(r, "Cannot store Cookie data to DBM file `%s'",
- chxj_cookie_db_name_create(r, dconf->cookie_db_dir));
- goto on_error;
+ {
+ int done_proc = 0;
+#if defined(USE_MYSQL_COOKIE)
+ if (IS_COOKIE_STORE_MYSQL(dconf->cookie_store_type)) {
+ if (!chxj_update_cookie_mysql(r, dconf, cookie->cookie_id, store_string)) {
+ ERR(r, "failed: chxj_update_cookie_mysql() cookie_id:[%s]", cookie->cookie_id);
+ goto on_error;
+ }
+ done_proc = 1;
+ }
+#endif
+
+#if defined(USE_MEMCACHE_COOKIE)
+ if (IS_COOKIE_STORE_MEMCACHE(dconf->cookie_store_type)) {
+ if (! chxj_update_cookie_memcache(r, dconf, cookie->cookie_id, store_string)) {
+ ERR(r, "failed: chxj_update_cookie_memcache() cookie_id:[%s]", cookie->cookie_id);
+ goto on_error;
+ }
+ done_proc = 1;
+ }
+#endif
+ if (!done_proc || IS_COOKIE_STORE_DBM(dconf->cookie_store_type)) {
+ if (! chxj_update_cookie_dbm(r, dconf, cookie->cookie_id, store_string)) {
+ ERR(r, "failed: chxj_update_cookie_dbm() cookie_id:[%s]", cookie->cookie_id);
+ goto on_error;
+ }
+ }
}
chxj_save_cookie_expire(r, cookie);
on_error:
- apr_dbm_close(f);
- chxj_cookie_db_unlock(r, file);
-
DBG(r, "end chxj_update_cookie()");
return cookie;
}
*
* @return loaded data.
*/
-cookie_t*
-chxj_load_cookie(request_rec* r, char* cookie_id)
+cookie_t *
+chxj_load_cookie(request_rec *r, char *cookie_id)
{
- apr_status_t retval;
- apr_datum_t dbmkey;
- apr_datum_t dbmval;
- apr_dbm_t* f;
- mod_chxj_config* dconf;
- chxjconvrule_entry* entryp;
- apr_file_t* file;
- cookie_t* cookie;
- apr_table_t* load_cookie_table;
- char* load_string;
- char* pstat;
- char* key;
- char* val;
- char* pair;
-
- DBG(r, "========================================================");
- DBG(r, "========================================================");
- DBG(r, "========================================================");
- DBG(r, "========================================================");
- DBG1(r, "start chxj_load_cookie() cookie_id=[%s]", cookie_id);
+ mod_chxj_config *dconf;
+ chxjconvrule_entry *entryp;
+ cookie_t *cookie;
+ apr_table_t *load_cookie_table;
+ char *load_string = NULL;
+ char *pstat;
+ char *key;
+ char *val;
+ char *pair;
+ char *header_cookie;
+
+ DBG(r, "start chxj_load_cookie() cookie_id=[%s]", 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 = ap_get_module_config(r->per_dir_config, &chxj_module);
+ 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, "end chxj_load_cookie() CookieOff");
goto on_error0;
}
+ load_cookie_table = apr_table_make(r->pool, 0);
-
- file = chxj_cookie_db_lock(r);
- if (! file) {
- ERR(r, "mod_chxj: Can't lock cookie db");
- goto on_error0;
- }
-
- retval = apr_dbm_open_ex(&f,
- "default",
- chxj_cookie_db_name_create(r, dconf->cookie_db_dir),
- APR_DBM_RWCREATE,
- APR_OS_DEFAULT,
- r->pool);
- if (retval != APR_SUCCESS) {
- ERR2(r,
- "could not open dbm (type %s) auth file: %s",
- "default",
- chxj_cookie_db_name_create(r, dconf->cookie_db_dir));
- goto on_error1;
- }
-
- /*
- * create key
- */
- dbmkey.dptr = apr_pstrdup(r->pool, cookie->cookie_id);
- dbmkey.dsize = strlen(dbmkey.dptr);
-
- if (apr_dbm_exists(f, dbmkey)) {
-
- retval = apr_dbm_fetch(f, dbmkey, &dbmval);
- if (retval != APR_SUCCESS) {
- ERR2(r,
- "could not fetch dbm (type %s) auth file: %s", "default",
- chxj_cookie_db_name_create(r, dconf->cookie_db_dir));
- goto on_error2;
+ {
+ int done_proc = 0;
+#if defined(USE_MYSQL_COOKIE)
+ if (IS_COOKIE_STORE_MYSQL(dconf->cookie_store_type)) {
+ if (! (load_string = chxj_load_cookie_mysql(r, dconf, cookie->cookie_id))) {
+ ERR(r, "%s:%d failed: chxj_load_cookie_mysql() cookie_id:[%s]", APLOG_MARK, cookie_id);
+ goto on_error0;
+ }
+ done_proc = 1;
}
- load_cookie_table = apr_table_make(r->pool, 0);
- load_string = apr_palloc(r->pool, dbmval.dsize+1);
-
- memset(load_string, 0, dbmval.dsize+1);
- memcpy(load_string, dbmval.dptr, dbmval.dsize);
-
- char* header_cookie = apr_palloc(r->pool, 1);
+#endif
+#if defined(USE_MEMCACHE_COOKIE)
+ if (IS_COOKIE_STORE_MEMCACHE(dconf->cookie_store_type)) {
+ if (! (load_string = chxj_load_cookie_memcache(r, dconf, cookie->cookie_id))) {
+ ERR(r, "%s:%d failed: chxj_load_cookie_memcache() cookie_id:[%s]", APLOG_MARK,cookie_id);
+ goto on_error0;
+ }
+ done_proc = 1;
+ }
+#endif
+ if (!done_proc || IS_COOKIE_STORE_DBM(dconf->cookie_store_type)) {
+ if (! (load_string = chxj_load_cookie_dbm(r, dconf, cookie->cookie_id))) {
+ ERR(r, "%s:%d failed: chxj_load_cookie_dbm() cookie_id:[%s]", APLOG_MARK,cookie_id);
+ goto on_error0;
+ }
+ }
+ }
+ if (load_string) {
+ DBG(r, "load_string=[%s]", load_string);
+ header_cookie = apr_palloc(r->pool, 1);
header_cookie[0] = 0;
for (;;) {
- char* tmp_sem;
+ char *tmp_sem;
+ char *tmp_pair;
pair = apr_strtok(load_string, "\n", &pstat);
load_string = NULL;
if (!pair) break;
- DBG1(r, "Cookie:[%s]", pair);
- char* tmp_pair;
+ DBG(r, "Cookie:[%s]", pair);
tmp_pair = apr_pstrdup(r->pool, pair);
val = strchr(tmp_pair, '=');
key = tmp_pair;
*val++ = 0;
apr_table_add(load_cookie_table, key, val);
+ DBG(r, "ADD key:[%s] val:[%s]", key, val);
}
- tmp_sem = strchr(pair, ';');
+ tmp_pair = apr_pstrdup(r->pool, pair);
+ tmp_sem = strchr(tmp_pair, ';');
if (tmp_sem)
*tmp_sem = '\0';
- if (strlen(header_cookie))
- header_cookie = apr_pstrcat(r->pool, header_cookie, ";", NULL);
-
- header_cookie = apr_pstrcat(r->pool, header_cookie, pair, NULL);
+ if (check_valid_cookie_attribute(r, pair)) {
+ if (strlen(header_cookie))
+ header_cookie = apr_pstrcat(r->pool, header_cookie, ";", NULL);
+
+ header_cookie = apr_pstrcat(r->pool, header_cookie, tmp_pair, NULL);
+ }
}
- if (strlen(header_cookie))
+ if (strlen(header_cookie)) {
+ DBG(r, "ADD COOKIE to REQUEST HEADER:[%s]", header_cookie);
apr_table_add(r->headers_in, "Cookie", header_cookie);
+ }
cookie->cookie_headers = (apr_array_header_t*)apr_table_elts(load_cookie_table);
*/
apr_table_setn(r->headers_in, "CHXJ_COOKIE_ID", cookie->cookie_id);
}
- apr_dbm_close(f);
- chxj_cookie_db_unlock(r, file);
- DBG(r, "end chxj_load_cookie()");
- DBG(r, "========================================================");
- DBG(r, "========================================================");
- DBG(r, "========================================================");
- DBG(r, "========================================================");
+ DBG(r, "end chxj_load_cookie()");
return cookie;
-on_error2:
- apr_dbm_close(f);
-
-on_error1:
- chxj_cookie_db_unlock(r, file);
-
on_error0:
DBG(r, "end chxj_load_cookie()");
- DBG(r, "========================================================");
- DBG(r, "========================================================");
- DBG(r, "========================================================");
- DBG(r, "========================================================");
return NULL;
}
+static int
+check_valid_cookie_attribute(request_rec *r, const char *value)
+{
+ char *pstat;
+ char *pair;
+ char *first_pair;
+ char *domain_pair;
+ char *path_pair;
+ char *expire_pair;
+ char *secure_pair;
+ char *p;
+
+ DBG(r, "start check_valid_cookie_attribute() value:[%s]", value);
+
+ domain_pair = path_pair = expire_pair = secure_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('d','D',"domain", pair, sizeof("domain")-1)) {
+ domain_pair = apr_pstrdup(r->pool, pair);
+ }
+ else if (STRNCASEEQ('p','P',"path", pair, sizeof("path")-1)) {
+ path_pair = apr_pstrdup(r->pool, pair);
+ }
+ else if (STRNCASEEQ('e','E',"expires", pair, sizeof("expires")-1)) {
+ expire_pair = apr_pstrdup(r->pool, pair);
+ }
+ else if (STRNCASEEQ('s','S',"secure", pair, sizeof("secure")-1)) {
+ secure_pair = apr_pstrdup(r->pool, pair);
+ }
+ }
+
+ if (domain_pair) {
+ if (!valid_domain(r, domain_pair)) {
+ DBG(r, "invalid domain. domain_pair:[%s]", domain_pair);
+ return CHXJ_FALSE;
+ }
+ }
+ if (path_pair) {
+ if (!valid_path(r, path_pair)) {
+ DBG(r, "invalid path. path_pair:[%s]", path_pair);
+ return CHXJ_FALSE;
+ }
+ }
+ if (expire_pair) {
+ if (!valid_expires(r, expire_pair)) {
+ DBG(r, "invalid expire. expire_pair:[%s]", expire_pair);
+ return CHXJ_FALSE;
+ }
+ }
+ if (secure_pair) {
+ if (!valid_secure(r, secure_pair)) {
+ DBG(r, "invalid secure. secure_pair:[%s]", secure_pair);
+ return CHXJ_FALSE;
+ }
+ }
+ DBG(r, "end check_valid_cookie_attribute() value:[%s]", value);
+ return CHXJ_TRUE;
+}
+
+
+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;
+ char *name;
+ char *val;
+ char *pstat;
+ char *p = apr_pstrdup(r->pool, value);
+ const char *host = apr_table_get(r->headers_in, HTTP_HOST);
+
+ DBG(r, "start valid_domain() value:[%s]", value);
+ DBG(r, "host:[%s]", host);
+ if (!host)
+ return CHXJ_TRUE;
+
+ name = apr_strtok(p,"=", &pstat);
+ name = qs_trim_string(r->pool, name);
+ val = apr_strtok(NULL, "=", &pstat);
+ val = qs_trim_string(r->pool, val);
+ 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);
+ return CHXJ_FALSE;
+ }
+ }
+ DBG(r, "end valid_domain() value:[%s]", value);
+ return CHXJ_TRUE;
+}
+
+
+static int
+valid_path(request_rec *r, const char *value)
+{
+ char *p = apr_pstrdup(r->pool, value);
+ char *uri;
+ char *tmp;
+ char *name;
+ char *val;
+ char *pstat;
+
+ DBG(r, "start valid_path() unparsed_uri:[%s] value:[%s]", r->unparsed_uri, value);
+ if (chxj_starts_with(r->unparsed_uri, "http://")) {
+ uri = strchr(&r->unparsed_uri[sizeof("http://")], '/');
+ if (uri != NULL) {
+ uri = apr_pstrdup(r->pool, uri);
+ }
+ }
+ else if (chxj_starts_with(r->unparsed_uri, "https://")) {
+ uri = strchr(&r->unparsed_uri[sizeof("https://")], '/');
+ if (uri != NULL) {
+ uri = apr_pstrdup(r->pool, uri);
+ }
+ }
+ else if (chxj_starts_with(r->unparsed_uri, "/")) {
+ uri = apr_pstrdup(r->pool, r->unparsed_uri);
+ }
+ else {
+ uri = apr_pstrdup(r->pool, "/");
+ }
+
+ if ((tmp = strchr(uri, '?'))) {
+ *tmp = '\0';
+ }
+ DBG(r, "uri=[%s]", uri);
+ name = apr_strtok(p, "=", &pstat);
+ val = apr_strtok(NULL, "=", &pstat);
+ name = qs_trim_string(r->pool, name);
+ val = qs_trim_string(r->pool, val);
+ DBG(r, "name=[%s] val=[%s]", name, val);
+
+ DBG(r, "val:[%s] vs uri:[%s]", val, uri);
+ if (! chxj_starts_with(uri, val)) {
+ DBG(r, "end valid_path() unparsed_uri:[%s] value:[%s] (false)", r->unparsed_uri, value);
+ return CHXJ_FALSE;
+ }
+ DBG(r, "end valid_path() unparsed_uri:[%s] value:[%s] (true)", r->unparsed_uri, value);
+ return CHXJ_TRUE;
+}
+
-char*
-chxj_add_cookie_parameter(request_rec* r, char* value, cookie_t* cookie)
+static int
+valid_expires(request_rec *r, const char *value)
{
- char* qs;
- char* dst;
+ char *name;
+ char *val;
+ char *p = apr_pstrdup(r->pool, value);
+ char *pstat;
+ apr_time_t expires;
+ apr_time_t now;
+
+ DBG(r, "start valid_expire() value:[%s]", value);
+ name = apr_strtok(p, "=", &pstat);
+ val = apr_strtok(NULL, "=", &pstat);
+ DBG(r, "name=[%s] val=[%s]", name, val);
+ now = apr_time_now();
+ expires = chxj_parse_cookie_expires(val);
+ if (expires < now) {
+ DBG(r, "end valid_expire() value:[%s] (expired)", value);
+ return CHXJ_FALSE;
+ }
+
+ DBG(r, "end valid_expire() value:[%s] (non expired)", value);
+ return CHXJ_TRUE;
+}
- DBG1(r, "start chxj_add_cookie_parameter() cookie_id=[%s]", (cookie) ? cookie->cookie_id : NULL);
+
+static int
+valid_secure(request_rec *r, const char *value)
+{
+ const char *scheme;
+ DBG(r, "start valid_secure() value:[%s]", value);
+ scheme = chxj_apache_run_http_scheme(r);
+ if (strcasecmp("https", scheme)) {
+ DBG(r, "end valid_secure() value:[%s] (non secure)", value);
+ return CHXJ_FALSE;
+ }
+ DBG(r, "end valid_secure() value:[%s] (secure)", value);
+ return CHXJ_TRUE;
+}
+
+
+char *
+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);
dst = apr_pstrdup(r->pool, value);
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);
+ 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);
}
- DBG1(r, "end chxj_add_cookie_parameter() dst=[%s]", dst);
+ DBG(r, "end chxj_add_cookie_parameter() dst=[%s]", dst);
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, "");
+ }
+
+ 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, "REQ[%X] end chxj_add_cookie_no_update_parameter() (on_error)", (unsigned int)(apr_size_t)r);
+ return dst;
+}
+
+
int
-chxj_cookie_check_host(request_rec* r, char* value)
+chxj_cookie_check_host(request_rec *r, char *value)
{
- char* hostnm;
+ char *hostnm;
+ mod_chxj_config *dconf;
+
+ 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);
- DBG1(r, "hostname=[%s]", r->hostname);
+ 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;
}
-static char*
-s_get_hostname_from_url(request_rec* r, char* value)
+static char *
+s_get_hostname_from_url(request_rec *r, char *value)
{
if (!value)
return NULL;
}
-static char*
-s_cut_until_end_hostname(request_rec* r, char* value)
+static char *
+s_cut_until_end_hostname(request_rec *r, char *value)
{
- char* sp;
- char* hostnm;
+ char *sp;
+ char *hostnm;
hostnm = sp = apr_pstrdup(r->pool, value);
for (;*sp; sp++) {
- if (*sp == '/'|| *sp == '?') {
+ if (*sp == '/'|| *sp == '?' || *sp == ':') {
*sp = '\0';
break;
}
}
-apr_file_t*
-chxj_cookie_db_lock(request_rec* r)
-{
- apr_file_t* file;
- apr_status_t rv;
- mod_chxj_config* dconf;
-
- dconf = (mod_chxj_config*)ap_get_module_config(r->per_dir_config, &chxj_module);
-
- rv = apr_file_open(&file,
- chxj_cookie_db_lock_name_create(r, dconf->cookie_db_dir),
- APR_CREATE|APR_WRITE,
- APR_OS_DEFAULT,
- r->pool);
- if (rv != APR_SUCCESS) {
- ERR(r, "cookie lock file open failed.");
- return NULL;
- }
-
- rv = apr_file_lock(file,APR_FLOCK_EXCLUSIVE);
- if (rv != APR_SUCCESS) {
- ERR(r, "cookie lock file open failed.");
- apr_file_close(file);
- return NULL;
- }
-
- return file;
-}
-
void
-chxj_cookie_db_unlock(request_rec* r, apr_file_t* file)
+chxj_delete_cookie(request_rec *r, const char *cookie_id)
{
- apr_status_t rv;
-
- rv = apr_file_unlock(file);
- if (rv != APR_SUCCESS) {
- ERR(r, "cookie lock file open failed.");
- return;
- }
-
- apr_file_close(file);
-}
-
-
-void
-chxj_delete_cookie(request_rec* r, char* cookie_id)
-{
- apr_status_t retval;
- apr_datum_t dbmkey;
- apr_dbm_t* f;
- apr_file_t* file;
- mod_chxj_config* dconf;
+ int done_proc = 0;
+ mod_chxj_config *dconf;
DBG(r, "start chxj_delete_cookie()");
-
- file = chxj_cookie_db_lock(r);
- if (! file) {
- ERR(r, "mod_chxj: Can't lock cookie db");
- goto on_error0;
- }
- dconf = ap_get_module_config(r->per_dir_config, &chxj_module);
-
- retval = apr_dbm_open_ex(&f,
- "default",
- chxj_cookie_db_name_create(r, dconf->cookie_db_dir),
- APR_DBM_RWCREATE,
- APR_OS_DEFAULT,
- r->pool);
- if (retval != APR_SUCCESS) {
- ERR2(r,
- "could not open dbm (type %s) auth file: %s",
- "default",
- chxj_cookie_db_name_create(r,dconf->cookie_db_dir));
- goto on_error1;
- }
-
- /*
- * create key
- */
- dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
- dbmkey.dsize = strlen(dbmkey.dptr);
- if (apr_dbm_exists(f, dbmkey)) {
- apr_dbm_delete(f, dbmkey);
+ 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_delete_cookie_mysql(r, dconf, cookie_id)) {
+ ERR(r, "failed: chxj_delete_cookie_mysql() cookie_id:[%s]", cookie_id);
+ DBG(r, "end chxj_delete_cookie()");
+ return;
+ }
+ done_proc = 1;
+ }
+#endif
+#if defined(USE_MEMCACHE_COOKIE)
+ if (IS_COOKIE_STORE_MEMCACHE(dconf->cookie_store_type)) {
+ if (! chxj_delete_cookie_memcache(r, dconf, cookie_id)) {
+ ERR(r, "failed: chxj_delete_cookie_memcache() cookie_id:[%s]", cookie_id);
+ DBG(r, "end chxj_delete_cookie()");
+ return;
+ }
+ done_proc = 1;
+ }
+#endif
+ if (!done_proc || IS_COOKIE_STORE_DBM(dconf->cookie_store_type)) {
+ if (! chxj_delete_cookie_dbm(r, dconf, cookie_id)) {
+ ERR(r, "failed: chxj_delete_cookie_dbm() cookie_id:[%s]", cookie_id);
+ DBG(r, "end chxj_delete_cookie()");
+ return;
+ }
}
- apr_dbm_close(f);
- chxj_cookie_db_unlock(r, file);
DBG(r, "end chxj_delete_cookie()");
-
- return;
-
-on_error1:
- chxj_cookie_db_unlock(r, file);
-
-on_error0:
- return;
-
-}
-
-
-char*
-chxj_cookie_db_name_create(request_rec* r, const char* dir)
-{
- char* dst;
-
- if (!dir) {
- dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
- }
- else {
- dst = apr_pstrdup(r->pool, dir);
- }
-
- if (dst[strlen(dst)-1] != '/') {
- dst = apr_pstrcat(r->pool, dst, "/", COOKIE_DB_NAME, NULL);
- }
- else {
- dst = apr_pstrcat(r->pool, dst, COOKIE_DB_NAME, NULL);
- }
-
- return dst;
}
-char*
-chxj_cookie_db_lock_name_create(request_rec* r, const char* dir)
-{
- char* dst;
- DBG(r, "start chxj_cookie_db_lock_name_create()");
-
- if (!dir) {
-DBG(r, " ");
- dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
-DBG(r, " ");
- }
- else {
-DBG1(r, " dir=[%x]", (unsigned int)dir);
- dst = apr_pstrdup(r->pool, dir);
-DBG(r, " ");
- }
-DBG1(r, "dst[strlen(dst)-1]=[%c]", dst[strlen(dst)-1]);
- if (dst[strlen(dst)-1] != '/') {
- dst = apr_pstrcat(r->pool, dst, "/", COOKIE_DB_LOCK_NAME, NULL);
- }
- else {
- dst = apr_pstrcat(r->pool, dst, COOKIE_DB_LOCK_NAME, NULL);
- }
- DBG(r, "end chxj_cookie_db_lock_name_create()");
- return dst;
-}
/*
*
*/
void
-chxj_save_cookie_expire(request_rec* r, cookie_t* cookie)
+chxj_save_cookie_expire(request_rec *r, cookie_t *cookie)
{
- apr_status_t retval;
- apr_datum_t dbmkey;
- apr_datum_t dbmval;
- apr_dbm_t* f;
- apr_file_t* file;
- mod_chxj_config* dconf;
- char* store_string;
+ int done_proc = 0;
+ mod_chxj_config *dconf;
DBG(r, "start chxj_save_cookie_expire()");
if (!cookie) {
DBG(r, "cookie is NULL");
return;
}
-
- dconf = ap_get_module_config(r->per_dir_config, &chxj_module);
- if (!dconf) {
- DBG(r, "dconf is NULL");
+ if (!cookie->cookie_id) {
+ DBG(r, "cookie->cookie_id is NULL");
return;
}
- file = chxj_cookie_expire_db_lock(r);
- if (! file) {
- ERR(r, "mod_chxj: Can't lock cookie db");
- return;
- }
-
- DBG(r, " ");
-
- retval = apr_dbm_open_ex(&f,
- "default",
- chxj_cookie_expire_db_name_create(r, dconf->cookie_db_dir),
- APR_DBM_RWCREATE,
- APR_OS_DEFAULT,
- r->pool);
- if (retval != APR_SUCCESS) {
- ERR2(r, "could not open dbm (type %s) auth file: %s",
- "default",
- chxj_cookie_expire_db_name_create(r,dconf->cookie_db_dir));
- chxj_cookie_expire_db_unlock(r, file);
+ dconf = chxj_get_module_config(r->per_dir_config, &chxj_module);
+ if (!dconf) {
+ DBG(r, "dconf is NULL");
return;
}
- /*
- * create key
- */
-
- dbmkey.dptr = cookie->cookie_id;
- dbmkey.dsize = strlen(cookie->cookie_id);
-
- /*
- * create val
- */
-
- store_string = apr_psprintf(r->pool, "%d", (int)time(NULL));
- dbmval.dptr = store_string;
- dbmval.dsize = strlen(store_string);
- /*
- * store to db
- */
- retval = apr_dbm_store(f, dbmkey, dbmval);
- if (retval != APR_SUCCESS) {
- ERR1(r, "Cannot store Cookie data to DBM file `%s'",
- chxj_cookie_db_name_create(r, dconf->cookie_db_dir));
+#if defined(USE_MYSQL_COOKIE)
+ if (IS_COOKIE_STORE_MYSQL(dconf->cookie_store_type)) {
+ if (! chxj_save_cookie_expire_mysql(r, dconf, cookie->cookie_id)) {
+ ERR(r, "failed: chxj_save_cookie_expire_mysql() cookie_id:[%s]", cookie->cookie_id);
+ DBG(r, "end chxj_save_cookie_expire()");
+ return;
+ }
+ done_proc = 1;
+ }
+#endif
+#if defined(USE_MEMCACHE_COOKIE)
+ if (IS_COOKIE_STORE_MEMCACHE(dconf->cookie_store_type)) {
+ if (! chxj_save_cookie_expire_memcache(r, dconf, cookie->cookie_id)) {
+ ERR(r, "failed: chxj_save_cookie_expire_memcache() cookie_id:[%s]", cookie->cookie_id);
+ DBG(r, "end chxj_save_cookie_expire()");
+ return;
+ }
+ done_proc = 1;
+ }
+#endif
+ if (!done_proc || IS_COOKIE_STORE_DBM(dconf->cookie_store_type)) {
+ if (! chxj_save_cookie_expire_dbm(r, dconf, cookie->cookie_id)) {
+ ERR(r, "failed: chxj_save_cookie_expire_dbm() cookie_id:[%s]", cookie->cookie_id);
+ DBG(r, "end chxj_save_cookie_expire()");
+ return;
+ }
}
-
- apr_dbm_close(f);
- chxj_cookie_expire_db_unlock(r, file);
-
DBG(r, "end chxj_save_cookie_expire()");
}
-char*
-chxj_cookie_expire_db_name_create(request_rec* r, const char* dir)
+void
+chxj_delete_cookie_expire(request_rec *r, char *cookie_id)
{
- char* dst;
-
- if (!dir) {
- dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
- }
- else {
- dst = apr_pstrdup(r->pool, dir);
- }
-
- if (dst[strlen(dst)-1] != '/') {
- dst = apr_pstrcat(r->pool, dst, "/", COOKIE_EXPIRE_DB_NAME, NULL);
- }
- else {
- dst = apr_pstrcat(r->pool, dst, COOKIE_EXPIRE_DB_NAME, NULL);
- }
-
- return dst;
-}
+ int done_proc = 0;
+ mod_chxj_config *dconf;
+ DBG(r, "start chxj_delete_cookie_expire()");
-char*
-chxj_cookie_expire_db_lock_name_create(request_rec* r, const char* dir)
-{
- char* dst;
+ dconf = chxj_get_module_config(r->per_dir_config, &chxj_module);
- if (!dir) {
- dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
- }
- else {
- dst = apr_pstrdup(r->pool, dir);
- }
- if (dst[strlen(dst)-1] != '/') {
- dst = apr_pstrcat(r->pool, dst, "/", COOKIE_EXPIRE_DB_LOCK_NAME, NULL);
- }
- else {
- dst = apr_pstrcat(r->pool, dst, COOKIE_EXPIRE_DB_LOCK_NAME, NULL);
+#if defined(USE_MYSQL_COOKIE)
+ if (IS_COOKIE_STORE_MYSQL(dconf->cookie_store_type)) {
+ if (! chxj_delete_cookie_expire_mysql(r, dconf, cookie_id)) {
+ ERR(r, "failed: chxj_delete_cookie_expire_mysql() cookie_id:[%s]", cookie_id);
+ return;
+ }
+ done_proc = 1;
}
-
- return dst;
-}
-
-
-apr_file_t*
-chxj_cookie_expire_db_lock(request_rec* r)
-{
- apr_file_t* file;
- apr_status_t rv;
- mod_chxj_config* dconf;
-
- dconf = (mod_chxj_config*)ap_get_module_config(r->per_dir_config, &chxj_module);
-
- rv = apr_file_open(&file,
- chxj_cookie_expire_db_lock_name_create(r, dconf->cookie_db_dir),
- APR_CREATE|APR_WRITE,
- APR_OS_DEFAULT,
- r->pool);
- if (rv != APR_SUCCESS) {
- ERR(r, "cookie lock file open failed.");
- return NULL;
+#endif
+#if defined(USE_MEMCACHE_COOKIE)
+ if (IS_COOKIE_STORE_MEMCACHE(dconf->cookie_store_type)) {
+ if (!chxj_delete_cookie_expire_memcache(r, dconf, cookie_id)) {
+ ERR(r, "failed: chxj_delete_cookie_expire_memcache() cookie_id:[%s]", cookie_id);
+ return;
+ }
+ done_proc = 1;
}
-
- rv = apr_file_lock(file,APR_FLOCK_EXCLUSIVE);
- if (rv != APR_SUCCESS) {
- ERR(r, "cookie lock file open failed.");
- apr_file_close(file);
- return NULL;
+#endif
+ if (!done_proc || IS_COOKIE_STORE_DBM(dconf->cookie_store_type)) {
+ if (!chxj_delete_cookie_expire_dbm(r, dconf, cookie_id)) {
+ ERR(r, "failed: chxj_delete_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
+ return;
+ }
}
- return file;
+ DBG(r, "end chxj_delete_cookie_expire()");
}
void
-chxj_cookie_expire_db_unlock(request_rec* r, apr_file_t* file)
+chxj_cookie_expire_gc(request_rec *r)
{
- apr_status_t rv;
+ mod_chxj_config *dconf;
+ int done_proc = 0;
- rv = apr_file_unlock(file);
- if (rv != APR_SUCCESS) {
- ERR(r, "cookie lock file open failed.");
- return;
- }
+ DBG(r, "start chxj_cookie_expire_gc()");
- apr_file_close(file);
+ 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_expire_gc_mysql(r, dconf)) {
+ ERR(r, "%s:%d end chxj_cookie_expire_gc(): failed: chxj_cookie_expire_gc_mysql()", APLOG_MARK);
+ return;
+ }
+ done_proc = 1;
+ }
+#endif
+#if defined(USE_MEMCACHE_COOKIE)
+ if (IS_COOKIE_STORE_MEMCACHE(dconf->cookie_store_type)) {
+ if (! chxj_cookie_expire_gc_memcache(r, dconf)) {
+ ERR(r, "%s:%d end chxj_cookie_expire_gc(): failed: chxj_cookie_expire_gc_memcache()", APLOG_MARK);
+ return;
+ }
+ done_proc = 1;
+ }
+#endif
+ if (!done_proc) {
+ if (! chxj_cookie_expire_gc_dbm(r, dconf)) {
+ ERR(r, "%s:%d end chxj_cookie_expire_gc(): failed: chxj_cookie_expire_gc_dbm()", APLOG_MARK);
+ return;
+ }
+ }
+ DBG(r, "end chxj_cookie_expire_gc()");
}
-void
-chxj_delete_cookie_expire(request_rec* r, char* cookie_id)
+apr_time_t
+chxj_parse_cookie_expires(const char *s)
{
- apr_status_t retval;
- apr_datum_t dbmkey;
- apr_dbm_t* f;
- apr_file_t* file;
- mod_chxj_config* dconf;
+ if (!s) return (apr_time_t)0;
+ return apr_date_parse_rfc(s);
+}
- DBG(r, "start chxj_delete_cookie_expire()");
- file = chxj_cookie_expire_db_lock(r);
- if (! file) {
- ERR(r, "mod_chxj: Can't lock cookie db");
- goto on_error0;
- }
- dconf = ap_get_module_config(r->per_dir_config, &chxj_module);
+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;
- retval = apr_dbm_open_ex(&f,
- "default",
- chxj_cookie_expire_db_name_create(r, dconf->cookie_db_dir),
- APR_DBM_RWCREATE,
- APR_OS_DEFAULT,
- r->pool);
- if (retval != APR_SUCCESS) {
- ERR2(r,
- "could not open dbm (type %s) auth file: %s",
- "default",
- chxj_cookie_expire_db_name_create(r,dconf->cookie_db_dir));
- goto on_error1;
+ 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 NULL;
}
-
- /*
- * create key
- */
- dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
- dbmkey.dsize = strlen(dbmkey.dptr);
- if (apr_dbm_exists(f, dbmkey)) {
- apr_dbm_delete(f, dbmkey);
+ 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 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 NULL;
+ }
+ done_proc = 1;
+ ret = apr_palloc(r->pool, sizeof(*ret));
+ memset(ret, 0, sizeof(*ret));
+ }
+#endif
+ if (!done_proc) {
+ if (!(ret = chxj_cookie_lock_dbm(r, dconf))) {
+ ERR(r, "%s:%d end chxj_cookie_lock(): failed: chxj_cookie_lock_dbm()", APLOG_MARK);
+ DBG(r, "end chxj_cookie_lock() call from %s:%d", filename, line);
+ return NULL;
+ }
}
- apr_dbm_close(f);
- chxj_cookie_expire_db_unlock(r, file);
-
- DBG(r, "end chxj_delete_cookie_expire()");
-
- return;
-
-on_error1:
- chxj_cookie_expire_db_unlock(r, file);
-
-on_error0:
- return;
-
+ DBG(r, "REQ:[%X] end chxj_cookie_lock() call from %s:%d", (unsigned int)(apr_size_t)r, filename, line);
+ return ret;
}
-void
-chxj_cookie_expire_gc(request_rec* r)
+int
+__chxj_cookie_unlock(request_rec *r, cookie_lock_t *lock, const char *filename, int line)
{
- apr_status_t retval;
- apr_datum_t dbmkey;
- apr_datum_t dbmval;
- apr_dbm_t* f;
- apr_file_t* file;
- mod_chxj_config* dconf;
- time_t now_time;
+ mod_chxj_config *dconf;
+ int done_proc = 0;
+ apr_status_t rv;
+ int rtn = 1;
- DBG(r, "start chxj_cookie_expire_gc()");
+ DBG(r, "start chxj_cookie_unlock() call from %s:%d", filename, line);
- file = chxj_cookie_expire_db_lock(r);
- if (! file) {
- ERR(r, "mod_chxj: Can't lock cookie db");
- goto on_error0;
- }
- dconf = ap_get_module_config(r->per_dir_config, &chxj_module);
-
- retval = apr_dbm_open_ex(&f,
- "default",
- chxj_cookie_expire_db_name_create(r, dconf->cookie_db_dir),
- APR_DBM_RWCREATE,
- APR_OS_DEFAULT,
- r->pool);
- if (retval != APR_SUCCESS) {
- ERR2(r,
- "could not open dbm (type %s) auth file: %s",
- "default",
- chxj_cookie_expire_db_name_create(r,dconf->cookie_db_dir));
- goto on_error1;
+ 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_unlock_mysql(r, dconf)) {
+ ERR(r, "failed: chxj_cookie_unlock_mysql()");
+ rtn = 0;
+ goto end_chxj_cookie_unlock;
+ }
+ done_proc = 1;
+ }
+#endif
+#if defined(USE_MEMCACHE_COOKIE)
+ if (IS_COOKIE_STORE_MEMCACHE(dconf->cookie_store_type)) {
+ if (! chxj_cookie_unlock_memcache(r, dconf)) {
+ ERR(r, "failed: chxj_cookie_unlock_memcache()");
+ rtn = 0;
+ goto end_chxj_cookie_unlock;
+ }
+ done_proc = 1;
+ }
+#endif
+ if (!done_proc) {
+ if (! chxj_cookie_unlock_dbm(r, lock, dconf)) {
+ ERR(r, "failed: chxj_cookie_unlock_dbm()");
+ rtn = 0;
+ goto end_chxj_cookie_unlock;
+ }
}
-
- /*
- * create key
- */
- memset(&dbmkey, 0, sizeof(apr_datum_t));
-
- now_time = time(NULL);
-
- retval = apr_dbm_firstkey(f, &dbmkey);
- if (retval == APR_SUCCESS) {
- DBG2(r, "firstkey=[%.*s]", dbmkey.dsize, dbmkey.dptr);
- do {
- char* tmp;
- char* old_cookie_id;
- int val_time;
- int cmp_time;
-
- retval = apr_dbm_fetch(f, dbmkey, &dbmval);
- if (retval != APR_SUCCESS) {
- break;
- }
- tmp = apr_palloc(r->pool, dbmval.dsize+1);
- memset(tmp, 0, dbmval.dsize+1);
- memcpy(tmp, dbmval.dptr, dbmval.dsize);
-
-
- val_time = atoi(tmp);
-
- if (dconf->cookie_timeout == 0)
- cmp_time = now_time - DEFAULT_COOKIE_TIMEOUT;
- else
- cmp_time = now_time - dconf->cookie_timeout;
-
- DBG2(r, "key=[%.*s]", dbmkey.dsize, dbmkey.dptr);
- if (cmp_time >= val_time) {
- apr_dbm_delete(f, dbmkey);
-
- old_cookie_id = apr_palloc(r->pool, dbmkey.dsize+1);
- memset(old_cookie_id, 0, dbmkey.dsize+1);
- memcpy(old_cookie_id, dbmkey.dptr, dbmkey.dsize);
-
- chxj_delete_cookie(r,old_cookie_id);
- DBG1(r, "detect timeout cookie [%s]", old_cookie_id);
- }
-
- retval = apr_dbm_nextkey(f, &dbmkey);
- } while(retval == APR_SUCCESS && dbmkey.dptr != NULL);
+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() call from %s:%d", filename, line);
- apr_dbm_close(f);
- chxj_cookie_expire_db_unlock(r, file);
-
- DBG(r, "end chxj_cookie_expire_gc()");
-
- return;
-
-on_error1:
- chxj_cookie_expire_db_unlock(r, file);
-
-on_error0:
- return;
-
+ return rtn;
}
/*
* vim:ts=2 et