OSDN Git Service

* Added test code of the <plaintext> for au XHTML converter.
[modchxj/mod_chxj.git] / src / chxj_memcache.c
1 /*
2  * Copyright (C) 2005-2008 Atsushi Konno All rights reserved.
3  * Copyright (C) 2005 QSDN,Inc. All rights reserved.
4  *
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
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  */
17 #ifdef USE_MEMCACHE_COOKIE
18 #include "mod_chxj.h"
19 #include "chxj_cookie.h"
20 #include "chxj_url_encode.h"
21 #include "chxj_apply_convrule.h"
22 #include "chxj_str_util.h"
23
24 #include "ap_release.h"
25
26 #include "apu.h"
27 #include "apr_uuid.h"
28 #include "apr_md5.h"
29 #include "apr_base64.h"
30 #include "apr_uri.h"
31
32 #include <unistd.h>
33
34 /* for apr-memcache */
35 #include "apr_memcache.h"
36
37 #define MEMCACHE_MIN_CONNECTION (0)
38 #define MEMCACHE_SMAX_CONNECTION (1)
39 #define MEMCACHE_MAX_CONNECTION (1)
40 #define MEMCACHE_TTL_CONNECTION (60)
41
42
43 #define MEMCACHE_MAX_SERVER (10)
44 #define MEMCACHE_FLAGS (0)
45
46 #define DEFAULT_MEMCACHE_TIMEOUT (1000)
47 #define DEFAULT_DELETE_TIMEOUT (0)
48
49 #define DEFAULT_COOKIE_DB_NAME "chxj_cookie"
50 #define DEFAULT_COOKIE_EXPIRE_DB_NAME "chxj_cookie_expire"
51
52 /* The underlying apr_memcache system is thread safe. */
53 static apr_memcache_t* mc = NULL;
54
55 static apr_status_t
56 _memcache_cleanup(void *UNUSED(notused))
57 {
58   mc = NULL;
59   return APR_SUCCESS;
60 }
61
62 int
63 chxj_memcache_init(request_rec *r, mod_chxj_config *m)
64 {
65   apr_memcache_server_t* st;
66   DBG(r, "start chxj_memcache_init()");
67   if (! mc) {
68     if (!chxj_memcache_and_memcache_server_create(r, m, &st, &mc)) {
69       ERR(r, "failed: chxj_memcache_and_memcache_server_create()");
70       return CHXJ_FALSE;
71     }
72     apr_pool_cleanup_register(r->pool, (void *)NULL, _memcache_cleanup, _memcache_cleanup);
73   }
74   DBG(r, "end chxj_memcache_init()");
75   return CHXJ_TRUE;
76 }
77
78 int
79 chxj_memcache_and_memcache_server_create(request_rec *r, mod_chxj_config *m, apr_memcache_server_t **memcache_server, apr_memcache_t **memcache)
80 {
81   DBG(r, "start chxj_memcache_server_create()");
82   if (apr_memcache_server_create(r->pool, 
83                                  m->memcache.host,
84                                  m->memcache.port,
85                                  MEMCACHE_MIN_CONNECTION, 
86                                  MEMCACHE_SMAX_CONNECTION,
87                                  MEMCACHE_MAX_CONNECTION,
88                                  MEMCACHE_TTL_CONNECTION,
89                                  memcache_server) != APR_SUCCESS) {
90     ERR(r, "failed apr_memcache_server_create() host:[%s] port:[%d]", m->memcache.host, m->memcache.port);
91     return CHXJ_FALSE;
92   }
93   DBG(r, "done create_server");
94   if (apr_memcache_create(r->pool, MEMCACHE_MAX_SERVER, MEMCACHE_FLAGS, memcache) != APR_SUCCESS) {
95     ERR(r, "failed apr_memcache_create()");
96     return CHXJ_FALSE;
97   }
98   DBG(r, "done create memcache");
99   if (apr_memcache_add_server(*memcache, *memcache_server) != APR_SUCCESS) {
100     ERR(r, "failed apr_memcache_add_server()");
101     return CHXJ_FALSE;
102   }
103   DBG(r, "end chxj_memcache_server_create()");
104
105   return CHXJ_TRUE;
106 }
107
108
109 int
110 chxj_memcache_set_cookie(request_rec *r, mod_chxj_config *m, const char *cookie_id, const char *store_string)
111 {
112   apr_status_t ret;
113   apr_uint32_t timeout = (apr_uint32_t) ((m->cookie_timeout) ? m->cookie_timeout : DEFAULT_COOKIE_TIMEOUT);
114   DBG(r, "start chxj_memcache_set_cookie()");
115
116   do {
117     if ((ret = apr_memcache_set(mc, cookie_id, (char *)store_string, strlen(store_string), timeout, 0)) != APR_SUCCESS) {
118       if (ret == APR_EAGAIN) {
119         continue;
120       }
121       ERR(r, "failed: apr_memcache_set() ret:[%d]", ret);
122       return CHXJ_FALSE;
123     }
124   }
125   while(0);
126
127   DBG(r, "end chxj_memcache_set_cookie()");
128   return CHXJ_TRUE;
129 }
130
131
132 int
133 chxj_memcache_reset_cookie(request_rec *r, mod_chxj_config *m, const char *cookie_id)
134 {
135   char *store_string;
136   DBG(r, "start chxj_memcache_reset_cookie()");
137
138
139   if (! (store_string = chxj_memcache_get_cookie(r, m, cookie_id))) {
140     ERR(r, "failed: chxj_memcache_get_cookie() cookie_id:[%s]", cookie_id);
141     return CHXJ_FALSE;
142   }
143
144   if (! chxj_memcache_set_cookie(r, m, cookie_id, store_string)) {
145     ERR(r, "failed: apr_memcache_set()");
146     return CHXJ_FALSE;
147   }
148
149   DBG(r, "end chxj_memcache_reset_cookie()");
150   return CHXJ_TRUE;
151 }
152
153
154 char *
155 chxj_memcache_get_cookie(request_rec *r, mod_chxj_config *UNUSED(m), const char *cookie_id)
156 {
157   char *load_string;
158   char *ret_value;
159   apr_size_t len;
160   apr_status_t ret;
161   DBG(r, "start chxj_memcache_get_cookie()");
162
163   do {
164     if ((ret = apr_memcache_getp(mc, r->pool, cookie_id, &load_string, &len, 0)) != APR_SUCCESS) {
165       if (ret == APR_EAGAIN) {
166         continue;
167       }
168       ERR(r, "failed: apr_memcache_get() cookie_id:[%s] ret:[%d]", cookie_id, ret);
169       return NULL;
170     }
171   }
172   while(0);
173   
174   ret_value = apr_palloc(r->pool, len+1);
175   memset(ret_value, 0, len+1);
176   memcpy(ret_value, load_string, len);
177
178   DBG(r, "end chxj_memcache_get_cookie()");
179   return ret_value;
180 }
181
182
183 int
184 chxj_memcache_delete_cookie(request_rec *r, mod_chxj_config *UNUSED(m),  const char *cookie_id)
185 {
186   apr_status_t ret;
187   DBG(r, "start chxj_memcache_delete_cookie()");
188
189   do {
190     if ((ret = apr_memcache_delete(mc, cookie_id, 0)) != APR_SUCCESS) {
191       if (ret == APR_EAGAIN) {
192         continue;
193       }
194       ERR(r, "failed: apr_memcache_delete() cookie_id:[%s] ret:[%d]", cookie_id, ret);
195       return CHXJ_FALSE;
196     }
197   }
198   while(0);
199
200   DBG(r, "end chxj_memcache_delete_cookie()");
201   return CHXJ_TRUE;
202 }
203
204
205
206 int
207 chxj_save_cookie_memcache(request_rec *r, mod_chxj_config *m, const char *cookie_id, const char *store_string)
208 {
209   DBG(r, "start chxj_save_cookie_memcache() cookie_id:[%s]", cookie_id);
210   if (! chxj_memcache_init(r, m)) {
211     ERR(r, "Cannot create memcache server");
212     DBG(r, "end chxj_save_cookie_memcache() cookie_id:[%s]", cookie_id);
213     return CHXJ_FALSE;
214   }
215
216   if (! chxj_memcache_set_cookie(r, m, cookie_id, store_string)) {
217     ERR(r, "cannot store to memcache host:[%s] port:[%d]", m->memcache.host, m->memcache.port);
218     DBG(r, "end chxj_save_cookie_memcache() cookie_id:[%s]", cookie_id);
219     return CHXJ_FALSE;
220   }
221   DBG(r, "stored DATA:[%s]", chxj_memcache_get_cookie(r, m, cookie_id));
222   DBG(r, "end chxj_save_cookie_memcache() cookie_id:[%s]", cookie_id);
223   return CHXJ_TRUE;
224 }
225
226
227 int
228 chxj_update_cookie_memcache(request_rec *r, mod_chxj_config *m, const char *cookie_id, const char *store_string)
229 {
230   DBG(r, "start chxj_update_cookie_memcache() cookie_id:[%s]", cookie_id);
231   if (! chxj_memcache_init(r, m)) {
232     ERR(r, "Cannot create memcache server");
233     DBG(r, "end chxj_update_cookie_memcache() cookie_id:[%s]", cookie_id);
234     return CHXJ_FALSE;
235   }
236
237   if (! chxj_memcache_set_cookie(r, m, cookie_id, store_string)) {
238     ERR(r, "cannot store to memcache host:[%s] port:[%d]", m->memcache.host, m->memcache.port);
239     DBG(r, "end chxj_update_cookie_memcache() cookie_id:[%s]", cookie_id);
240     return CHXJ_FALSE;
241   }
242   DBG(r, "end chxj_update_cookie_memcache() cookie_id:[%s]", cookie_id);
243   return CHXJ_TRUE;
244 }
245
246
247 char *
248 chxj_load_cookie_memcache(request_rec *r, mod_chxj_config *m, const char *cookie_id)
249 {
250   char *load_string;
251   DBG(r, "start chxj_load_cookie_memcache() cookie_id:[%s]", cookie_id);
252
253   if (! chxj_memcache_init(r, m)) {
254     ERR(r, "Cannot create memcache server");
255     DBG(r, "end   chxj_load_cookie_memcache() cookie_id:[%s]", cookie_id);
256     return NULL;
257   }
258
259   if (! (load_string = chxj_memcache_get_cookie(r, m, cookie_id))) {
260     ERR(r, "cannot store to memcache host:[%s] port:[%d]", m->memcache.host, m->memcache.port);
261     DBG(r, "end   chxj_load_cookie_memcache() cookie_id:[%s]", cookie_id);
262     return NULL;
263   }
264   DBG(r, "end   chxj_load_cookie_memcache() cookie_id:[%s]", cookie_id);
265   return load_string;
266 }
267
268
269 int
270 chxj_delete_cookie_memcache(request_rec *r, mod_chxj_config *m, const char *cookie_id)
271 {
272   DBG(r, "start chxj_delete_cookie_memcache() cookie_id:[%s]", cookie_id);
273   if (! chxj_memcache_init(r, m)) {
274     ERR(r, "Cannot create memcache server");
275     DBG(r, "end   chxj_delete_cookie_memcache() cookie_id:[%s]", cookie_id);
276     return CHXJ_FALSE;
277   }
278
279   if (! chxj_memcache_delete_cookie(r, m, cookie_id)) {
280     ERR(r, "cannot store to memcache host:[%s] port:[%d]", m->memcache.host, m->memcache.port);
281     DBG(r, "end   chxj_delete_cookie_memcache() cookie_id:[%s]", cookie_id);
282     return CHXJ_FALSE;
283   }
284   DBG(r, "end   chxj_delete_cookie_memcache() cookie_id:[%s]", cookie_id);
285   return CHXJ_TRUE;
286 }
287
288
289 int
290 chxj_save_cookie_expire_memcache(request_rec *r, mod_chxj_config *m, const char *cookie_id)
291 {
292   DBG(r, "start chxj_save_cookie_expire_memcache() cookie_id:[%s]", cookie_id);
293   if (! chxj_memcache_init(r, m)) {
294     ERR(r, "Cannot create memcache server");
295     DBG(r, "end   chxj_save_cookie_expire_memcache() cookie_id:[%s]", cookie_id);
296     return CHXJ_FALSE;
297   }
298
299   if (! chxj_memcache_reset_cookie(r, m, cookie_id)) {
300     ERR(r, "cannot store to memcache host:[%s] port:[%d]", m->memcache.host, m->memcache.port);
301     DBG(r, "end   chxj_save_cookie_expire_memcache() cookie_id:[%s]", cookie_id);
302     return CHXJ_FALSE;
303   }
304   DBG(r, "end   chxj_save_cookie_expire_memcache() cookie_id:[%s]", cookie_id);
305   return CHXJ_TRUE;
306 }
307
308
309 int
310 chxj_delete_cookie_expire_memcache(request_rec *r, mod_chxj_config *UNUSED(m), const char *cookie_id)
311 {
312   DBG(r, "start chxj_delete_cookie_expire_memcache() cookie_id:[%s]", cookie_id);
313   /* PASS */
314   DBG(r, "end   chxj_delete_cookie_expire_memcache() cookie_id:[%s]", cookie_id);
315   return CHXJ_TRUE;
316 }
317
318
319 int
320 chxj_cookie_expire_gc_memcache(request_rec *r, mod_chxj_config *UNUSED(m))
321 {
322   DBG(r, "start chxj_cookie_expire_gc_memcache()");
323   /* PASS */
324   DBG(r, "end   chxj_cookie_expire_gc_memcache()");
325   return CHXJ_TRUE;
326 }
327
328 #endif
329 /*
330  * vim:ts=2 et
331  */