2 * Copyright (C) 2005-2008 Atsushi Konno All rights reserved.
3 * Copyright (C) 2005 QSDN,Inc. All rights reserved.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
20 #include "chxj_cookie.h"
21 #include "chxj_url_encode.h"
22 #include "chxj_apply_convrule.h"
24 #include "ap_release.h"
30 #include "apr_base64.h"
33 #ifdef USE_MYSQL_COOKIE
34 #include "chxj_mysql.h"
37 static char *s_get_hostname_from_url(request_rec *r, char *value);
38 static char *s_cut_until_end_hostname(request_rec *, char *value);
41 alloc_cookie_id(request_rec *r)
45 unsigned char *md5_value;
50 uuid_string = apr_palloc(r->pool, APR_UUID_FORMATTED_LENGTH + 1);
51 memset(uuid_string, 0, APR_UUID_FORMATTED_LENGTH + 1);
52 apr_uuid_format(uuid_string, &uuid);;
54 md5_value = (unsigned char*)apr_palloc(r->pool, APR_MD5_DIGESTSIZE + 1);
55 memset(md5_value, 0, APR_MD5_DIGESTSIZE + 1);
57 retval = apr_md5(md5_value,
58 (const char*)uuid_string,
59 APR_UUID_FORMATTED_LENGTH);
60 if (retval != APR_SUCCESS) {
61 ERR(r, "md5 failed.");
65 cookie_id = apr_palloc(r->pool, apr_base64_encode_len(APR_MD5_DIGESTSIZE)+1);
66 memset(cookie_id, 0, APR_MD5_DIGESTSIZE+1);
67 apr_base64_encode(cookie_id, (char*)md5_value, APR_MD5_DIGESTSIZE);
69 DBG(r, "cookie_id=[%s]", cookie_id);
71 cookie_id = chxj_url_encode(r,cookie_id);
73 DBG(r, "cookie_id=[%s]", cookie_id);
81 chxj_save_cookie(request_rec *r)
84 apr_array_header_t *headers;
85 apr_table_entry_t *hentryp;
88 mod_chxj_config *dconf;
89 chxjconvrule_entry *entryp;
90 #if !defined(USE_MYSQL_COOKIE) && !defined(USE_MEMCACHE_COOKIE)
98 apr_table_t *new_cookie_table;
101 cookie_t *old_cookie;
103 apr_uri_t parsed_uri;
107 DBG(r, "start chxj_save_cookie()");
109 cookie = (cookie_t*)apr_palloc(r->pool, sizeof(cookie_t));
110 cookie->cookie_id = NULL;
115 dconf = ap_get_module_config(r->per_dir_config, &chxj_module);
116 entryp = chxj_apply_convrule(r, dconf->convrules);
118 DBG(r, "end chxj_save_cookie() no pattern");
121 if (! (entryp->action & CONVRULE_COOKIE_ON_BIT)) {
122 DBG(r, "end chxj_save_cookie() CookieOff");
128 headers = (apr_array_header_t*)apr_table_elts(r->headers_out);
129 hentryp = (apr_table_entry_t*)headers->elts;
132 new_cookie_table = apr_table_make(r->pool, 0);
134 for (ii=0; ii<headers->nelts; ii++) {
135 if (strcasecmp(hentryp[ii].key, "Set-Cookie") == 0) {
136 DBG(r, "=====================================");
137 DBG(r, "cookie=[%s:%s]", hentryp[ii].key, hentryp[ii].val);
144 buff = apr_pstrdup(r->pool, hentryp[ii].val);
145 val = strchr(buff, '=');
149 apr_table_add(new_cookie_table, key, val);
150 if (strcasecmp(REFERER_COOKIE_KEY, key) == 0) has_refer++;
155 DBG(r, "=====================================");
158 apr_table_unset(r->headers_out, "Set-Cookie");
161 apr_uri_parse(r->pool,r->uri, &parsed_uri);
162 refer_string = apr_psprintf(r->pool,
164 #if AP_SERVER_MAJORVERSION_NUMBER == 2 && AP_SERVER_MINORVERSION_NUMBER == 2
165 ap_run_http_scheme(r),
167 ap_run_http_method(r),
170 apr_uri_unparse(r->pool,
172 APR_URI_UNP_OMITSITEPART));
173 if (r->args && strlen(r->args)) {
174 refer_string = apr_pstrcat(r->pool, refer_string, "?", r->args, NULL);
176 apr_table_setn(new_cookie_table, REFERER_COOKIE_KEY, refer_string);
177 DBG(r, "ADD REFER[%s]", refer_string);
183 * check input parameters
185 old_cookie_id = (char*)apr_table_get(r->headers_in, "CHXJ_COOKIE_ID");
187 old_cookie = chxj_load_cookie(r, old_cookie_id);
188 if (old_cookie && old_cookie->cookie_headers) {
189 hentryp = (apr_table_entry_t*)old_cookie->cookie_headers->elts;
190 for (ii=0; ii<old_cookie->cookie_headers->nelts; ii++) {
191 if (hentryp && apr_table_get(new_cookie_table, hentryp[ii].key) == NULL) {
192 apr_table_add(new_cookie_table, hentryp[ii].key, hentryp[ii].val);
196 chxj_delete_cookie(r, old_cookie_id);
197 chxj_delete_cookie_expire(r, old_cookie_id);
203 DBG(r, "end chxj_save_cookie()");
210 cookie->cookie_headers = (apr_array_header_t*)apr_table_elts(new_cookie_table);
211 store_string = apr_palloc(r->pool, 1);
213 hentryp = (apr_table_entry_t*)cookie->cookie_headers->elts;
215 for (ii=0; ii<cookie->cookie_headers->nelts; ii++) {
216 if (ii) store_string = apr_pstrcat(r->pool,
221 store_string = apr_pstrcat(r->pool,
229 cookie->cookie_id = alloc_cookie_id(r);
231 #if defined(USE_MYSQL_COOKIE)
233 if (! chxj_open_mysql_handle(r, dconf)) {
234 ERR(r, "Cannot open mysql connection");
238 if (!chxj_mysql_exist_cookie_table(r, dconf)) {
239 DBG(r, "not found cookie table:[%s]", dconf->mysql.tablename);
240 if (!chxj_mysql_create_cookie_table(r, dconf)) {
241 ERR(r, "cannot create cookie table:[%s]", dconf->mysql.tablename);
245 if (! chxj_mysql_insert_or_update_cookie(r, dconf, cookie->cookie_id, store_string)) {
246 ERR(r, "cannot create cookie table:[%s]", dconf->mysql.tablename);
250 /* *NEED NOT* close database. */
251 /* chxj_close_mysql_handle(); */
253 #elif defined(USE_MEMCACHE_COOKIE)
256 file = chxj_cookie_db_lock(r);
258 ERR(r, "mod_chxj: Can't lock cookie db");
259 DBG(r, "end chxj_save_cookie()");
263 retval = apr_dbm_open_ex(&f,
265 chxj_cookie_db_name_create(r, dconf->cookie_db_dir),
269 if (retval != APR_SUCCESS) {
270 DBG(r, "end chxj_save_cookie()");
271 ERR(r, "could not open dbm (type %s) auth file: %s",
273 chxj_cookie_db_name_create(r,dconf->cookie_db_dir));
274 chxj_cookie_db_unlock(r, file);
283 dbmkey.dptr = cookie->cookie_id;
284 dbmkey.dsize = strlen(cookie->cookie_id);
285 dbmval.dptr = store_string;
286 dbmval.dsize = strlen(store_string);
291 retval = apr_dbm_store(f, dbmkey, dbmval);
292 if (retval != APR_SUCCESS) {
293 ERR(r, "Cannot store Cookie data to DBM file `%s'",
294 chxj_cookie_db_name_create(r, dconf->cookie_db_dir));
300 chxj_save_cookie_expire(r, cookie);
305 #if !defined(USE_MYSQL_COOKIE) && !defined(USE_MEMCACHE_COOKIE)
307 chxj_cookie_db_unlock(r, file);
310 DBG(r, "end chxj_save_cookie()");
318 chxj_update_cookie(request_rec *r, cookie_t *old_cookie)
321 apr_array_header_t *headers;
322 apr_table_entry_t *hentryp;
324 mod_chxj_config *dconf;
325 chxjconvrule_entry *entryp;
326 #if !defined(USE_MYSQL_COOKIE) && !defined(USE_MEMCACHE_COOKIE)
336 DBG(r, "start chxj_update_cookie()");
337 if (!old_cookie || ! old_cookie->cookie_headers || ! old_cookie->cookie_id) {
338 DBG(r, "end chxj_update_cookie() (old_cookie is null)");
342 cookie = (cookie_t*)apr_palloc(r->pool, sizeof(cookie_t));
343 cookie->cookie_id = NULL;
346 dconf = ap_get_module_config(r->per_dir_config, &chxj_module);
347 entryp = chxj_apply_convrule(r, dconf->convrules);
349 DBG(r, "end chxj_update_cookie() no pattern");
352 if (! (entryp->action & CONVRULE_COOKIE_ON_BIT)) {
353 DBG(r, "end chxj_update_cookie() CookieOff");
358 headers = (apr_array_header_t*)apr_table_elts(r->headers_out);
359 hentryp = (apr_table_entry_t*)headers->elts;
362 chxj_delete_cookie(r, old_cookie->cookie_id);
363 chxj_delete_cookie_expire(r, old_cookie->cookie_id);
365 cookie->cookie_id = alloc_cookie_id(r);
367 cookie->cookie_headers = old_cookie->cookie_headers;
368 store_string = apr_palloc(r->pool, 1);
370 hentryp = (apr_table_entry_t*)cookie->cookie_headers->elts;
372 for (ii=0; ii<cookie->cookie_headers->nelts; ii++) {
373 if (ii) store_string = apr_pstrcat(r->pool,
378 DBG(r, "OLD COOKIE VALUE=[%s][%s]", hentryp[ii].key, hentryp[ii].val);
379 store_string = apr_pstrcat(r->pool,
387 #if defined(USE_MYSQL_COOKIE)
388 if (! chxj_open_mysql_handle(r, dconf)) {
389 ERR(r, "Cannot open mysql connection");
393 if (!chxj_mysql_exist_cookie_table(r, dconf)) {
394 DBG(r, "not found cookie table:[%s]", dconf->mysql.tablename);
395 if (!chxj_mysql_create_cookie_table(r, dconf)) {
396 ERR(r, "cannot create cookie table:[%s]", dconf->mysql.tablename);
400 if (! chxj_mysql_insert_or_update_cookie(r, dconf, cookie->cookie_id, store_string)) {
401 ERR(r, "cannot create cookie table:[%s]", dconf->mysql.tablename);
405 /* *NEED NOT* close database. */
406 /* chxj_close_mysql_handle(); */
407 #elif defined(USE_MEMCACHE_COOKIE)
409 file = chxj_cookie_db_lock(r);
411 ERR(r, "mod_chxj: Can't lock cookie db");
415 retval = apr_dbm_open_ex(&f,
417 chxj_cookie_db_name_create(r, dconf->cookie_db_dir),
421 if (retval != APR_SUCCESS) {
422 ERR(r, "could not open dbm (type %s) auth file: %s",
424 chxj_cookie_db_name_create(r,dconf->cookie_db_dir));
425 chxj_cookie_db_unlock(r, file);
434 dbmkey.dptr = cookie->cookie_id;
435 dbmkey.dsize = strlen(cookie->cookie_id);
440 dbmval.dptr = store_string;
441 dbmval.dsize = strlen(store_string);
446 retval = apr_dbm_store(f, dbmkey, dbmval);
447 if (retval != APR_SUCCESS) {
448 ERR(r, "Cannot store Cookie data to DBM file `%s'",
449 chxj_cookie_db_name_create(r, dconf->cookie_db_dir));
454 chxj_save_cookie_expire(r, cookie);
456 apr_table_setn(r->headers_in, "CHXJ_COOKIE_ID", cookie->cookie_id);
460 #if !defined(USE_MYSQL_COOKIE) && !defined(USE_MEMCACHE_COOKIE)
462 chxj_cookie_db_unlock(r, file);
465 DBG(r, "end chxj_update_cookie()");
472 * @return loaded data.
475 chxj_load_cookie(request_rec *r, char *cookie_id)
477 mod_chxj_config *dconf;
478 chxjconvrule_entry *entryp;
479 #if !defined(USE_MYSQL_COOKIE) && !defined(USE_MEMCACHE_COOKIE)
487 apr_table_t *load_cookie_table;
488 char *load_string = NULL;
495 DBG(r, "========================================================");
496 DBG(r, "========================================================");
497 DBG(r, "========================================================");
498 DBG(r, "========================================================");
499 DBG(r, "start chxj_load_cookie() cookie_id=[%s]", cookie_id);
500 chxj_cookie_expire_gc(r);
502 cookie = (cookie_t*)apr_palloc(r->pool, sizeof(cookie_t));
503 cookie->cookie_headers = NULL;
504 cookie->cookie_id = apr_pstrdup(r->pool, cookie_id);
506 dconf = ap_get_module_config(r->per_dir_config, &chxj_module);
507 entryp = chxj_apply_convrule(r, dconf->convrules);
509 DBG(r, "end chxj_load_cookie() no pattern");
512 if (! (entryp->action & CONVRULE_COOKIE_ON_BIT)) {
513 DBG(r, "end chxj_load_cookie() CookieOff");
516 load_cookie_table = apr_table_make(r->pool, 0);
518 #if defined(USE_MYSQL_COOKIE)
520 if (! chxj_open_mysql_handle(r, dconf)) {
521 ERR(r, "Cannot open mysql connection");
525 if (!chxj_mysql_exist_cookie_table(r, dconf)) {
526 DBG(r, "not found cookie table:[%s]", dconf->mysql.tablename);
527 if (!chxj_mysql_create_cookie_table(r, dconf)) {
528 ERR(r, "cannot create cookie table:[%s]", dconf->mysql.tablename);
532 if (!(load_string = chxj_mysql_load_cookie(r, dconf, cookie->cookie_id))) {
533 ERR(r, "not found cookie. cookie_id:[%s]", cookie->cookie_id);
537 /* *NEED NOT* close database. */
538 /* chxj_close_mysql_handle(); */
540 #elif defined(USE_MEMCACHE_COOKIE)
542 file = chxj_cookie_db_lock(r);
544 ERR(r, "mod_chxj: Can't lock cookie db");
548 retval = apr_dbm_open_ex(&f,
550 chxj_cookie_db_name_create(r, dconf->cookie_db_dir),
554 if (retval != APR_SUCCESS) {
556 "could not open dbm (type %s) auth file: %s",
558 chxj_cookie_db_name_create(r, dconf->cookie_db_dir));
565 dbmkey.dptr = apr_pstrdup(r->pool, cookie->cookie_id);
566 dbmkey.dsize = strlen(dbmkey.dptr);
568 if (apr_dbm_exists(f, dbmkey)) {
569 retval = apr_dbm_fetch(f, dbmkey, &dbmval);
570 if (retval != APR_SUCCESS) {
572 "could not fetch dbm (type %s) auth file: %s", "default",
573 chxj_cookie_db_name_create(r, dconf->cookie_db_dir));
576 load_string = apr_palloc(r->pool, dbmval.dsize+1);
578 memset(load_string, 0, dbmval.dsize+1);
579 memcpy(load_string, dbmval.dptr, dbmval.dsize);
583 chxj_cookie_db_unlock(r, file);
588 DBG(r, "load_string=[%s]", load_string);
589 header_cookie = apr_palloc(r->pool, 1);
591 header_cookie[0] = 0;
594 pair = apr_strtok(load_string, "\n", &pstat);
598 DBG(r, "Cookie:[%s]", pair);
601 tmp_pair = apr_pstrdup(r->pool, pair);
602 val = strchr(tmp_pair, '=');
606 apr_table_add(load_cookie_table, key, val);
608 tmp_sem = strchr(pair, ';');
612 if (strlen(header_cookie))
613 header_cookie = apr_pstrcat(r->pool, header_cookie, ";", NULL);
615 header_cookie = apr_pstrcat(r->pool, header_cookie, pair, NULL);
617 if (strlen(header_cookie))
618 apr_table_add(r->headers_in, "Cookie", header_cookie);
620 cookie->cookie_headers = (apr_array_header_t*)apr_table_elts(load_cookie_table);
622 if (apr_table_get(r->headers_in, "referer") == NULL) {
623 apr_table_setn(r->headers_in,
625 apr_table_get(load_cookie_table, REFERER_COOKIE_KEY));
629 * save cookie_id to request header.
631 apr_table_setn(r->headers_in, "CHXJ_COOKIE_ID", cookie->cookie_id);
634 DBG(r, "end chxj_load_cookie()");
635 DBG(r, "========================================================");
636 DBG(r, "========================================================");
637 DBG(r, "========================================================");
638 DBG(r, "========================================================");
643 #if !defined(USE_MYSQL_COOKIE) && !defined(USE_MEMCACHE_COOKIE)
648 chxj_cookie_db_unlock(r, file);
653 DBG(r, "end chxj_load_cookie()");
654 DBG(r, "========================================================");
655 DBG(r, "========================================================");
656 DBG(r, "========================================================");
657 DBG(r, "========================================================");
663 chxj_add_cookie_parameter(request_rec *r, char *value, cookie_t *cookie)
668 DBG(r, "start chxj_add_cookie_parameter() cookie_id=[%s]", (cookie) ? cookie->cookie_id : NULL);
670 dst = apr_pstrdup(r->pool, value);
675 if (!cookie->cookie_id)
678 if (chxj_cookie_check_host(r, value) != 0) {
679 DBG(r, "end chxj_add_cookie_parameter()(check host)");
683 qs = strchr(dst, '?');
685 dst = apr_psprintf(r->pool, "%s&%s=%s", dst, CHXJ_COOKIE_PARAM, cookie->cookie_id);
688 dst = apr_psprintf(r->pool, "%s?%s=%s", dst, CHXJ_COOKIE_PARAM, cookie->cookie_id);
691 DBG(r, "end chxj_add_cookie_parameter() dst=[%s]", dst);
696 DBG(r, "end chxj_add_cookie_parameter() (on_error)");
702 chxj_cookie_check_host(request_rec *r, char *value)
706 DBG(r, "hostname=[%s]", r->hostname);
708 hostnm = s_get_hostname_from_url(r, value);
710 if (strcasecmp(hostnm, r->hostname) == 0)
720 s_get_hostname_from_url(request_rec *r, char *value)
725 if (strncasecmp(value, "http://", 7) == 0 )
726 return s_cut_until_end_hostname(r, &value[7]);
728 if (strncasecmp(value, "https://", 8) == 0)
729 return s_cut_until_end_hostname(r, &value[8]);
736 s_cut_until_end_hostname(request_rec *r, char *value)
741 hostnm = sp = apr_pstrdup(r->pool, value);
743 if (*sp == '/'|| *sp == '?') {
752 #if !defined(USE_MYSQL_COOKIE) && !defined(USE_MEMCACHE_COOKIE)
754 chxj_cookie_db_lock(request_rec *r)
758 mod_chxj_config *dconf;
760 dconf = (mod_chxj_config *)ap_get_module_config(r->per_dir_config, &chxj_module);
762 rv = apr_file_open(&file,
763 chxj_cookie_db_lock_name_create(r, dconf->cookie_db_dir),
764 APR_CREATE|APR_WRITE,
767 if (rv != APR_SUCCESS) {
768 ERR(r, "cookie lock file open failed.");
772 rv = apr_file_lock(file,APR_FLOCK_EXCLUSIVE);
773 if (rv != APR_SUCCESS) {
774 ERR(r, "cookie lock file open failed.");
775 apr_file_close(file);
784 chxj_cookie_db_unlock(request_rec *r, apr_file_t *file)
788 rv = apr_file_unlock(file);
789 if (rv != APR_SUCCESS) {
790 ERR(r, "cookie lock file open failed.");
794 apr_file_close(file);
801 chxj_delete_cookie(request_rec *r, char *cookie_id)
803 #if !defined(USE_MYSQL_COOKIE) && !defined(USE_MEMCACHE_COOKIE)
809 mod_chxj_config *dconf;
812 DBG(r, "start chxj_delete_cookie()");
814 dconf = ap_get_module_config(r->per_dir_config, &chxj_module);
816 #if defined(USE_MYSQL_COOKIE)
817 if (!chxj_mysql_delete_cookie(r, dconf, cookie_id)) {
818 ERR(r, "failed: chxj_mysql_delete_cookie() cookie_id:[%s]", cookie_id);
822 #elif defined(USE_MEMCACHE_COOKIE)
824 file = chxj_cookie_db_lock(r);
826 ERR(r, "mod_chxj: Can't lock cookie db");
830 retval = apr_dbm_open_ex(&f,
832 chxj_cookie_db_name_create(r, dconf->cookie_db_dir),
836 if (retval != APR_SUCCESS) {
838 "could not open dbm (type %s) auth file: %s",
840 chxj_cookie_db_name_create(r,dconf->cookie_db_dir));
847 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
848 dbmkey.dsize = strlen(dbmkey.dptr);
849 if (apr_dbm_exists(f, dbmkey)) {
850 apr_dbm_delete(f, dbmkey);
853 chxj_cookie_db_unlock(r, file);
856 DBG(r, "end chxj_delete_cookie()");
860 #if !defined (USE_MYSQL_COOKIE) && !defined(USE_MEMCACHE_COOKIE)
862 chxj_cookie_db_unlock(r, file);
871 #if !defined(USE_MYSQL_COOKIE) && !defined(USE_MEMCACHE_COOKIE)
873 chxj_cookie_db_name_create(request_rec *r, const char *dir)
878 dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
881 dst = apr_pstrdup(r->pool, dir);
884 if (dst[strlen(dst)-1] != '/') {
885 dst = apr_pstrcat(r->pool, dst, "/", COOKIE_DB_NAME, NULL);
888 dst = apr_pstrcat(r->pool, dst, COOKIE_DB_NAME, NULL);
895 chxj_cookie_db_lock_name_create(request_rec *r, const char *dir)
898 DBG(r, "start chxj_cookie_db_lock_name_create()");
902 dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
906 dst = apr_pstrdup(r->pool, dir);
909 DBG(r, "dst[strlen(dst)-1]=[%c]", dst[strlen(dst)-1]);
910 if (dst[strlen(dst)-1] != '/') {
911 dst = apr_pstrcat(r->pool, dst, "/", COOKIE_DB_LOCK_NAME, NULL);
914 dst = apr_pstrcat(r->pool, dst, COOKIE_DB_LOCK_NAME, NULL);
916 DBG(r, "end chxj_cookie_db_lock_name_create()");
924 chxj_save_cookie_expire(request_rec *r, cookie_t *cookie)
926 mod_chxj_config *dconf;
927 #if !defined(USE_MYSQL_COOKIE) && !defined(USE_MEMCACHE_COOKIE)
936 DBG(r, "start chxj_save_cookie_expire()");
939 DBG(r, "cookie is NULL");
942 if (!cookie->cookie_id) {
943 DBG(r, "cookie->cookie_id is NULL");
947 dconf = ap_get_module_config(r->per_dir_config, &chxj_module);
949 DBG(r, "dconf is NULL");
953 #if defined(USE_MYSQL_COOKIE)
954 if (! chxj_open_mysql_handle(r, dconf)) {
955 ERR(r, "Cannot open mysql connection");
956 DBG(r, "end chxj_save_cookie_expire()");
960 if (!chxj_mysql_exist_cookie_table_expire(r, dconf)) {
961 DBG(r, "not found cookie table:[%s_expire]", dconf->mysql.tablename);
962 if (!chxj_mysql_create_cookie_expire_table(r, dconf)) {
963 ERR(r, "cannot create cookie table:[%s_expire]", dconf->mysql.tablename);
964 DBG(r, "end chxj_save_cookie_expire()");
968 if (! chxj_mysql_insert_or_update_cookie_expire(r, dconf, cookie->cookie_id)) {
969 ERR(r, "cannot create cookie table:[%s_expire]", dconf->mysql.tablename);
970 DBG(r, "end chxj_save_cookie_expire()");
974 /* *NEED NOT* close database. */
975 /* chxj_close_mysql_handle(); */
976 #elif defined(USE_MEMCACHE_COOKIE)
978 file = chxj_cookie_expire_db_lock(r);
980 ERR(r, "mod_chxj: Can't lock cookie db");
986 retval = apr_dbm_open_ex(&f,
988 chxj_cookie_expire_db_name_create(r, dconf->cookie_db_dir),
992 if (retval != APR_SUCCESS) {
993 ERR(r, "could not open dbm (type %s) auth file: %s",
995 chxj_cookie_expire_db_name_create(r,dconf->cookie_db_dir));
996 chxj_cookie_expire_db_unlock(r, file);
1003 dbmkey.dptr = cookie->cookie_id;
1004 dbmkey.dsize = strlen(cookie->cookie_id);
1010 store_string = apr_psprintf(r->pool, "%d", (int)time(NULL));
1011 dbmval.dptr = store_string;
1012 dbmval.dsize = strlen(store_string);
1017 retval = apr_dbm_store(f, dbmkey, dbmval);
1018 if (retval != APR_SUCCESS) {
1019 ERR(r, "Cannot store Cookie data to DBM file `%s'",
1020 chxj_cookie_db_name_create(r, dconf->cookie_db_dir));
1025 chxj_cookie_expire_db_unlock(r, file);
1028 DBG(r, "end chxj_save_cookie_expire()");
1032 #if !defined(USE_MYSQL_COOKIE) && !defined(USE_MEMCACHE_COOKIE)
1034 chxj_cookie_expire_db_name_create(request_rec *r, const char *dir)
1039 dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
1042 dst = apr_pstrdup(r->pool, dir);
1045 if (dst[strlen(dst)-1] != '/') {
1046 dst = apr_pstrcat(r->pool, dst, "/", COOKIE_EXPIRE_DB_NAME, NULL);
1049 dst = apr_pstrcat(r->pool, dst, COOKIE_EXPIRE_DB_NAME, NULL);
1057 chxj_cookie_expire_db_lock_name_create(request_rec *r, const char *dir)
1062 dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
1065 dst = apr_pstrdup(r->pool, dir);
1067 if (dst[strlen(dst)-1] != '/') {
1068 dst = apr_pstrcat(r->pool, dst, "/", COOKIE_EXPIRE_DB_LOCK_NAME, NULL);
1071 dst = apr_pstrcat(r->pool, dst, COOKIE_EXPIRE_DB_LOCK_NAME, NULL);
1079 chxj_cookie_expire_db_lock(request_rec *r)
1083 mod_chxj_config *dconf;
1085 dconf = (mod_chxj_config *)ap_get_module_config(r->per_dir_config, &chxj_module);
1087 rv = apr_file_open(&file,
1088 chxj_cookie_expire_db_lock_name_create(r, dconf->cookie_db_dir),
1089 APR_CREATE|APR_WRITE,
1092 if (rv != APR_SUCCESS) {
1093 ERR(r, "cookie lock file open failed.");
1097 rv = apr_file_lock(file,APR_FLOCK_EXCLUSIVE);
1098 if (rv != APR_SUCCESS) {
1099 ERR(r, "cookie lock file open failed.");
1100 apr_file_close(file);
1109 chxj_cookie_expire_db_unlock(request_rec *r, apr_file_t *file)
1113 rv = apr_file_unlock(file);
1114 if (rv != APR_SUCCESS) {
1115 ERR(r, "cookie lock file open failed.");
1119 apr_file_close(file);
1127 chxj_delete_cookie_expire(request_rec *r, char *cookie_id)
1129 #if !defined(USE_MYSQL_COOKIE) && !defined(USE_MEMCACHE_COOKIE)
1130 apr_status_t retval;
1135 mod_chxj_config *dconf;
1137 DBG(r, "start chxj_delete_cookie_expire()");
1139 dconf = ap_get_module_config(r->per_dir_config, &chxj_module);
1141 #if defined(USE_MYSQL_COOKIE)
1142 if (!chxj_mysql_delete_cookie_expire(r, dconf, cookie_id)) {
1143 ERR(r, "failed: chxj_mysql_delete_cookie() cookie_id:[%s]", cookie_id);
1146 #elif defined(USE_MEMCACHE_COOKIE)
1148 file = chxj_cookie_expire_db_lock(r);
1150 ERR(r, "mod_chxj: Can't lock cookie db");
1154 retval = apr_dbm_open_ex(&f,
1156 chxj_cookie_expire_db_name_create(r, dconf->cookie_db_dir),
1160 if (retval != APR_SUCCESS) {
1162 "could not open dbm (type %s) auth file: %s",
1164 chxj_cookie_expire_db_name_create(r,dconf->cookie_db_dir));
1171 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
1172 dbmkey.dsize = strlen(dbmkey.dptr);
1173 if (apr_dbm_exists(f, dbmkey)) {
1174 apr_dbm_delete(f, dbmkey);
1177 chxj_cookie_expire_db_unlock(r, file);
1180 DBG(r, "end chxj_delete_cookie_expire()");
1184 #if !defined(USE_MYSQL_COOKIE) && !defined(USE_MEMCACHE_COOKIE)
1186 chxj_cookie_expire_db_unlock(r, file);
1196 chxj_cookie_expire_gc(request_rec *r)
1198 #if !defined(USE_MYSQL_COOKIE) && !defined(USE_MEMCACHE_COOKIE)
1199 apr_status_t retval;
1206 mod_chxj_config *dconf;
1208 DBG(r, "start chxj_cookie_expire_gc()");
1209 dconf = ap_get_module_config(r->per_dir_config, &chxj_module);
1211 #if defined(USE_MYSQL_COOKIE)
1212 if (!chxj_mysql_delete_expired_cookie(r, dconf)) {
1213 ERR(r, "failed chxj_mysql_delete_expired_cookie()");
1217 #elif defined(USE_MEMCACHE_COOKIE)
1219 file = chxj_cookie_expire_db_lock(r);
1221 ERR(r, "mod_chxj: Can't lock cookie db");
1225 retval = apr_dbm_open_ex(&f,
1227 chxj_cookie_expire_db_name_create(r, dconf->cookie_db_dir),
1231 if (retval != APR_SUCCESS) {
1233 "could not open dbm (type %s) auth file: %s",
1235 chxj_cookie_expire_db_name_create(r,dconf->cookie_db_dir));
1242 memset(&dbmkey, 0, sizeof(apr_datum_t));
1244 now_time = time(NULL);
1246 retval = apr_dbm_firstkey(f, &dbmkey);
1247 if (retval == APR_SUCCESS) {
1248 DBG(r, "firstkey=[%.*s]", (int)dbmkey.dsize, dbmkey.dptr);
1251 char *old_cookie_id;
1255 retval = apr_dbm_fetch(f, dbmkey, &dbmval);
1256 if (retval != APR_SUCCESS) {
1259 tmp = apr_palloc(r->pool, dbmval.dsize+1);
1260 memset(tmp, 0, dbmval.dsize+1);
1261 memcpy(tmp, dbmval.dptr, dbmval.dsize);
1264 val_time = atoi(tmp);
1266 if (dconf->cookie_timeout == 0)
1267 cmp_time = now_time - DEFAULT_COOKIE_TIMEOUT;
1269 cmp_time = now_time - dconf->cookie_timeout;
1271 DBG(r, "dconf->cookie_timeout=[%d]", (int)dconf->cookie_timeout);
1272 DBG(r, "key=[%.*s] cmp_time=[%d] val_time=[%d]", (int)dbmkey.dsize, dbmkey.dptr, cmp_time, val_time);
1273 if (cmp_time >= val_time) {
1274 apr_dbm_delete(f, dbmkey);
1276 old_cookie_id = apr_palloc(r->pool, dbmkey.dsize+1);
1277 memset(old_cookie_id, 0, dbmkey.dsize+1);
1278 memcpy(old_cookie_id, dbmkey.dptr, dbmkey.dsize);
1280 chxj_delete_cookie(r,old_cookie_id);
1281 DBG(r, "detect timeout cookie [%s]", old_cookie_id);
1284 retval = apr_dbm_nextkey(f, &dbmkey);
1285 } while(retval == APR_SUCCESS && dbmkey.dptr != NULL);
1289 chxj_cookie_expire_db_unlock(r, file);
1292 DBG(r, "end chxj_cookie_expire_gc()");
1296 #if !defined(USE_MYSQL_COOKIE) && !defined(USE_MEMCACHE_COOKIE)
1298 chxj_cookie_expire_db_unlock(r, file);