2 * Copyright (C) 2005-2009 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.
17 #ifdef USE_MYSQL_COOKIE
19 #include "chxj_cookie.h"
20 #include "chxj_url_encode.h"
21 #include "chxj_apply_convrule.h"
23 #include "ap_release.h"
28 #include "apr_base64.h"
38 #define CHXJ_MYSQL_RECONNECT_WAIT_TIME (5000)
39 #define CHXJ_MYSQL_RECONNECT_COUNT (3)
50 static mysql_connection connection = {NULL, "", "", "", 0, 0};
54 _mysql_cleanup(void *UNUSED(notused))
56 chxj_close_mysql_handle();
61 _mysql_cleanup_child(void *UNUSED(notused))
68 chxj_close_mysql_handle()
70 if (connection.handle) {
71 mysql_close(connection.handle);
72 connection.handle = NULL;
77 chxj_open_mysql_handle(request_rec *r, mod_chxj_config *m)
79 static MYSQL mysql_conn;
80 char query[MAX_STRING_LEN];
82 if (connection.handle && connection.reconnect == 0) {
83 if ((!m->mysql.host || (strcasecmp(m->mysql.host, "localhost") == 0)) && connection.host[0] == '\0'
84 && (m->mysql.username && strcmp(m->mysql.username, connection.username) == 0)) {
86 if (m->mysql.database && strcmp(m->mysql.database, connection.database) == 0) {
87 DBG(r, "already connected");
88 DBG(r, "end chxj_open_mysql_handle()");
92 if (mysql_select_db(connection.handle,m->mysql.database) != 0) {
93 ERR(r, "%s:%d MySQL ERROR: %s", APLOG_MARK, mysql_error(connection.handle));
97 strcpy (connection.database, m->mysql.database);
98 DBG(r, "already connected. new database:[%s]", m->mysql.database);
105 chxj_close_mysql_handle();
106 connection.handle = mysql_init(&mysql_conn);
107 if (! connection.handle) {
108 ERR(r, "%s:%d MySQL ERROR: %s", APLOG_MARK, mysql_error(&mysql_conn));
112 if (!m->mysql.host || strcmp(m->mysql.host,"localhost") == 0) {
113 connection.host[0] = '\0';
115 strcpy(connection.host, m->mysql.host);
118 connection.handle = mysql_real_connect(&mysql_conn,connection.host,m->mysql.username,
119 m->mysql.password, NULL, m->mysql.port, m->mysql.socket_path, 0);
120 if (!connection.handle) {
121 ERR(r, "MySQL ERROR: %s. host:[%s] username:[%s] password:[%s] port:[%d] socket_path:[%s]", mysql_error(&mysql_conn),
126 m->mysql.socket_path);
127 DBG(r, "end chxj_open_mysql_handle()");
131 apr_pool_cleanup_register(r->pool, (void *)NULL, _mysql_cleanup, _mysql_cleanup_child);
132 if (m->mysql.username) {
133 strcpy(connection.username, m->mysql.username);
136 connection.username[0] = '\0';
139 if (mysql_select_db(connection.handle,m->mysql.database) != 0) {
140 ERR(r, "%s:%d MySQL ERROR: %s", APLOG_MARK, mysql_error(connection.handle));
144 strcpy (connection.database, m->mysql.database);
145 if (m->mysql.charset) {
146 apr_snprintf(query, sizeof(query)-1, "SET CHARACTER SET %s", m->mysql.charset);
147 if (mysql_query(connection.handle, query) != 0) {
148 ERR(r, "%s:%d MySQL ERROR: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri);
153 DBG(r, "end chxj_open_mysql_handle()");
159 chxj_mysql_exist_cookie_table(request_rec *r, mod_chxj_config *m)
162 char query[MAX_STRING_LEN];
164 apr_interval_time_t wait_time = CHXJ_MYSQL_RECONNECT_WAIT_TIME;
166 apr_snprintf(query, sizeof(query)-1, "desc %s", m->mysql.tablename);
167 DBG(r, "start chxj_mysql_exist_cookie_table() query:[%s]", query);
169 if (!chxj_open_mysql_handle(r, m)) {
170 ERR(r, "%s:%d failed chxj_open_mysql_handle() query:[%s]", APLOG_MARK, query);
173 connection.reconnect = 0;
174 if (mysql_query(connection.handle, query) != 0) {
175 if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) {
176 connection.reconnect = 1;
178 if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) {
179 ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK, mysql_error(connection.handle), r->uri);
182 apr_sleep(wait_time);
185 WRN(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri);
191 result = mysql_store_result(connection.handle);
192 if (result) mysql_free_result(result);
194 DBG(r, "end chxj_mysql_exist_cookie_table() query:[%s]", query);
201 chxj_mysql_exist_cookie_table_expire(request_rec *r, mod_chxj_config *m)
204 char query[MAX_STRING_LEN];
206 apr_interval_time_t wait_time = CHXJ_MYSQL_RECONNECT_WAIT_TIME;
208 apr_snprintf(query, sizeof(query)-1, "desc %s_expire", m->mysql.tablename);
210 DBG(r, "start chxj_mysql_exist_cookie_table_expire() query:[%s]", query);
213 if (!chxj_open_mysql_handle(r, m)) {
214 ERR(r, "%s:%d failed chxj_open_mysql_handle() query:[%s]", APLOG_MARK, query);
217 connection.reconnect = 0;
218 if (mysql_query(connection.handle, query) != 0) {
219 if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) {
220 connection.reconnect = 1;
222 if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) {
223 ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK, mysql_error(connection.handle), r->uri);
226 apr_sleep(wait_time);
229 WRN(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri);
234 result = mysql_store_result(connection.handle);
235 if (result) mysql_free_result(result);
237 DBG(r, "end chxj_mysql_exist_cookie_table_expire() query:[%s]", query);
244 chxj_mysql_create_cookie_table(request_rec *r, mod_chxj_config *m)
247 char query[MAX_STRING_LEN];
249 apr_interval_time_t wait_time = CHXJ_MYSQL_RECONNECT_WAIT_TIME;
251 apr_snprintf(query, sizeof(query)-1, "CREATE TABLE %s (cookie_id VARCHAR(%d) NOT NULL, data TEXT, PRIMARY KEY(cookie_id)) TYPE=InnoDB;",
253 apr_base64_encode_len(APR_MD5_DIGESTSIZE) * 3);
254 DBG(r, "start chxj_mysql_create_cookie_table() query:[%s]", query);
256 if (!chxj_open_mysql_handle(r, m)) {
257 ERR(r, "%s:%d failed chxj_open_mysql_handle() query:[%s]", APLOG_MARK, query);
260 connection.reconnect = 0;
261 if (mysql_query(connection.handle, query) != 0) {
262 if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) {
263 connection.reconnect = 1;
265 if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) {
266 ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK, mysql_error(connection.handle), r->uri);
269 apr_sleep(wait_time);
272 WRN(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri);
278 result = mysql_store_result(connection.handle);
279 if (result) mysql_free_result(result);
281 DBG(r, "end chxj_mysql_create_cookie_table() query:[%s]", query);
287 chxj_mysql_create_cookie_expire_table(request_rec *r, mod_chxj_config *m)
290 char query[MAX_STRING_LEN];
292 apr_interval_time_t wait_time = CHXJ_MYSQL_RECONNECT_WAIT_TIME;
294 apr_snprintf(query, sizeof(query)-1, "CREATE TABLE %s_expire (cookie_id VARCHAR(%d) NOT NULL, created_at DATETIME, PRIMARY KEY(cookie_id)) TYPE=InnoDB;",
296 apr_base64_encode_len(APR_MD5_DIGESTSIZE) * 3);
298 DBG(r, "start chxj_mysql_create_cookie_expire_table() query:[%s]", query);
301 if (!chxj_open_mysql_handle(r, m)) {
302 ERR(r, "%s:%d failed chxj_open_mysql_handle() query:[%s]", APLOG_MARK, query);
305 connection.reconnect = 0;
306 if (mysql_query(connection.handle, query) != 0) {
307 if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) {
308 connection.reconnect = 1;
310 if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) {
311 ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK, mysql_error(connection.handle), r->uri);
314 apr_sleep(wait_time);
317 WRN(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri);
323 result = mysql_store_result(connection.handle);
324 if (result) mysql_free_result(result);
326 DBG(r, "end chxj_mysql_create_cookie_expire_table() query:[%s]", query);
333 chxj_mysql_get_cookie_from_cookie_id(request_rec *r, mod_chxj_config *m, const char *cookie_id)
336 char query[MAX_STRING_LEN];
338 apr_size_t clen = strlen(cookie_id);
339 char *sql_safe_cookie_id = apr_palloc(r->pool, clen*2+1);
341 apr_interval_time_t wait_time = CHXJ_MYSQL_RECONNECT_WAIT_TIME;
343 mysql_escape_string(sql_safe_cookie_id,cookie_id,clen);
345 apr_snprintf(query, sizeof(query)-1, "SELECT data, length(data) FROM %s WHERE cookie_id = '%s'", m->mysql.tablename, sql_safe_cookie_id);
346 DBG(r, "start chxj_mysql_get_cookie_from_cookie_id() query:[%s]", query);
348 if (!chxj_open_mysql_handle(r, m)) {
349 ERR(r, "%s:%d failed chxj_open_mysql_handle() query:[%s]", APLOG_MARK, query);
352 connection.reconnect = 0;
353 if (mysql_query(connection.handle, query) != 0) {
354 if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) {
355 connection.reconnect = 1;
357 if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) {
358 ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK, mysql_error(connection.handle), r->uri);
361 apr_sleep(wait_time);
364 WRN(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri);
370 result = mysql_store_result(connection.handle);
371 if (result && (mysql_num_rows(result) >= 1)) {
372 MYSQL_ROW data = mysql_fetch_row(result);
375 mysql_free_result(result);
376 ERR(r, "%s:%d MySQL cookie_id:[%s] has no valid cookie_id. %s", APLOG_MARK, cookie_id, r->uri);
380 retval = (char *) apr_palloc(r->pool, len + 1);
381 memcpy(retval, data[0], len);
383 if (result) mysql_free_result(result);
386 DBG(r, "end chxj_mysql_get_cookie_from_cookie_id() query:[%s]", query);
393 chxj_mysql_get_cookie_expire_from_cookie_id(request_rec *r, mod_chxj_config *m, const char *cookie_id)
396 char query[MAX_STRING_LEN];
397 apr_size_t clen = strlen(cookie_id);
399 char *sql_safe_cookie_id = apr_palloc(r->pool, clen*2+1);
401 apr_interval_time_t wait_time = CHXJ_MYSQL_RECONNECT_WAIT_TIME;
403 mysql_escape_string(sql_safe_cookie_id,cookie_id,clen);
405 apr_snprintf(query, sizeof(query)-1, "SELECT DATE_FORMAT(created_at, '%%Y%%m%%d%%H%%i%%s') FROM %s_expire WHERE cookie_id = '%s'",
406 m->mysql.tablename, sql_safe_cookie_id);
408 DBG(r, "start chxj_mysql_get_cookie_expire_from_cookie_id() query:[%s]", query);
411 if (!chxj_open_mysql_handle(r, m)) {
412 ERR(r, "%s:%d failed chxj_open_mysql_handle() query:[%s]", APLOG_MARK, query);
415 connection.reconnect = 0;
416 if (mysql_query(connection.handle, query) != 0) {
417 if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) {
418 connection.reconnect = 1;
420 if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) {
421 ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK, mysql_error(connection.handle), r->uri);
424 apr_sleep(wait_time);
427 WRN(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri);
433 result = mysql_store_result(connection.handle);
434 if (result && (mysql_num_rows(result) >= 1)) {
435 MYSQL_ROW data = mysql_fetch_row(result);
437 mysql_free_result(result);
438 ERR(r, "%s:%d MySQL cookie_id:[%s] has no valid cookie_id. %s", APLOG_MARK, cookie_id, r->uri);
441 retval = (char *) apr_palloc(r->pool, 19 + 1);
442 memset(retval, 0, 19+1);
443 memcpy(retval, data[0], 19);
445 if (result) mysql_free_result(result);
447 DBG(r, "end chxj_mysql_get_cookie_expire_from_cookie_id() query:[%s] retval:[%s]", query, retval);
454 chxj_mysql_insert_or_update_cookie(request_rec *r, mod_chxj_config *m, const char *cookie_id, const char *data)
457 char query[MAX_STRING_LEN];
458 char *cid = ap_escape_logitem(r->pool, cookie_id);
459 char *cdt = ap_escape_logitem(r->pool, data);
461 apr_interval_time_t wait_time = CHXJ_MYSQL_RECONNECT_WAIT_TIME;
463 DBG(r, "start chxj_mysql_insert_or_update_cookie() data:[%s]", data);
465 if (!chxj_open_mysql_handle(r, m)) {
466 ERR(r, "%s:%d failed chxj_open_mysql_handle()", APLOG_MARK);
469 connection.reconnect = 0;
470 apr_snprintf(query, sizeof(query)-1, "BEGIN;");
471 DBG(r, "query:[%s]", query);
472 if (mysql_query(connection.handle, query) != 0) {
473 if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) {
474 connection.reconnect = 1;
476 if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) {
477 ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK, mysql_error(connection.handle), r->uri);
480 apr_sleep(wait_time);
483 ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri);
489 apr_snprintf(query, sizeof(query)-1, "INSERT INTO %s (cookie_id, data) VALUES ('%s','%s');", m->mysql.tablename, cid, cdt);
490 DBG(r, "query:[%s]", query);
491 if (mysql_query(connection.handle, query) != 0) {
492 WRN(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri);
493 if (!chxj_mysql_get_cookie_from_cookie_id(r, m, cookie_id)) {
494 ERR(r, "%s:%d failed chxj_mysql_get_cookie_from_cookie_id() cookie_id:[%s]", APLOG_MARK, cookie_id);
497 apr_snprintf(query, sizeof(query)-1, "UPDATE %s set data = '%s' WHERE cookie_id = '%s';", m->mysql.tablename, cdt, cid);
498 DBG(r, "query:[%s]", query);
499 if (mysql_query(connection.handle, query) != 0) {
500 ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri);
501 chxj_mysql_rollback(r, m);
506 apr_snprintf(query, sizeof(query)-1, "COMMIT;");
507 DBG(r, "query:[%s]", query);
508 if (mysql_query(connection.handle, query) != 0) {
509 ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri);
510 chxj_mysql_rollback(r, m);
514 result = mysql_store_result(connection.handle);
515 if (result) mysql_free_result(result);
517 DBG(r, "end chxj_mysql_get_cookie_from_cookie_id()");
524 chxj_mysql_insert_or_update_cookie_expire(request_rec *r, mod_chxj_config *m, const char *cookie_id)
527 char query[MAX_STRING_LEN];
528 char *cid = ap_escape_logitem(r->pool, cookie_id);
530 apr_interval_time_t wait_time = CHXJ_MYSQL_RECONNECT_WAIT_TIME;
532 DBG(r, "start chxj_mysql_insert_or_update_cookie_expire()");
535 if (!chxj_open_mysql_handle(r, m)) {
536 ERR(r, "%s:%d failed chxj_open_mysql_handle()", APLOG_MARK);
539 connection.reconnect = 0;
540 apr_snprintf(query, sizeof(query)-1, "BEGIN;");
541 DBG(r, "query:[%s]", query);
542 if (mysql_query(connection.handle, query) != 0) {
543 if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) {
544 connection.reconnect = 1;
546 if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) {
547 ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK, mysql_error(connection.handle), r->uri);
550 apr_sleep(wait_time);
553 ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK,mysql_error(connection.handle), r->uri);
559 apr_snprintf(query, sizeof(query)-1, "INSERT INTO %s_expire (cookie_id, created_at) VALUES ('%s',localtime);", m->mysql.tablename, cid);
560 DBG(r, "query:[%s]", query);
561 if (mysql_query(connection.handle, query) != 0) {
562 WRN(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri);
563 if (!chxj_mysql_get_cookie_from_cookie_id(r, m, cookie_id)) {
564 ERR(r, "%s:%d failed chxj_mysql_get_cookie_from_cookie_id() cookie_id:[%s]", APLOG_MARK, cookie_id);
567 apr_snprintf(query, sizeof(query)-1, "UPDATE %s_expire set created_at = localtime WHERE cookie_id = '%s';", m->mysql.tablename, cid);
568 DBG(r, "query:[%s]", query);
569 if (mysql_query(connection.handle, query) != 0) {
570 ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri);
571 chxj_mysql_rollback(r, m);
576 apr_snprintf(query, sizeof(query)-1, "COMMIT;");
577 DBG(r, "query:[%s]", query);
578 if (mysql_query(connection.handle, query) != 0) {
579 ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri);
580 chxj_mysql_rollback(r, m);
584 result = mysql_store_result(connection.handle);
585 if (result) mysql_free_result(result);
587 DBG(r, "end chxj_mysql_insert_or_update_cookie_expire()");
594 chxj_mysql_rollback(request_rec *r, mod_chxj_config *m)
596 char query[MAX_STRING_LEN];
598 DBG(r, "start chxj_mysql_rollback()");
600 apr_snprintf(query, sizeof(query)-1, "ROLLBACK;");
602 if (!chxj_open_mysql_handle(r, m)) {
603 DBG(r, "end chxj_mysql_rollback()");
606 if (mysql_query(connection.handle, query) != 0) {
607 ERR(r, "%s:%d MySQL ERROR: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri);
608 return 0; /* FALSE */
610 DBG(r, "end chxj_mysql_rollback()");
615 chxj_mysql_load_cookie(request_rec *r, mod_chxj_config *m, const char *cookie_id)
618 char query[MAX_STRING_LEN];
619 apr_size_t clen = strlen(cookie_id);
621 char *sql_safe_cookie_id = apr_palloc(r->pool, clen*2+1);
623 apr_interval_time_t wait_time = CHXJ_MYSQL_RECONNECT_WAIT_TIME;
625 mysql_escape_string(sql_safe_cookie_id,cookie_id,clen);
627 apr_snprintf(query, sizeof(query)-1, "SELECT data, length(data) FROM %s WHERE cookie_id = '%s';", m->mysql.tablename, sql_safe_cookie_id);
629 DBG(r, "start chxj_mysql_load_cookie() query:[%s]", query);
632 if (!chxj_open_mysql_handle(r, m)) {
633 ERR(r, "%s:%d failed chxj_open_mysql_handle() query:[%s]", APLOG_MARK, query);
636 connection.reconnect = 0;
637 if (mysql_query(connection.handle, query) != 0) {
638 if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) {
639 connection.reconnect = 1;
641 if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) {
642 ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK, mysql_error(connection.handle), r->uri);
645 apr_sleep(wait_time);
648 WRN(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri);
654 result = mysql_store_result(connection.handle);
655 if (result && (mysql_num_rows(result) >= 1)) {
656 MYSQL_ROW data = mysql_fetch_row(result);
659 ERR(r, "%s:%d MySQL cookie_id:[%s] has no valid cookie_id. %s", APLOG_MARK, cookie_id, r->uri);
660 mysql_free_result(result);
664 retval = (char *) apr_palloc(r->pool, len + 1);
665 memset(retval, 0, len + 1);
666 memcpy(retval, data[0], len);
668 if (result) mysql_free_result(result);
670 DBG(r, "end chxj_load_mysql_cookie() query:[%s]", query);
677 chxj_mysql_load_cookie_expire(request_rec *r, mod_chxj_config *m, const char *cookie_id)
680 char query[MAX_STRING_LEN];
682 apr_size_t clen = strlen(cookie_id);
683 char *sql_safe_cookie_id = apr_palloc(r->pool, clen*2+1);
685 apr_interval_time_t wait_time = CHXJ_MYSQL_RECONNECT_WAIT_TIME;
687 mysql_escape_string(sql_safe_cookie_id,cookie_id,clen);
691 "SELECT DATE_FORMAT(created_at, '%%Y%%m%%d%%H%%i%%s') FROM %s_expire WHERE cookie_id = '%s';",
695 DBG(r, "start chxj_mysql_load_cookie_expire() query:[%s]", query);
698 if (!chxj_open_mysql_handle(r, m)) {
699 ERR(r, "%s:%d failed chxj_open_mysql_handle() query:[%s]", APLOG_MARK,query);
702 connection.reconnect = 0;
703 if (mysql_query(connection.handle, query) != 0) {
704 if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) {
705 connection.reconnect = 1;
707 if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) {
708 ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK,mysql_error(connection.handle), r->uri);
711 apr_sleep(wait_time);
714 WRN(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri);
720 result = mysql_store_result(connection.handle);
721 if (result && (mysql_num_rows(result) >= 1)) {
722 MYSQL_ROW data = mysql_fetch_row(result);
724 ERR(r, "%s:%d MySQL cookie_id:[%s] has no valid cookie_id. %s", APLOG_MARK,cookie_id, r->uri);
725 mysql_free_result(result);
728 retval = (char *) apr_palloc(r->pool, 14 + 1);
729 memcpy(retval, data[0], 14);
731 if (result) mysql_free_result(result);
733 DBG(r, "end chxj_mysql_load_cookie_expire() query:[%s]", query);
740 chxj_mysql_delete_cookie(request_rec *r, mod_chxj_config *m, const char *cookie_id)
743 char query[MAX_STRING_LEN];
744 char *cid = ap_escape_logitem(r->pool, cookie_id);
746 apr_interval_time_t wait_time = CHXJ_MYSQL_RECONNECT_WAIT_TIME;
748 DBG(r, "start chxj_mysql_delete_cookie() cookie_id:[%s]", cookie_id);
751 if (!chxj_open_mysql_handle(r, m)) {
752 ERR(r, "%s:%d failed chxj_open_mysql_handle()", APLOG_MARK);
755 connection.reconnect = 0;
756 apr_snprintf(query, sizeof(query)-1, "BEGIN;");
757 DBG(r, "query:[%s]", query);
758 if (mysql_query(connection.handle, query) != 0) {
759 if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) {
760 connection.reconnect = 1;
762 if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) {
763 ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK,mysql_error(connection.handle), r->uri);
766 apr_sleep(wait_time);
769 ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri);
775 if (!chxj_mysql_get_cookie_from_cookie_id(r, m, cookie_id)) {
776 ERR(r, "%s:%d failed chxj_mysql_get_cookie_from_cookie_id() cookie_id:[%s]", APLOG_MARK,cookie_id);
779 apr_snprintf(query, sizeof(query)-1, "DELETE FROM %s WHERE cookie_id = '%s';", m->mysql.tablename, cid);
780 DBG(r, "query:[%s]", query);
781 if (mysql_query(connection.handle, query) != 0) {
782 ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri);
783 chxj_mysql_rollback(r, m);
787 apr_snprintf(query, sizeof(query)-1, "COMMIT;");
788 DBG(r, "query:[%s]", query);
789 if (mysql_query(connection.handle, query) != 0) {
790 ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri);
791 chxj_mysql_rollback(r, m);
795 result = mysql_store_result(connection.handle);
796 if (result) mysql_free_result(result);
798 DBG(r, "end chxj_mysql_delete_cookie()");
805 chxj_mysql_delete_cookie_expire(request_rec *r, mod_chxj_config *m, const char *cookie_id)
808 char query[MAX_STRING_LEN];
809 char *cid = ap_escape_logitem(r->pool, cookie_id);
811 apr_interval_time_t wait_time = CHXJ_MYSQL_RECONNECT_WAIT_TIME;
813 DBG(r, "start chxj_mysql_delete_cookie_expire() cookie_id:[%s]", cookie_id);
816 if (!chxj_open_mysql_handle(r, m)) {
817 ERR(r, "%s:%d failed chxj_open_mysql_handle()", APLOG_MARK);
820 connection.reconnect = 0;
821 apr_snprintf(query, sizeof(query)-1, "BEGIN;");
822 DBG(r, "query:[%s]", query);
823 if (mysql_query(connection.handle, query) != 0) {
824 if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) {
825 connection.reconnect = 1;
827 if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) {
828 ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK,mysql_error(connection.handle), r->uri);
831 apr_sleep(wait_time);
834 ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK,mysql_error(connection.handle), r->uri);
840 if (!chxj_mysql_get_cookie_expire_from_cookie_id(r, m, cookie_id)) {
841 ERR(r, "%s:%d failed chxj_mysql_get_cookie_expire_from_cookie_id() cookie_id:[%s]", APLOG_MARK,cookie_id);
844 apr_snprintf(query, sizeof(query)-1, "DELETE FROM %s_expire WHERE cookie_id = '%s';", m->mysql.tablename, cid);
845 DBG(r, "query:[%s]", query);
846 if (mysql_query(connection.handle, query) != 0) {
847 ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK,mysql_error(connection.handle), r->uri);
848 chxj_mysql_rollback(r, m);
852 apr_snprintf(query, sizeof(query)-1, "COMMIT;");
853 DBG(r, "query:[%s]", query);
854 if (mysql_query(connection.handle, query) != 0) {
855 ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri);
856 chxj_mysql_rollback(r, m);
860 result = mysql_store_result(connection.handle);
861 if (result) mysql_free_result(result);
863 DBG(r, "end chxj_mysql_delete_cookie_expire() cookie_id:[%s]", cookie_id);
869 chxj_mysql_get_timeout_localtime(request_rec *r, mod_chxj_config *m)
872 char query[MAX_STRING_LEN];
875 apr_interval_time_t wait_time = CHXJ_MYSQL_RECONNECT_WAIT_TIME;
877 DBG(r, "start chxj_mysql_get_timeout_localtime()");
879 if (!chxj_open_mysql_handle(r, m)) {
880 ERR(r, "%s:%d failed chxj_open_mysql_handle()", APLOG_MARK);
883 connection.reconnect = 0;
884 apr_snprintf(query, sizeof(query)-1, "SELECT DATE_SUB(localtime, interval %ld second);",
885 (m->cookie_timeout == 0) ? DEFAULT_COOKIE_TIMEOUT : m->cookie_timeout);
886 DBG(r, "query:[%s]", query);
887 if (mysql_query(connection.handle, query) != 0) {
888 if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) {
889 connection.reconnect = 1;
891 if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) {
892 ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK, mysql_error(connection.handle), r->uri);
895 apr_sleep(wait_time);
898 ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri);
903 result = mysql_store_result(connection.handle);
904 if (result && (mysql_num_rows(result) >= 1)) {
905 MYSQL_ROW data = mysql_fetch_row(result);
907 ERR(r, "%s:%d MySQL ERROR: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri);
908 mysql_free_result(result);
911 retval = (char *) apr_palloc(r->pool, 19 + 1);
912 memset(retval, 0, 19+1);
913 memcpy(retval, data[0], 19);
915 if (result) mysql_free_result(result);
917 DBG(r, "end chxj_mysql_get_timeout_localtime()");
923 chxj_mysql_delete_expired_cookie(request_rec *r, mod_chxj_config *m)
926 char query[MAX_STRING_LEN];
929 apr_interval_time_t wait_time = CHXJ_MYSQL_RECONNECT_WAIT_TIME;
931 DBG(r, "start chxj_mysql_delete_expired_cookie()");
934 if (!chxj_open_mysql_handle(r, m)) {
935 ERR(r, "%s:%d failed chxj_open_mysql_handle()", APLOG_MARK);
938 connection.reconnect = 0;
939 apr_snprintf(query, sizeof(query)-1, "BEGIN;");
940 DBG(r, "query:[%s]", query);
941 if (mysql_query(connection.handle, query) != 0) {
942 if (mysql_errno(connection.handle) == CR_SERVER_GONE_ERROR) {
943 connection.reconnect = 1;
945 if (retry_count >= CHXJ_MYSQL_RECONNECT_COUNT) {
946 ERR(r, "%s:%d MySQL ERROR: %s: %s(retry over)", APLOG_MARK,mysql_error(connection.handle), r->uri);
949 apr_sleep(wait_time);
952 ERR(r, "%s:%d MySQL ERROR: %s: %s", APLOG_MARK,mysql_error(connection.handle), r->uri);
958 timeout = chxj_mysql_get_timeout_localtime(r, m);
960 ERR(r, "%s:%d MySQL ERROR: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri);
964 apr_snprintf(query, sizeof(query)-1, "SELECT * FROM %s_expire WHERE created_at <= '%s'", m->mysql.tablename, timeout);
965 DBG(r, "query:[%s]", query);
966 if (mysql_query(connection.handle, query) != 0) {
967 ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK,mysql_error(connection.handle), r->uri);
968 chxj_mysql_rollback(r, m);
971 result = mysql_store_result(connection.handle);
972 if (result) mysql_free_result(result);
975 /* delete from chxj_cookie */
976 apr_snprintf(query, sizeof(query)-1, "DELETE %s FROM %s, %s_expire WHERE %s_expire.created_at <= '%s' AND %s.cookie_id = %s_expire.cookie_id;",
984 DBG(r, "query:[%s]", query);
985 if (mysql_query(connection.handle, query) != 0) {
986 ERR(r, "%s:%d MySQL ERROR: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri);
987 chxj_mysql_rollback(r, m);
990 result = mysql_store_result(connection.handle);
991 if (result) mysql_free_result(result);
994 /* delete from chxj_cookie_expire */
995 apr_snprintf(query, sizeof(query)-1, "DELETE %s_expire FROM %s_expire WHERE %s_expire.created_at <= '%s';",
1000 DBG(r, "query:[%s]", query);
1001 if (mysql_query(connection.handle, query) != 0) {
1002 ERR(r, "%s:%d MySQL ERROR: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri);
1003 chxj_mysql_rollback(r, m);
1006 result = mysql_store_result(connection.handle);
1007 if (result) mysql_free_result(result);
1010 apr_snprintf(query, sizeof(query)-1, "COMMIT;");
1011 DBG(r, "query:[%s]", query);
1012 if (mysql_query(connection.handle, query) != 0) {
1013 ERR(r, "%s:%d MySQL WARN: %s: %s", APLOG_MARK, mysql_error(connection.handle), r->uri);
1014 chxj_mysql_rollback(r, m);
1018 result = mysql_store_result(connection.handle);
1019 if (result) mysql_free_result(result);
1021 DBG(r, "end chxj_mysql_delete_expired_cookie()");
1036 chxj_save_cookie_mysql(request_rec *r, mod_chxj_config *m, const char *cookie_id, const char *store_string)
1038 DBG(r, "start chxj_save_cookie_mysql()");
1039 if (! chxj_open_mysql_handle(r, m)) {
1040 ERR(r, "Cannot open mysql connection");
1041 DBG(r, "end chxj_save_cookie_mysql()");
1045 if (!chxj_mysql_exist_cookie_table(r, m)) {
1046 DBG(r, "not found cookie table:[%s]", m->mysql.tablename);
1047 if (!chxj_mysql_create_cookie_table(r, m)) {
1048 ERR(r, "cannot create cookie table:[%s]", m->mysql.tablename);
1049 DBG(r, "end chxj_save_cookie_mysql()");
1053 if (! chxj_mysql_insert_or_update_cookie(r, m, cookie_id, store_string)) {
1054 ERR(r, "cannot store to cookie table:[%s]", m->mysql.tablename);
1055 DBG(r, "end chxj_save_cookie_mysql()");
1059 /* *NEED NOT* close database. */
1060 DBG(r, "end chxj_save_cookie_mysql()");
1065 chxj_update_cookie_mysql(request_rec *r, mod_chxj_config *m, const char *cookie_id, const char *store_string)
1067 DBG(r, "start chxj_update_cookie_mysql() cookie_id:[%s]", cookie_id);
1068 if (! chxj_open_mysql_handle(r, m)) {
1069 ERR(r, "Cannot open mysql connection");
1070 DBG(r, "end chxj_update_cookie_mysql() cookie_id:[%s]", cookie_id);
1074 if (!chxj_mysql_exist_cookie_table(r, m)) {
1075 DBG(r, "not found cookie table:[%s]", m->mysql.tablename);
1076 if (!chxj_mysql_create_cookie_table(r, m)) {
1077 ERR(r, "cannot create cookie table:[%s]", m->mysql.tablename);
1078 DBG(r, "end chxj_update_cookie_mysql() cookie_id:[%s]", cookie_id);
1082 if (! chxj_mysql_insert_or_update_cookie(r, m, cookie_id, store_string)) {
1083 ERR(r, "cannot create cookie table:[%s]", m->mysql.tablename);
1084 DBG(r, "end chxj_update_cookie_mysql() cookie_id:[%s]", cookie_id);
1088 /* *NEED NOT* close database. */
1089 /* chxj_close_mysql_handle(); */
1090 DBG(r, "end chxj_update_cookie_mysql() cookie_id:[%s]", cookie_id);
1096 chxj_load_cookie_mysql(request_rec *r, mod_chxj_config *m, const char *cookie_id)
1100 DBG(r, "start chxj_load_cookie_mysql() cookie_id:[%s]", cookie_id);
1101 if (! chxj_open_mysql_handle(r, m)) {
1102 ERR(r, "Cannot open mysql connection");
1103 DBG(r, "end chxj_load_cookie_mysql() cookie_id:[%s]", cookie_id);
1107 if (!chxj_mysql_exist_cookie_table(r, m)) {
1108 DBG(r, "not found cookie table:[%s]", m->mysql.tablename);
1109 if (!chxj_mysql_create_cookie_table(r, m)) {
1110 ERR(r, "cannot create cookie table:[%s]", m->mysql.tablename);
1111 DBG(r, "end chxj_load_cookie_mysql() cookie_id:[%s]", cookie_id);
1115 if (!(load_string = chxj_mysql_load_cookie(r, m, cookie_id))) {
1116 ERR(r, "%s:%d not found cookie. cookie_id:[%s]", APLOG_MARK, cookie_id);
1117 DBG(r, "end chxj_load_cookie_mysql() cookie_id:[%s]", cookie_id);
1121 /* *NEED NOT* close database. */
1122 /* chxj_close_mysql_handle(); */
1123 DBG(r, "end chxj_load_cookie_mysql() cookie_id:[%s]", cookie_id);
1129 chxj_delete_cookie_mysql(request_rec *r, mod_chxj_config *m, const char *cookie_id)
1131 DBG(r, "start chxj_delete_cookie_mysql() cookie_id=[%s]", cookie_id);
1132 if (! chxj_open_mysql_handle(r, m)) {
1133 ERR(r, "%s:%d Cannot open mysql connection cookie_id=[%s]", APLOG_MARK, cookie_id);
1136 if (!chxj_mysql_exist_cookie_table(r, m)) {
1137 DBG(r, "not found cookie table:[%s]", m->mysql.tablename);
1138 if (!chxj_mysql_create_cookie_table(r, m)) {
1139 ERR(r, "%s:%d cannot create cookie table:[%s]", APLOG_MARK, m->mysql.tablename);
1144 if (!chxj_mysql_delete_cookie(r, m, cookie_id)) {
1145 ERR(r, "%s:%d failed: chxj_mysql_delete_cookie() cookie_id:[%s]", APLOG_MARK, cookie_id);
1149 DBG(r, "end chxj_delete_cookie_mysql() cookie_id=[%s]", cookie_id);
1155 chxj_save_cookie_expire_mysql(request_rec *r, mod_chxj_config *m, const char *cookie_id)
1157 DBG(r, "start chxj_save_cookie_expire_mysql() cookie_id:[%s]", cookie_id);
1158 if (! chxj_open_mysql_handle(r, m)) {
1159 ERR(r, "%s:%d Cannot open mysql connection cookie_id=[%s]",APLOG_MARK, cookie_id);
1163 if (!chxj_mysql_exist_cookie_table_expire(r, m)) {
1164 DBG(r, "not found cookie table:[%s_expire]", m->mysql.tablename);
1165 if (!chxj_mysql_create_cookie_expire_table(r, m)) {
1166 ERR(r, "%s:%d cannot create cookie table:[%s_expire] cookie_id:[%s]", APLOG_MARK, m->mysql.tablename, cookie_id);
1170 if (! chxj_mysql_insert_or_update_cookie_expire(r, m, cookie_id)) {
1171 ERR(r, "%s:%d cannot create cookie table:[%s_expire] cookie_id:[%s]", APLOG_MARK, m->mysql.tablename, cookie_id);
1175 /* *NEED NOT* close database. */
1176 /* chxj_close_mysql_handle(); */
1178 DBG(r, "end chxj_save_cookie_expire_mysql() cookie_id:[%s]", cookie_id);
1184 chxj_delete_cookie_expire_mysql(request_rec *r, mod_chxj_config *m, const char *cookie_id)
1186 DBG(r, "start chxj_delete_cookie_expire_mysql() cookie_id:[%s]", cookie_id);
1187 if (! chxj_open_mysql_handle(r, m)) {
1188 ERR(r, "%s:%d Cannot open mysql connection", APLOG_MARK);
1192 if (!chxj_mysql_exist_cookie_table_expire(r, m)) {
1193 DBG(r, "not found cookie table:[%s_expire]", m->mysql.tablename);
1194 if (!chxj_mysql_create_cookie_expire_table(r, m)) {
1195 ERR(r, "%s:%d cannot create cookie table:[%s_expire] cookie_id:[%s]", APLOG_MARK, m->mysql.tablename, cookie_id);
1199 if (!chxj_mysql_delete_cookie_expire(r, m, cookie_id)) {
1200 ERR(r, "%s:%d failed: chxj_mysql_delete_cookie() cookie_id:[%s]", APLOG_MARK, cookie_id);
1204 DBG(r, "end chxj_delete_cookie_expire_mysql() cookie_id:[%s]", cookie_id);
1210 chxj_cookie_expire_gc_mysql(request_rec *r, mod_chxj_config *m)
1212 DBG(r, "start chxj_cookie_expire_gc_mysql()");
1213 if (! chxj_open_mysql_handle(r, m)) {
1214 ERR(r, "Cannot open mysql connection");
1215 DBG(r, "end chxj_cookie_expire_gc_mysql()");
1218 if (!chxj_mysql_exist_cookie_table_expire(r, m)) {
1219 DBG(r, "not found cookie table:[%s_expire]", m->mysql.tablename);
1220 if (!chxj_mysql_create_cookie_expire_table(r, m)) {
1221 ERR(r, "%s:%d cannot create cookie table:[%s_expire]", APLOG_MARK, m->mysql.tablename);
1225 if (!chxj_mysql_delete_expired_cookie(r, m)) {
1226 ERR(r, "%s:%d failed: chxj_mysql_delete_expired_cookie()", APLOG_MARK);
1230 DBG(r, "end chxj_cookie_expire_gc_mysql()");
1236 chxj_cookie_lock_mysql(request_rec *r, mod_chxj_config *m)
1239 char query[MAX_STRING_LEN];
1240 DBG(r, "start chxj_cookie_lock_mysql()");
1241 if (! chxj_open_mysql_handle(r, m)) {
1242 ERR(r, "Cannot open mysql connection");
1243 DBG(r, "end chxj_save_cookie_expire_mysql()");
1246 if (!chxj_mysql_exist_cookie_table_expire(r, m)) {
1247 DBG(r, "not found cookie table:[%s_expire]", m->mysql.tablename);
1248 if (!chxj_mysql_create_cookie_expire_table(r, m)) {
1249 ERR(r, "cannot create cookie table:[%s_expire]", m->mysql.tablename);
1250 DBG(r, "end chxj_cookie_expire_gc_mysql()");
1254 apr_snprintf(query, sizeof(query)-1, "LOCK TABLES %s WRITE", m->mysql.tablename);
1255 DBG(r, "query:[%s]", query);
1256 if (mysql_query(connection.handle, query) != 0) {
1257 chxj_mysql_rollback(r, m);
1258 ERR(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri);
1262 result = mysql_store_result(connection.handle);
1263 if (result) mysql_free_result(result);
1265 DBG(r, "end chxj_cookie_lock_mysql()");
1271 chxj_cookie_unlock_mysql(request_rec *r, mod_chxj_config *UNUSED(m))
1273 char query[MAX_STRING_LEN];
1274 if (r) DBG(r, "start chxj_cookie_unlock_mysql()");
1275 apr_snprintf(query, sizeof(query)-1, "UNLOCK TABLES");
1276 if (mysql_query(connection.handle, query) != 0) {
1278 ERR(r, "MySQL WARN: %s: %s", mysql_error(connection.handle), r->uri);
1279 DBG(r, "end chxj_cookie_unlock_mysql()");
1283 if (r) DBG(r, "end chxj_cookie_unlock_mysql()");