/*
+ * Copyright (C) 2005-2008 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 <unistd.h>
#include <string.h>
+#include <limits.h>
+#include <errno.h>
#include "httpd.h"
#include "http_config.h"
#include "chxj_apply_convrule.h"
#include "chxj_cookie.h"
#include "chxj_url_encode.h"
+#include "chxj_str_util.h"
+#if defined(USE_MYSQL_COOKIE)
+# include "chxj_mysql.h"
+#endif
#define CHXJ_VERSION_PREFIX PACKAGE_NAME "/"
.converter = NULL,
.encoder = NULL,
},
- {
- NULL
- }
};
static int chxj_convert_input_header(request_rec *r,chxjconvrule_entry* entryp);
* @param len [i/o] It is length of former HTML character string.
*/
static char*
-chxj_exchange(request_rec *r, const char** src, apr_size_t* len)
+chxj_exchange(request_rec *r, const char** src, apr_size_t* len, device_table *spec, const char *ua, cookie_t **cookiep)
{
- char* user_agent;
- char* dst;
- char* tmp;
- char* cookie_id;
- mod_chxj_config* dconf;
- chxjconvrule_entry* entryp;
-
+ char *user_agent;
+ char *dst;
+ char *tmp;
+ cookie_t *cookie;
+ mod_chxj_config *dconf;
+ chxjconvrule_entry *entryp;
+
+ DBG(r,"start of chxj_exchange() input:[%.*s]", (int)*len, *src);
dst = apr_pstrcat(r->pool, (char*)*src, NULL);
dconf = ap_get_module_config(r->per_dir_config, &chxj_module);
else
user_agent = (char*)apr_table_get(r->headers_in, HTTP_USER_AGENT);
- DBG1(r,"User-Agent:[%s]", user_agent);
- DBG(r, "start chxj_exchange()");
- DBG1(r,"content type is %s", r->content_type);
+ DBG(r,"User-Agent:[%s]", user_agent);
+ DBG(r,"content type is %s", r->content_type);
- if (*(char*)r->content_type == 't'
- && strncmp(r->content_type, "text/html", 9) != 0) {
- DBG1(r,"content type is %s", r->content_type);
+ if (! STRNCASEEQ('t','T', "text/html", r->content_type, sizeof("text/html")-1)
+ && ! STRNCASEEQ('a','A', "application/xhtml+xml", r->content_type, sizeof("application/xhtml+xml")-1)) {
+ DBG(r,"no convert. content type is %s", r->content_type);
+ DBG(r,"end of chxj_exchange()");
return (char*)*src;
}
+ if (ua && user_agent && strcasecmp(user_agent, ua) != 0) {
+ /* again */
+ spec = chxj_specified_device(r, user_agent);
+ }
+
/*
* save cookie.
*/
- cookie_id = NULL;
- if (entryp->action & CONVRULE_COOKIE_ON_BIT)
- cookie_id = chxj_save_cookie(r);
+ cookie = NULL;
+ if (entryp->action & CONVRULE_COOKIE_ON_BIT) {
+ switch(spec->html_spec_type) {
+ case CHXJ_SPEC_Chtml_1_0:
+ case CHXJ_SPEC_Chtml_2_0:
+ case CHXJ_SPEC_Chtml_3_0:
+ case CHXJ_SPEC_Chtml_4_0:
+ case CHXJ_SPEC_Chtml_5_0:
+ case CHXJ_SPEC_Jhtml:
+ cookie = chxj_save_cookie(r);
+ break;
+ default:
+ break;
+ }
+ }
if (!r->header_only) {
- device_table* spec = chxj_specified_device(r, user_agent);
tmp = NULL;
if (convert_routine[spec->html_spec_type].encoder)
*len,
len,
entryp,
- cookie_id);
+ cookie);
else
dst = convert_routine[spec->html_spec_type].converter(r,
spec,
*len,
len,
entryp,
- cookie_id);
+ cookie);
}
}
*len = 1;
}
dst[*len] = 0;
+ if (cookie) {
+ *cookiep = cookie;
+ }
- DBG(r, "end chxj_exchange()");
+ DBG(r, "end of chxj_exchange()");
return dst;
}
{
char* buff;
+ char* buff_pre;
apr_size_t urilen;
char* result;
char* pair;
char* value;
char* pstate;
char* vstate;
+ cookie_t* cookie;
+ int no_update_flag = 0;
DBG(r, "start chxj_convert_input_header()");
result = qs_alloc_zero_byte_string(r);
+ buff_pre = apr_pstrdup(r->pool, r->args);
+
+ for (;;) {
+ char* pair_sv;
+
+ pair = apr_strtok(buff_pre, "&", &pstate);
+ if (pair == NULL)
+ break;
+
+ buff_pre = NULL;
+
+ pair_sv = apr_pstrdup(r->pool, pair);
+
+ name = apr_strtok(pair, "=", &vstate);
+ value = apr_strtok(NULL, "=", &vstate);
+ if (strcasecmp(name, CHXJ_COOKIE_NOUPDATE_PARAM) == 0) {
+ DBG(r, "found cookie no update parameter");
+ no_update_flag++;
+ }
+ }
+
buff = apr_pstrdup(r->pool, r->args);
- DBG1(r, "r->args=[%s]", buff);
+ DBG(r, "r->args=[%s]", buff);
/* _chxj_dmy */
/* _chxj_c_ */
/* _chxj_r_ */
/* _chxj_s_ */
for (;;) {
+ char* pair_sv;
pair = apr_strtok(buff, "&", &pstate);
if (pair == NULL)
buff = NULL;
+ pair_sv = apr_pstrdup(r->pool, pair);
+
name = apr_strtok(pair, "=", &vstate);
value = apr_strtok(NULL, "=", &vstate);
if (strncasecmp(name, "_chxj", 5) != 0) {
dlen = strlen(value);
value = chxj_url_decode(r, value);
- DBG1(r, "************ before encoding[%s]", value);
+ DBG(r, "************ before encoding[%s]", value);
dvalue = chxj_rencoding(r, value, &dlen);
dvalue = chxj_url_encode(r, dvalue);
- DBG1(r, "************ after encoding[%s]", dvalue);
+ DBG(r, "************ after encoding[%s]", dvalue);
result = apr_pstrcat(r->pool, result, name, "=", dvalue, NULL);
}
else {
- if (strcmp(name, pair) != 0)
+ if (strcmp(name, pair_sv) != 0)
result = apr_pstrcat(r->pool, result, name, "=", value, NULL);
else
result = apr_pstrcat(r->pool, result, name, NULL);
}
else
if (strcasecmp(name, CHXJ_COOKIE_PARAM) == 0) {
- DBG1(r, "found cookie parameter[%s]", value);
- chxj_load_cookie(r, value);
+ DBG(r, "found cookie parameter[%s]", value);
+ DBG(r, "call start chxj_load_cookie()");
+ cookie = chxj_load_cookie(r, value);
+ DBG(r, "call end chxj_load_cookie()");
+ if (! no_update_flag && cookie) {
+ chxj_update_cookie(r, cookie);
+ }
}
}
r->args = result;
- DBG1(r, "result r->args=[%s]", r->args);
+ DBG(r, "result r->args=[%s]", r->args);
DBG(r, "end chxj_convert_input_header()");
return 0;
}
char* vstate;
char* s;
char* result;
+ cookie_t* cookie;
+ char* buff_pre;
+ int no_update_flag = 0;
- s = apr_pstrdup(r->pool, *src);
+ s = apr_pstrdup(r->pool, *src);
+ buff_pre = apr_pstrdup(r->pool, *src);
result = qs_alloc_zero_byte_string(r);
- DBG1(r, "BEFORE input convert source = [%s]", s);
+ DBG(r, "BEFORE input convert source = [%s]", s);
+
+ for (;;) {
+ char* pair_sv;
+
+ pair = apr_strtok(buff_pre, "&", &pstate);
+ if (pair == NULL)
+ break;
+
+ buff_pre = NULL;
+
+ pair_sv = apr_pstrdup(r->pool, pair);
+
+ name = apr_strtok(pair, "=", &vstate);
+ value = apr_strtok(NULL, "=", &vstate);
+ if (strcasecmp(name, CHXJ_COOKIE_NOUPDATE_PARAM) == 0) {
+ DBG(r, "found cookie no update parameter");
+ no_update_flag++;
+ }
+ }
/* _chxj_dmy */
/* _chxj_c_ */
dlen = strlen(value);
value = chxj_url_decode(r, value);
- DBG1(r, "************ before encoding[%s]", value);
+ DBG(r, "************ before encoding[%s]", value);
dvalue = chxj_rencoding(r, value, &dlen);
dvalue = chxj_url_encode(r,dvalue);
- DBG1(r, "************ after encoding[%s]", dvalue);
+ DBG(r, "************ after encoding[%s]", dvalue);
result = apr_pstrcat(r->pool, result, name, "=", dvalue, NULL);
dlen = strlen(value);
value = chxj_url_decode(r, value);
- DBG1(r, "************ before encoding[%s]", value);
+ DBG(r, "************ before encoding[%s]", value);
dvalue = chxj_rencoding(r, value, &dlen);
dvalue = chxj_url_encode(r,dvalue);
- DBG1(r, "************ after encoding[%s]", dvalue);
+ DBG(r, "************ after encoding[%s]", dvalue);
result = apr_pstrcat(r->pool, result, &name[8], "=", dvalue, NULL);
}
else
if (strcasecmp(name, CHXJ_COOKIE_PARAM) == 0) {
- DBG1(r, "found cookie parameter[%s]", value);
- chxj_load_cookie(r, value);
+ DBG(r, "found cookie parameter[%s]", value);
+ DBG(r, "call start chxj_load_cookie()");
+ cookie = chxj_load_cookie(r, value);
+ DBG(r, "call end chxj_load_cookie()");
+ if (! no_update_flag && cookie) {
+ chxj_update_cookie(r, cookie);
+ }
}
}
*len = strlen(result);
- DBG1(r, "AFTER input convert result = [%s]", result);
+ DBG(r, "AFTER input convert result = [%s]", result);
return result;
}
apr_bucket* b;
const char* data;
char* contentLength;
+ char* user_agent = NULL;
apr_size_t len;
- mod_chxj_ctx* ctx;
- char* cookie_id;
+ mod_chxj_ctx* ctx = (mod_chxj_ctx *)f->ctx;
+ cookie_t* cookie = NULL;
char* location_header;
mod_chxj_config* dconf;
- chxjconvrule_entry* entryp;
+ chxjconvrule_entry *entryp = NULL;
+ device_table *spec = NULL;
- DBG(r, "start of chxj_output_filter()");
-
+ DBG(f->r, "start of chxj_output_filter()");
r = f->r;
rv = APR_SUCCESS;
&& !f->r->prev)
f->r->chunked = 1;
}
+ if (r->content_type) {
+ if (! STRNCASEEQ('t','T',"text/html",r->content_type, sizeof("text/html")-1)
+ && ! STRNCASEEQ('t','T',"text/xml", r->content_type, sizeof("text/xml")-1)
+ && ! STRNCASEEQ('a','A',"application/xhtml+xml", r->content_type, sizeof("application/xhtml+xml")-1)
+ && ! (STRNCASEEQ('i','I',"image/", r->content_type, sizeof("image/") -1)
+ && ( STRCASEEQ('j','J',"jpeg", &r->content_type[6]) /* JPEG */
+ || STRCASEEQ('j','J',"jp2", &r->content_type[6]) /* JPEG2000 */
+ || STRCASEEQ('j','J',"jpeg2000", &r->content_type[6]) /* JPEG2000 */
+ || STRCASEEQ('j','J',"jpeg2000-image", &r->content_type[6]) /* JPEG2000 */
+ || STRCASEEQ('x','X',"x-jpeg2000-image",&r->content_type[6]) /* JPEG2000 */
+ || STRCASEEQ('p','P',"png", &r->content_type[6]) /* PNG */
+ || STRCASEEQ('x','X',"x-png", &r->content_type[6]) /* PNG */
+ || STRCASEEQ('g','G',"gif", &r->content_type[6])))) { /* GIF */
+
+ DBG(r, "not convert content-type:[%s]", r->content_type);
+ ap_pass_brigade(f->next, bb);
+ return APR_SUCCESS;
+ }
+ }
+ else {
+ DBG(r, "not convert content-type:[(null)]");
+ ap_pass_brigade(f->next, bb);
+ return APR_SUCCESS;
+ }
- dconf = ap_get_module_config(r->per_dir_config, &chxj_module);
- entryp = chxj_apply_convrule(r, dconf->convrules);
+ dconf = ap_get_module_config(r->per_dir_config, &chxj_module);
+ user_agent = (char*)apr_table_get(r->headers_in, HTTP_USER_AGENT);
+ if (ctx && ctx->entryp) entryp = ctx->entryp;
+ else entryp = chxj_apply_convrule(r, dconf->convrules);
+ if (ctx && ctx->spec) spec = ctx->spec;
+ else spec = chxj_specified_device(r, user_agent);
for (b = APR_BRIGADE_FIRST(bb);
b != APR_BRIGADE_SENTINEL(bb);
b = APR_BUCKET_NEXT(b)) {
+
+ if (apr_bucket_read(b, &data, &len, APR_BLOCK_READ) == APR_SUCCESS) {
+ DBG(r, "read data[%.*s]",(int)len, data);
+
+ if (f->ctx == NULL) {
+ /*--------------------------------------------------------------------*/
+ /* Start */
+ /*--------------------------------------------------------------------*/
+ DBG(r, "new context");
+ ctx = (mod_chxj_ctx*)apr_palloc(r->pool, sizeof(mod_chxj_ctx));
+ if (len > 0) {
+ ctx->buffer = apr_palloc(r->pool, len);
+ memcpy(ctx->buffer, data, len);
+ }
+ else {
+ ctx->buffer = apr_palloc(r->pool, 1);
+ ctx->buffer = '\0';
+ }
+ ctx->len = len;
+ f->ctx = (void*)ctx;
+ ctx->entryp = entryp;
+ ctx->spec = spec;
+ }
+ else {
+ /*--------------------------------------------------------------------*/
+ /* append data */
+ /*--------------------------------------------------------------------*/
+ char* tmp;
+ DBG(r, "append data start");
+ ctx = (mod_chxj_ctx*)f->ctx;
+
+ if (len > 0) {
+ tmp = apr_palloc(r->pool, ctx->len);
+ memcpy(tmp, ctx->buffer, ctx->len);
+
+ ctx->buffer = apr_palloc(r->pool, ctx->len + len);
+
+ memcpy(ctx->buffer, tmp, ctx->len);
+ memcpy(&ctx->buffer[ctx->len], data, len);
+
+ ctx->len += len;
+ }
+ DBG(r, "append data end");
+ }
+ }
+
if (APR_BUCKET_IS_EOS(b)) {
+
DBG(r, "eos");
/*----------------------------------------------------------------------*/
/* End Of File */
/*----------------------------------------------------------------------*/
- if (f->ctx) {
+ if (ctx) {
+
ctx = (mod_chxj_ctx*)f->ctx;
- DBG1(r, "content_type=[%s]", r->content_type);
- if (r->content_type
- && *(char*)r->content_type == 't'
- && strncmp(r->content_type, "text/html", 9) == 0) {
+
+ DBG(r, "content_type=[%s]", r->content_type);
+
+ if (spec->html_spec_type != CHXJ_SPEC_UNKNOWN
+ && r->content_type
+ && (STRNCASEEQ('a','A',"application/xhtml+xml", r->content_type, sizeof("application/xhtml+xml")-1)
+ || STRNCASEEQ('t','T',"text/html", r->content_type, sizeof("text/html")-1))) {
+ DBG(r, "detect exchange target:[%s]", r->content_type);
+
if (ctx->len) {
- char* tmp = apr_palloc(r->pool, ctx->len + 1);
+ char* tmp;
+
+ tmp = apr_palloc(r->pool, ctx->len + 1);
+
memset(tmp, 0, ctx->len + 1);
memcpy(tmp, ctx->buffer, ctx->len);
- DBG2(r, "input data=[%s] len=[%d]", tmp, ctx->len);
+#if 0
+ DBG(r, "input data=[%s] len=[%d]", tmp, ctx->len);
+#endif
- ctx->buffer = chxj_exchange(r, (const char**)&tmp, (apr_size_t*)&ctx->len);
+ ctx->buffer = chxj_exchange(r,
+ (const char**)&tmp,
+ (apr_size_t*)&ctx->len,
+ spec,
+ user_agent, &cookie);
- DBG2(r, "output data=[%.*s]", ctx->len,ctx->buffer);
+#if 0
+ DBG(r, "output data=[%.*s]", ctx->len,ctx->buffer);
+#endif
}
else {
ctx->buffer = apr_psprintf(r->pool, "\n");
ctx->len += 1;
ctx->buffer = chxj_exchange(r,
(const char**)&ctx->buffer,
- (apr_size_t*)&ctx->len);
+ (apr_size_t*)&ctx->len,
+ spec,
+ user_agent, &cookie);
}
}
+ if (r->content_type
+ && *(char*)r->content_type == 't'
+ && strncmp(r->content_type, "text/xml", 8) == 0) {
+ DBG(r, "text/XML");
+
+ Doc doc;
+ Node* root;
+ Node* child;
+ qr_code_t qrcode;
+ int sts;
+
+ memset(&doc, 0, sizeof(Doc));
+ memset(&qrcode, 0, sizeof(qr_code_t));
+ doc.r = r;
+ doc.parse_mode = PARSE_MODE_CHTML;
+ qrcode.doc = &doc;
+ qrcode.r = r;
+
+ qs_init_malloc(&doc);
+
+ root = qs_parse_string(&doc, ctx->buffer, ctx->len);
+
+ sts = 0;
+ for (child = qs_get_child_node(&doc,root);
+ child ;
+ child = qs_get_next_node(&doc,child)) {
+
+ char* name;
+
+ name = qs_get_node_name(&doc,child);
+
+ if (strcasecmp("qrcode",name) == 0) {
+ sts++;
+ break;
+ }
+ }
+ qs_all_free(&doc,QX_LOGMARK);
+ if (sts) {
+ r->handler = apr_psprintf(r->pool, "chxj-qrcode");
+ chxj_qrcode_node_to_qrcode(&qrcode, root);
+ sts = chxj_qrcode_create_image_data(&qrcode, &ctx->buffer, &ctx->len);
+ if (sts != OK) {
+ ERR(r, "qrcode create failed.");
+ return sts;
+ }
+ r->content_type = apr_psprintf(r->pool, "image/jpg");
+ }
+ }
- if (r->content_type
- && *(char*)r->content_type == 'i'
- && strncmp(r->content_type, "image/", 6) == 0) {
+ if (spec->html_spec_type != CHXJ_SPEC_UNKNOWN
+ && r->content_type
+ && ( *r->content_type == 'i' || *r->content_type == 'I')
+ && strncasecmp("image/", r->content_type, 6) == 0
+ && ( STRCASEEQ('j','J',"jpeg", &r->content_type[6]) /* JPEG */
+ || STRCASEEQ('j','J',"jp2", &r->content_type[6]) /* JPEG2000 */
+ || STRCASEEQ('j','J',"jpeg2000", &r->content_type[6]) /* JPEG2000 */
+ || STRCASEEQ('j','J',"jpeg2000-image", &r->content_type[6]) /* JPEG2000 */
+ || STRCASEEQ('x','X',"x-jpeg2000-image",&r->content_type[6]) /* JPEG2000 */
+ || STRCASEEQ('p','P',"png", &r->content_type[6]) /* PNG */
+ || STRCASEEQ('x','X',"x-png", &r->content_type[6]) /* PNG */
+ || STRCASEEQ('g','G',"gif", &r->content_type[6]))) { /* GIF */
if (ctx->len) {
- char* tmp = apr_palloc(r->pool, ctx->len + 1);
+ char* tmp;
+
+ tmp = apr_palloc(r->pool, ctx->len + 1);
+
memset(tmp, 0, ctx->len + 1);
memcpy(tmp, ctx->buffer, ctx->len);
- DBG1(r, "input data=[%s]", tmp);
+#if 0
+ DBG(r, "input data=[%s]", tmp);
+#endif
+
ctx->buffer =
- chxj_exchange_image(r, (const char**)&tmp,(apr_size_t*)&ctx->len);
- if (ctx->buffer == NULL) {
+ chxj_exchange_image(r,
+ (const char**)&tmp,
+ (apr_size_t*)&ctx->len);
+
+ if (ctx->buffer == NULL)
ctx->buffer = tmp;
- }
- DBG2(r, "output data=[%.*s]", ctx->len,ctx->buffer);
+#if 0
+ DBG(r, "output data=[%.*s]", ctx->len,ctx->buffer);
+#endif
}
}
- contentLength = apr_psprintf(r->pool, "%d", ctx->len);
+ contentLength = apr_psprintf(r->pool, "%d", (int)ctx->len);
apr_table_setn(r->headers_out, "Content-Length", contentLength);
if (ctx->len > 0) {
+ DBG(r, "call pass_data_to_filter()");
+ location_header = (char*)apr_table_get(r->headers_out, "Location");
+ if (cookie && location_header) {
+ DBG(r, "Location Header=[%s]", location_header);
+ location_header = chxj_add_cookie_parameter(r,
+ location_header,
+ cookie);
+ apr_table_setn(r->headers_out, "Location", location_header);
+ DBG(r, "Location Header=[%s]", location_header);
+ }
rv = pass_data_to_filter(f,
(const char*)ctx->buffer,
(apr_size_t)ctx->len);
}
f->ctx = NULL;
- DBG(r, " ");
+
return rv;
}
else {
- DBG1(r, " SAVE COOKIE[%x]", entryp->action);
+ DBG(r, " SAVE COOKIE[%x]", entryp->action);
+
/*
* save cookie.
*/
if (entryp->action & CONVRULE_COOKIE_ON_BIT) {
DBG(r, "entryp->action == COOKIE_ON_BIT");
+ char* user_agent = (char*)apr_table_get(r->headers_in, HTTP_USER_AGENT);
+ device_table* spec = chxj_specified_device(r, user_agent);
+
+ switch(spec->html_spec_type) {
+ case CHXJ_SPEC_Chtml_1_0:
+ case CHXJ_SPEC_Chtml_2_0:
+ case CHXJ_SPEC_Chtml_3_0:
+ case CHXJ_SPEC_Chtml_4_0:
+ case CHXJ_SPEC_Chtml_5_0:
+ case CHXJ_SPEC_Jhtml:
+
+ cookie = chxj_save_cookie(r);
+
+ /*
+ * Location Header Check to add cookie parameter.
+ */
+ location_header = (char*)apr_table_get(r->headers_out, "Location");
+ if (cookie && location_header) {
+ DBG(r, "Location Header=[%s]", location_header);
+ location_header = chxj_add_cookie_parameter(r,
+ location_header,
+ cookie);
+ apr_table_setn(r->headers_out, "Location", location_header);
+ DBG(r, "Location Header=[%s]", location_header);
+ }
+ break;
- cookie_id = chxj_save_cookie(r);
-
- /*
- * Location Header Check to add cookie parameter.
- */
- location_header = (char*)apr_table_get(r->headers_out, "Location");
- if (location_header) {
- DBG1(r, "Location Header=[%s]", location_header);
- location_header = chxj_add_cookie_parameter(r,
- location_header,
- cookie_id);
- apr_table_setn(r->headers_out, "Location", location_header);
- DBG1(r, "Location Header=[%s]", location_header);
+ default:
+ break;
}
}
apr_table_setn(r->headers_out, "Content-Length", "0");
+ DBG(r, "call pass_data_to_filter()");
rv = pass_data_to_filter(f, (const char*)"", (apr_size_t)0);
- DBG(r, " ");
- return rv;
- }
- }
- else
- if (apr_bucket_read(b, &data, &len, APR_BLOCK_READ) == APR_SUCCESS) {
- DBG2(r, "read data[%.*s]",len, data);
-
- if (f->ctx == NULL) {
- /*--------------------------------------------------------------------*/
- /* Start */
- /*--------------------------------------------------------------------*/
- DBG(r, "new context");
- ctx = (mod_chxj_ctx*)apr_palloc(r->pool, sizeof(mod_chxj_ctx));
- if (len > 0) {
- ctx->buffer = apr_palloc(r->pool, len);
- memcpy(ctx->buffer, data, len);
- }
- else {
- ctx->buffer = apr_palloc(r->pool, 1);
- ctx->buffer = '\0';
- }
- ctx->len = len;
- f->ctx = (void*)ctx;
- }
- else {
- /*--------------------------------------------------------------------*/
- /* append data */
- /*--------------------------------------------------------------------*/
- char* tmp;
- DBG(r, "append data start");
- ctx = (mod_chxj_ctx*)f->ctx;
-
- if (len > 0) {
- tmp = apr_palloc(r->pool, ctx->len);
- memcpy(tmp, ctx->buffer, ctx->len);
-
- ctx->buffer = apr_palloc(r->pool, ctx->len + len);
-
- memcpy(ctx->buffer, tmp, ctx->len);
- memcpy(&ctx->buffer[ctx->len], data, len);
- ctx->len += len;
- }
- DBG(r, "append data end");
+ return rv;
}
}
}
return APR_SUCCESS;
}
+
/**
* It is the main loop of the input filter.
*
apr_read_type_e block,
apr_off_t readbytes)
{
- request_rec* r = f->r;
+ request_rec *r;
apr_status_t rv;
- conn_rec* c = r->connection;
- apr_bucket* b;
+ conn_rec *c;
+ apr_bucket *b;
/*--------------------------------------------------------------------------*/
/* It is the brigade area for output */
/*--------------------------------------------------------------------------*/
- apr_bucket_brigade* ibb;
+ apr_bucket_brigade *ibb;
/*--------------------------------------------------------------------------*/
/* It is the brigade area for input */
/*--------------------------------------------------------------------------*/
- apr_bucket_brigade* obb;
+ apr_bucket_brigade *obb;
apr_size_t len;
- apr_bucket* tmp_heap;
- apr_bucket* eos;
- const char* data;
- char* data_bucket;
- char* data_brigade;
- char* content_type;
- device_table* spec ;
- char* user_agent;
- mod_chxj_config* dconf;
- chxjconvrule_entry* entryp;
+ apr_bucket *tmp_heap;
+ apr_bucket *eos;
+ const char *data;
+ char *data_bucket;
+ char *data_brigade;
+ char *content_type;
+ device_table *spec = NULL;
+ char *user_agent = NULL;
+ mod_chxj_config *dconf;
+ chxjconvrule_entry *entryp = NULL;
+ mod_chxj_ctx *ctx = (mod_chxj_ctx *)f->ctx;
+ int eos_flag = 0;
+
+ r = f->r;
+ c = r->connection;
DBG(r, "start of chxj_input_filter()");
content_type = (char*)apr_table_get(r->headers_in, "Content-Type");
if (content_type
- && strncasecmp("multipart/form-data", content_type, 19) == 0) {
+ && strncasecmp("multipart/form-data", content_type, 19) == 0) {
DBG(r, "detect multipart/form-data");
ap_remove_input_filter(f);
}
dconf = ap_get_module_config(r->per_dir_config, &chxj_module);
+ user_agent = (char*)apr_table_get(r->headers_in, "User-Agent");
+
+ if (ctx && ctx->entryp) entryp = ctx->entryp;
+ else entryp = chxj_apply_convrule(r, dconf->convrules);
+
+ if (ctx && ctx->spec) spec = ctx->spec;
+ else spec = chxj_specified_device(r, user_agent);
- entryp = chxj_apply_convrule(r, dconf->convrules);
if (!entryp || !(entryp->action & CONVRULE_ENGINE_ON_BIT)) {
DBG(r,"EngineOff");
return ap_get_brigade(f->next, bb, mode, block, readbytes);
}
- user_agent = (char*)apr_table_get(r->headers_in, "User-Agent");
- spec = chxj_specified_device(r, user_agent);
switch(spec->html_spec_type) {
case CHXJ_SPEC_Chtml_1_0:
DBG(r, "ap_get_brigade() failed");
return rv;
}
+ if (!ctx) {
+ ctx = apr_palloc(r->pool, sizeof(*ctx));
+ memset(ctx, 0, sizeof(*ctx));
+ if ((rv = apr_pool_create(&ctx->pool, r->pool)) != APR_SUCCESS) {
+ ERR(r, "failed: new pool create. rv:[%d]", rv);
+ return rv;
+ }
+ ctx->entryp = entryp;
+ ctx->spec = spec;
+ ctx->buffer = apr_palloc(ctx->pool, 1);
+ ctx->buffer[0] = 0;
+ f->ctx = ctx;
+ }
+
+ for (b = APR_BRIGADE_FIRST(ibb);
+ b != APR_BRIGADE_SENTINEL(ibb);
+ b = APR_BUCKET_NEXT(b)) {
- APR_BRIGADE_FOREACH(b, ibb) {
rv = apr_bucket_read(b, &data, &len, APR_BLOCK_READ);
if (rv != APR_SUCCESS) {
DBG(r, "apr_bucket_read() failed");
}
if (data != NULL) {
- data_bucket = apr_palloc(r->pool, len+1);
+ ctx->len += len;
+ data_bucket = apr_palloc(ctx->pool, len+1);
memset((void*)data_bucket, 0, len+1);
memcpy(data_bucket, data, len);
- DBG1(r, "(in)POSTDATA:[%s]", data_bucket);
-
- data_brigade = apr_pstrcat(r->pool, data_brigade, data_bucket, NULL);
+ DBG(r, "(in)POSTDATA:[%s]", data_bucket);
+ ctx->buffer = apr_pstrcat(ctx->pool, ctx->buffer, data_bucket, NULL);
}
-
if (APR_BUCKET_IS_EOS(b)) {
+ DBG(r, "eos");
+ eos_flag = 1;
break;
}
}
apr_brigade_cleanup(ibb);
-
- len = strlen(data_brigade);
- if (len == 0) {
+ if (ctx->len == 0) {
DBG(r,"data_brigade length is 0");
DBG(r,"end of chxj_input_filter()");
ap_remove_input_filter(f);
return ap_get_brigade(f->next, bb, mode, block, readbytes);
}
- data_brigade = chxj_input_convert(
- r,
- (const char**)&data_brigade,
- (apr_size_t*)&len,
- entryp
- );
-
- if (len > 0) {
- DBG1(r, "(in:exchange)POSTDATA:[%s]", data_brigade);
- obb = apr_brigade_create(r->pool, c->bucket_alloc);
-
- tmp_heap = apr_bucket_heap_create(data_brigade,
- len,
- NULL,
- f->c->bucket_alloc);
- eos = apr_bucket_eos_create(f->c->bucket_alloc);
-
- APR_BRIGADE_INSERT_TAIL(obb, tmp_heap);
- APR_BRIGADE_INSERT_TAIL(obb, eos);
- APR_BRIGADE_CONCAT(bb, obb);
+ if (eos_flag) {
+ len = ctx->len;
+ data_brigade = chxj_input_convert(
+ r,
+ (const char**)&ctx->buffer,
+ (apr_size_t*)&len,
+ entryp
+ );
+
+ if (len > 0) {
+ DBG(r, "(in:exchange)POSTDATA:[%s]", data_brigade);
+
+ obb = apr_brigade_create(r->pool, c->bucket_alloc);
+
+ tmp_heap = apr_bucket_heap_create(data_brigade,
+ len,
+ NULL,
+ f->c->bucket_alloc);
+ eos = apr_bucket_eos_create(f->c->bucket_alloc);
+
+ APR_BRIGADE_INSERT_TAIL(obb, tmp_heap);
+ APR_BRIGADE_INSERT_TAIL(obb, eos);
+ APR_BRIGADE_CONCAT(bb, obb);
+ }
+ else {
+ obb = apr_brigade_create(r->pool, c->bucket_alloc);
+ eos = apr_bucket_eos_create(f->c->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(obb, eos);
+ APR_BRIGADE_CONCAT(bb, obb);
+ }
+ apr_pool_destroy(ctx->pool);
+ f->ctx = NULL;
}
DBG(r, "end of chxj_input_filter()");
return conf;
}
+
/**
* initialize chxj module
*/
static int
chxj_init_module(apr_pool_t *p,
- apr_pool_t *plog,
- apr_pool_t *ptemp,
+ apr_pool_t* UNUSED(plog),
+ apr_pool_t* UNUSED(ptemp),
server_rec *s)
{
+#if 0
mod_chxj_global_config* conf;
+#endif
void *user_data;
SDBG(s, "start chxj_init_module()");
#endif
#endif
-
SDBG(s, "end chxj_init_module()");
return OK;
}
+
static void
-chxj_child_init(apr_pool_t *p, server_rec *s)
+chxj_child_init(apr_pool_t* UNUSED(p), server_rec *s)
{
#if 0
mod_chxj_global_config* conf;
conf = (mod_chxj_global_config*)ap_get_module_config(s->module_config,
&chxj_module);
- if (apr_global_mutex_child_init(&conf->cookie_db_lock, NULL, p)
- != APR_SUCCESS) {
+ if (apr_global_mutex_child_init(&conf->cookie_db_lock, NULL, p) != APR_SUCCESS) {
SERR(s, "Can't attach global mutex.");
return;
}
}
+static void
+chxj_insert_filter(request_rec *r)
+{
+ char* user_agent;
+ device_table* spec;
+ mod_chxj_config* dconf;
+ chxjconvrule_entry* entryp;
+DBG(r, "start chxj_insert_filter()");
+
+ dconf = ap_get_module_config(r->per_dir_config, &chxj_module);
+
+ user_agent = (char*)apr_table_get(r->headers_in, HTTP_USER_AGENT);
+ spec = chxj_specified_device(r, user_agent);
+ entryp = NULL;
+
+ entryp = chxj_apply_convrule(r, dconf->convrules);
+ if (!entryp) {
+ DBG(r, "end chxj_insert_filter()");
+ return;
+ }
+
+ if (entryp->action & CONVRULE_ENGINE_ON_BIT) {
+ ap_add_input_filter("chxj_input_filter", NULL, r, r->connection);
+ ap_add_output_filter("chxj_output_filter", NULL, r, r->connection);
+ }
+
+DBG(r, "end chxj_insert_filter()");
+}
+
+
/**
* The hook is registered.
*
* @param p
*/
static void
-chxj_register_hooks(apr_pool_t *p)
+chxj_register_hooks(apr_pool_t* UNUSED(p))
{
ap_hook_post_config(chxj_init_module,
NULL,
chxj_input_filter,
NULL,
AP_FTYPE_RESOURCE);
+ ap_hook_insert_filter(chxj_insert_filter, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_handler(chxj_img_conv_format_handler, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_handler(chxj_qr_code_handler, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_translate_name(chxj_translate_name, NULL, NULL, APR_HOOK_MIDDLE);
conf->emoji_tail = NULL;
conf->image = CHXJ_IMG_OFF;
conf->image_cache_dir = apr_psprintf(p, "%s",DEFAULT_IMAGE_CACHE_DIR);
+ conf->image_cache_limit = 0;
conf->server_side_encoding = NULL;
+ conf->cookie_db_dir = NULL;
+ conf->cookie_timeout = 0;
+ conf->cookie_store_type = COOKIE_STORE_TYPE_NONE;
+ conf->cookie_lazy_mode = 0;
+#if defined(USE_MYSQL_COOKIE)
+ memset((void*)&conf->mysql, 0, sizeof(mysql_t));
+ conf->mysql.port = MYSQL_PORT;
+ conf->mysql.host = NULL;
+#endif
+#if defined(USE_MEMCACHE_COOKIE)
+ memset((void*)&conf->memcache, 0, sizeof(memcache_t));
+ conf->memcache.host = NULL;
+ conf->memcache.port = 0;
+#endif
+
if (arg == NULL) {
conf->dir = NULL;
}
mrg->image = CHXJ_IMG_OFF;
mrg->image_cache_dir = NULL;
mrg->image_copyright = NULL;
+ mrg->image_cache_limit = 0;
mrg->emoji = NULL;
mrg->emoji_tail = NULL;
mrg->image = add->image;
- if (strcasecmp(add->image_cache_dir ,DEFAULT_IMAGE_CACHE_DIR)==0)
+ if (strcasecmp(add->image_cache_dir ,DEFAULT_IMAGE_CACHE_DIR)==0) {
mrg->image_cache_dir = apr_pstrdup(p, base->image_cache_dir);
- else
+ }
+ else {
mrg->image_cache_dir = apr_pstrdup(p, add->image_cache_dir);
+ }
+
+ if (add->image_cache_limit) {
+ mrg->image_cache_limit = add->image_cache_limit;
+ }
+ else {
+ mrg->image_cache_limit = base->image_cache_limit;
+ }
if (add->image_copyright)
mrg->image_copyright = apr_pstrdup(p, add->image_copyright);
mrg->convrules = apr_array_append(p, add->convrules, base->convrules);
- return mrg;
-}
+ if (add->cookie_db_dir) {
+ mrg->cookie_db_dir = apr_pstrdup(p, add->cookie_db_dir);
+ }
+ else
+ if (base->cookie_db_dir) {
+ mrg->cookie_db_dir = apr_pstrdup(p, base->cookie_db_dir);
+ }
+ else {
+ mrg->cookie_db_dir = NULL;
+ }
+
+ if (add->cookie_timeout) {
+ mrg->cookie_timeout = add->cookie_timeout;
+ }
+ else
+ if (base->cookie_db_dir) {
+ mrg->cookie_timeout = base->cookie_timeout;
+ }
+ else {
+ mrg->cookie_timeout = 0;
+ }
+
+#if defined(USE_MYSQL_COOKIE)
+ if (add->mysql.host) {
+ mrg->mysql.host = apr_pstrdup(p, add->mysql.host);
+ }
+ else if (base->mysql.host) {
+ mrg->mysql.host = apr_pstrdup(p, base->mysql.host);
+ }
+ else {
+ mrg->mysql.host = NULL;
+ }
+ if (add->mysql.port) {
+ mrg->mysql.port = add->mysql.port;
+ }
+ else if (base->mysql.port) {
+ mrg->mysql.port = base->mysql.port;
+ }
+ else {
+ mrg->mysql.port = 0;
+ }
+
+ if (add->mysql.database) {
+ mrg->mysql.database = apr_pstrdup(p, add->mysql.database);
+ }
+ else if (base->mysql.database) {
+ mrg->mysql.database = apr_pstrdup(p, base->mysql.database);
+ }
+ else {
+ mrg->mysql.database = NULL;
+ }
+
+ if (add->mysql.username) {
+ mrg->mysql.username = apr_pstrdup(p, add->mysql.username);
+ }
+ else if (base->mysql.username) {
+ mrg->mysql.username = apr_pstrdup(p, base->mysql.username);
+ }
+ else {
+ mrg->mysql.username = NULL;
+ }
+
+ if (add->mysql.password) {
+ mrg->mysql.password = apr_pstrdup(p, add->mysql.password);
+ }
+ else if (base->mysql.password) {
+ mrg->mysql.password = apr_pstrdup(p, base->mysql.password);
+ }
+ else {
+ mrg->mysql.password = NULL;
+ }
+
+ if (add->mysql.tablename) {
+ mrg->mysql.tablename = apr_pstrdup(p, add->mysql.tablename);
+ }
+ else if (base->mysql.tablename) {
+ mrg->mysql.tablename = apr_pstrdup(p, base->mysql.tablename);
+ }
+ else {
+ mrg->mysql.tablename = NULL;
+ }
+
+ if (add->mysql.socket_path) {
+ mrg->mysql.socket_path = apr_pstrdup(p, add->mysql.socket_path);
+ }
+ else if (base->mysql.socket_path) {
+ mrg->mysql.socket_path = apr_pstrdup(p, base->mysql.socket_path);
+ }
+ else {
+ mrg->mysql.socket_path = NULL;
+ }
+
+ if (add->mysql.charset) {
+ mrg->mysql.charset = apr_pstrdup(p, add->mysql.charset);
+ }
+ else if (base->mysql.charset) {
+ mrg->mysql.charset = apr_pstrdup(p, base->mysql.charset);
+ }
+ else {
+ mrg->mysql.charset = NULL;
+ }
+#endif
+#if defined(USE_MEMCACHE_COOKIE)
+ if (add->memcache.host) {
+ mrg->memcache.host = apr_pstrdup(p, add->memcache.host);
+ }
+ else if (base->memcache.host) {
+ mrg->memcache.host = apr_pstrdup(p, base->memcache.host);
+ }
+ else {
+ mrg->memcache.host = NULL;
+ }
+ if (add->memcache.port) {
+ mrg->memcache.port = add->memcache.port;
+ }
+ else if (base->memcache.port) {
+ mrg->memcache.port = base->memcache.port;
+ }
+ else {
+ mrg->memcache.port = 0;
+ }
+#endif
+ if (add->cookie_store_type) {
+ mrg->cookie_store_type = add->cookie_store_type;
+ }
+ else if (base->cookie_store_type) {
+ mrg->cookie_store_type = base->cookie_store_type;
+ }
+ else {
+ mrg->cookie_store_type = COOKIE_STORE_TYPE_NONE;
+ }
+ if (add->cookie_lazy_mode) {
+ mrg->cookie_lazy_mode = add->cookie_lazy_mode;
+ }
+ else if (base->cookie_lazy_mode) {
+ mrg->cookie_lazy_mode = base->cookie_lazy_mode;
+ }
+ else {
+ mrg->cookie_lazy_mode = 0;
+ }
+ return mrg;
+}
static int
doc.r = NULL;
if (strlen(arg) > 256)
- return "device data filename too long.";
+ return "mod_chxj: device data filename too long.";
conf = (mod_chxj_config*)mconfig;
conf->device_data_file = apr_pstrdup(parms->pool, arg);
if (strlen(arg) > 256)
- return "emoji data filename too long.";
+ return "mod_chxj: emoji data filename too long.";
conf = (mod_chxj_config*)mconfig;
conf->emoji_data_file = apr_pstrdup(parms->pool, arg);
static const char*
-cmd_set_image_engine(cmd_parms *parms, void *mconfig, const char* arg)
+cmd_set_image_engine(cmd_parms* UNUSED(parms), void *mconfig, const char* arg)
{
mod_chxj_config* conf;
Doc doc;
static const char*
+cmd_set_image_cache_limit(cmd_parms *parms, void *mconfig, const char* arg)
+{
+ mod_chxj_config* conf;
+ Doc doc;
+
+ doc.r = NULL;
+
+ if (strlen(arg) > IMAGE_CACHE_LIMIT_FMT_LEN)
+ return "cache size is too long.";
+
+ conf = (mod_chxj_config*)mconfig;
+ errno = 0;
+ /*
+ * I use strtol function because strtoul is not portable function.
+ */
+ conf->image_cache_limit = (unsigned long)strtol(arg, NULL, 10);
+ switch (errno) {
+ case EINVAL:
+ return apr_psprintf(parms->pool, "ChxjImageCacheLimit invalid value [%s] errno:[%d]", arg, errno);
+ case ERANGE:
+ return apr_psprintf(parms->pool, "ChxjImageCacheLimit Out of range [%s] errno:[%d]", arg, errno);
+ default:
+ break;
+ }
+ return NULL;
+}
+
+
+static const char*
cmd_set_image_copyright(cmd_parms *parms, void* mconfig, const char* arg)
{
mod_chxj_config* conf;
- Doc doc;
+ Doc doc;
doc.r = NULL;
+
if (strlen(arg) > 256)
return "Copyright Flag is too long.";
return NULL;
}
+
static const char*
cmd_convert_rule(cmd_parms *cmd, void* mconfig, const char *arg)
{
- mod_chxj_config* dconf;
- char* prm1;
- char* prm2;
- char* prm3;
- char* prm4;
- char* prm5;
- int mode;
- char* pstate;
- char* action;
- char* pp;
- ap_regex_t *regexp;
+ int mode;
+ ap_regex_t* regexp;
+ mod_chxj_config* dconf;
chxjconvrule_entry* newrule;
+ char* prm1;
+ char* prm2;
+ char* prm3;
+ char* prm4;
+ char* prm5;
+ char* pstate;
+ char* action;
+ char* pp;
dconf = (mod_chxj_config*)mconfig;
if (strlen(arg) > 4096)
- return "ChxjConvertRule: is too long.";
+ return "mod_chxj: ChxjConvertRule: is too long.";
dconf = (mod_chxj_config*)mconfig;
if (dconf->convrules == NULL)
- dconf->convrules = apr_array_make(cmd->pool, 2, sizeof(chxjconvrule_entry));
-
+ dconf->convrules = apr_array_make(cmd->pool,
+ 2,
+ sizeof(chxjconvrule_entry));
newrule = apr_array_push(dconf->convrules);
newrule->action |= CONVRULE_COOKIE_ON_BIT;
}
break;
-
default:
break;
}
}
mode = AP_REG_EXTENDED;
- if ((regexp = ap_pregcomp(cmd->pool, pp, mode)) == NULL) {
+ if ((regexp = ap_pregcomp((apr_pool_t *)cmd->pool, (const char *)pp, mode)) == NULL)
return "RewriteRule: cannot compile regular expression ";
- }
newrule->regexp = regexp;
if (*prm3)
}
+static const char*
+cmd_set_cookie_dir(
+ cmd_parms* cmd,
+ void* mconfig,
+ const char* arg)
+{
+ mod_chxj_config* dconf;
+
+
+ if (strlen(arg) > 4096)
+ return "mod_chxj: ChxjCookieDir is too long.";
+
+ dconf = (mod_chxj_config*)mconfig;
+
+ dconf->cookie_db_dir = apr_pstrdup(cmd->pool, arg);
+
+ return NULL;
+}
+
+
+static const char*
+cmd_set_cookie_timeout(
+ cmd_parms* UNUSED(cmd),
+ void* mconfig,
+ const char* arg)
+{
+ mod_chxj_config* dconf;
+
+
+ if (strlen(arg) > 4096)
+ return "mod_chxj: ChxjCookieTimeout is too long.";
+
+ if (chxj_chk_numeric(arg) != 0)
+ return "mod_chxj: ChxjCookieTimeout is not numeric.";
+
+ dconf = (mod_chxj_config*)mconfig;
+
+ dconf->cookie_timeout = atoi(arg);
+
+ return NULL;
+}
+
+
+#if defined(USE_MYSQL_COOKIE)
+static const char *
+cmd_set_cookie_mysql_database(
+ cmd_parms *cmd,
+ void *mconfig,
+ const char *arg)
+{
+ mod_chxj_config *dconf;
+
+ if (strlen(arg) > 255)
+ return "mod_chxj: ChxjCookieMysqlDatabase is too long.";
+
+ dconf = (mod_chxj_config *)mconfig;
+
+ dconf->mysql.database = apr_pstrdup(cmd->pool, arg);
+
+ return NULL;
+}
+
+
+static const char *
+cmd_set_cookie_mysql_username(
+ cmd_parms *cmd,
+ void *mconfig,
+ const char *arg)
+{
+ mod_chxj_config *dconf;
+
+ if (strlen(arg) > 255)
+ return "mod_chxj: ChxjCookieMysqlUsername is too long.";
+
+ dconf = (mod_chxj_config *)mconfig;
+
+ dconf->mysql.username = apr_pstrdup(cmd->pool, arg);
+
+ return NULL;
+}
+
+
+static const char *
+cmd_set_cookie_mysql_password(
+ cmd_parms *cmd,
+ void *mconfig,
+ const char *arg)
+{
+ mod_chxj_config *dconf;
+
+ if (strlen(arg) > 255)
+ return "mod_chxj: ChxjCookieMysqlPassword is too long.";
+
+ dconf = (mod_chxj_config *)mconfig;
+
+ dconf->mysql.password = apr_pstrdup(cmd->pool, arg);
+
+ return NULL;
+}
+
+
+static const char *
+cmd_set_cookie_mysql_table_name(
+ cmd_parms *cmd,
+ void *mconfig,
+ const char *arg)
+{
+ mod_chxj_config *dconf;
+
+ if (strlen(arg) > 255)
+ return "mod_chxj: ChxjCookieMysqlTableName is too long.";
+
+ dconf = (mod_chxj_config *)mconfig;
+
+ dconf->mysql.tablename = apr_pstrdup(cmd->pool, arg);
+
+ return NULL;
+}
+
+static const char *
+cmd_set_cookie_mysql_port(
+ cmd_parms *UNUSED(cmd),
+ void *mconfig,
+ const char *arg)
+{
+ mod_chxj_config *dconf;
+
+ if (strlen(arg) > 255)
+ return "mod_chxj: ChxjCookieMysqlPort is too long.";
+
+ dconf = (mod_chxj_config *)mconfig;
+
+ if (chxj_chk_numeric(arg) != 0)
+ return "mod_chxj: ChxjCookieMysqlPort is not numeric.";
+
+ dconf = (mod_chxj_config *)mconfig;
+
+ dconf->mysql.port = chxj_atoi(arg);
+
+ return NULL;
+}
+
+
+static const char *
+cmd_set_cookie_mysql_host(
+ cmd_parms *cmd,
+ void *mconfig,
+ const char *arg)
+{
+ mod_chxj_config *dconf;
+
+ if (strlen(arg) > 255)
+ return "mod_chxj: ChxjCookieMysqlHost is too long.";
+
+ dconf = (mod_chxj_config *)mconfig;
+
+ dconf->mysql.host = apr_pstrdup(cmd->pool, arg);
+
+ return NULL;
+}
+
+
+static const char *
+cmd_set_cookie_mysql_socket_path(
+ cmd_parms *cmd,
+ void *mconfig,
+ const char *arg)
+{
+ mod_chxj_config *dconf;
+
+ if (strlen(arg) > 4096)
+ return "mod_chxj: ChxjCookieMysqlSocketPath is too long.";
+
+ dconf = (mod_chxj_config *)mconfig;
+
+ dconf->mysql.socket_path = apr_pstrdup(cmd->pool, arg);
+
+ return NULL;
+}
+
+
+static const char *
+cmd_set_cookie_mysql_charset(
+ cmd_parms *cmd,
+ void *mconfig,
+ const char *arg)
+{
+ mod_chxj_config *dconf;
+
+ if (strlen(arg) > 255)
+ return "mod_chxj: ChxjCookieMysqlCharset is too long.";
+
+ dconf = (mod_chxj_config *)mconfig;
+
+ dconf->mysql.charset = apr_pstrdup(cmd->pool, arg);
+
+ return NULL;
+}
+#endif
+#if defined(USE_MEMCACHE_COOKIE)
+static const char *
+cmd_set_cookie_memcache_port(
+ cmd_parms *UNUSED(cmd),
+ void *mconfig,
+ const char *arg)
+{
+ mod_chxj_config *dconf;
+
+ if (strlen(arg) > 255)
+ return "mod_chxj: ChxjCookieMemcachePort is too long.";
+
+ dconf = (mod_chxj_config *)mconfig;
+
+ if (chxj_chk_numeric(arg) != 0)
+ return "mod_chxj: ChxjCookieMemcachePort is not numeric.";
+
+ dconf = (mod_chxj_config *)mconfig;
+
+ dconf->memcache.port = (apr_port_t)chxj_atoi(arg);
+
+ return NULL;
+}
+
+
+static const char *
+cmd_set_cookie_memcache_host(
+ cmd_parms *cmd,
+ void *mconfig,
+ const char *arg)
+{
+ mod_chxj_config *dconf;
+
+ if (strlen(arg) > 255)
+ return "mod_chxj: ChxjCookieMemcacheHost is too long.";
+
+ dconf = (mod_chxj_config *)mconfig;
+
+ dconf->memcache.host = apr_pstrdup(cmd->pool, arg);
+
+ return NULL;
+}
+#endif
+
+static const char *
+cmd_set_cookie_lazy_mode(
+ cmd_parms *UNUSED(cmd),
+ void *mconfig,
+ const char *arg)
+{
+ mod_chxj_config *dconf;
+
+ if (strlen(arg) > 255)
+ return "mod_chxj: ChxjCookieLazyMode is too long.";
+
+ dconf = (mod_chxj_config *)mconfig;
+
+ if (strcasecmp("TRUE",arg) == 0) {
+ dconf->cookie_lazy_mode = COOKIE_LAZY_ON;
+ }
+ else {
+ dconf->cookie_lazy_mode = COOKIE_LAZY_OFF;
+ }
+
+ return NULL;
+}
+
+static const char *
+cmd_set_cookie_store_type(
+ cmd_parms *UNUSED(cmd),
+ void *mconfig,
+ const char *arg)
+{
+ mod_chxj_config *dconf;
+
+ if (strlen(arg) > 255)
+ return "mod_chxj: ChxjCookieStoreType is too long.";
+
+ dconf = (mod_chxj_config *)mconfig;
+
+ if (strcasecmp(CHXJ_COOKIE_STORE_TYPE_DBM, arg) == 0) {
+ dconf->cookie_store_type = COOKIE_STORE_TYPE_DBM;
+ }
+ else if (strcasecmp(CHXJ_COOKIE_STORE_TYPE_MYSQL, arg) == 0) {
+ dconf->cookie_store_type = COOKIE_STORE_TYPE_MYSQL;
+ }
+ else if (strcasecmp(CHXJ_COOKIE_STORE_TYPE_MEMCACHE, arg) == 0) {
+ dconf->cookie_store_type = COOKIE_STORE_TYPE_MEMCACHE;
+ }
+ else {
+ dconf->cookie_store_type = COOKIE_STORE_TYPE_NONE;
+ }
+
+ return NULL;
+}
+
+
+
static const command_rec cmds[] = {
AP_INIT_TAKE1(
"ChxjLoadDeviceData",
OR_ALL,
"Image Cache Directory"),
AP_INIT_TAKE1(
+ "ChxjImageCacheLimit",
+ cmd_set_image_cache_limit,
+ NULL,
+ OR_ALL,
+ "Image Cache Limit"),
+ AP_INIT_TAKE1(
"ChxjImageCopyright",
cmd_set_image_copyright,
NULL,
NULL,
OR_FILEINFO,
"an URL-applied regexp-pattern and a substitution URL"),
- { NULL },
+ AP_INIT_TAKE1(
+ "ChxjCookieDir",
+ cmd_set_cookie_dir,
+ NULL,
+ OR_ALL,
+ "save cookie.db directory."),
+ AP_INIT_TAKE1(
+ "ChxjCookieTimeout",
+ cmd_set_cookie_timeout,
+ NULL,
+ OR_ALL,
+ "The compulsion time-out time of the cookie is specified. "),
+ AP_INIT_TAKE1(
+ "ChxjCookieStoreType",
+ cmd_set_cookie_store_type,
+ NULL,
+ OR_ALL,
+ "It specifies preserving of the cookie ahead. (DBM/MYSQL/MEMCACHE)"),
+ AP_INIT_TAKE1(
+ "ChxjCookieLazyMode",
+ cmd_set_cookie_lazy_mode,
+ NULL,
+ OR_ALL,
+ "OneTimeID is negligently done. (TRUE/FALSE)"),
+#if defined(USE_MYSQL_COOKIE)
+ AP_INIT_TAKE1(
+ "ChxjCookieMysqlHost",
+ cmd_set_cookie_mysql_host,
+ NULL,
+ OR_ALL,
+ "The MySQL database host used by saving Cookie"),
+ AP_INIT_TAKE1(
+ "ChxjCookieMysqlPort",
+ cmd_set_cookie_mysql_port,
+ NULL,
+ OR_ALL,
+ "The MySQL database port used by saving Cookie"),
+ AP_INIT_TAKE1(
+ "ChxjCookieMysqlDatabase",
+ cmd_set_cookie_mysql_database,
+ NULL,
+ OR_ALL,
+ "The MySQL database name used by saving Cookie"),
+ AP_INIT_TAKE1(
+ "ChxjCookieMysqlUsername",
+ cmd_set_cookie_mysql_username,
+ NULL,
+ OR_ALL,
+ "The MySQL username used by saving Cookie"),
+ AP_INIT_TAKE1(
+ "ChxjCookieMysqlPassword",
+ cmd_set_cookie_mysql_password,
+ NULL,
+ OR_ALL,
+ "The MySQL password used by saving Cookie"),
+ AP_INIT_TAKE1(
+ "ChxjCookieMysqlTableName",
+ cmd_set_cookie_mysql_table_name,
+ NULL,
+ OR_ALL,
+ "The MySQL table name used by saving Cookie"),
+ AP_INIT_TAKE1(
+ "ChxjCookieMysqlSocketPath",
+ cmd_set_cookie_mysql_socket_path,
+ NULL,
+ OR_ALL,
+ "The MySQL socket path used by saving Cookie"),
+ AP_INIT_TAKE1(
+ "ChxjCookieMysqlCharset",
+ cmd_set_cookie_mysql_charset,
+ NULL,
+ OR_ALL,
+ "The MySQL charset used by saving Cookie"),
+#endif
+#if defined(USE_MEMCACHE_COOKIE)
+ AP_INIT_TAKE1(
+ "ChxjCookieMemcacheHost",
+ cmd_set_cookie_memcache_host,
+ NULL,
+ OR_ALL,
+ "The Memcached host used by saving Cookie"),
+ AP_INIT_TAKE1(
+ "ChxjCookieMemcachePort",
+ cmd_set_cookie_memcache_port,
+ NULL,
+ OR_ALL,
+ "The Memcached port used by saving Cookie"),
+#endif
+ {NULL}
};
/*----------------------------------------------------------------------------*/
/* Dispatch list for API hooks */
/*----------------------------------------------------------------------------*/
-module AP_MODULE_DECLARE_DATA chxj_module =
-{
+module AP_MODULE_DECLARE_DATA chxj_module = {
STANDARD20_MODULE_STUFF,
chxj_create_per_dir_config, /* create per-dir config structures */
chxj_merge_per_dir_config, /* merge per-dir config structures */