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.
18 #include "chxj_encoding.h"
19 #include "chxj_apply_convrule.h"
20 #include "chxj_url_encode.h"
23 #if defined(HAVE_LIBICONV_HOOK)
24 # include "iconv_hook/iconv.h"
26 # if defined(HAVE_LIBICONV)
29 # error "Please install libiconv or libiconv_hook. and Please set LD_LIBRARY_PATH."
43 const char *from_code,
47 chxj_encoding(request_rec *r, const char *src, apr_size_t *len)
55 mod_chxj_config *dconf;
56 chxjconvrule_entry *entryp;
59 DBG(r,"start chxj_encoding() len=[%d] input[%.*s]", (int)*len, (int)*len, src);
61 dconf = ap_get_module_config(r->per_dir_config, &chxj_module);
63 DBG(r,"none encoding.");
67 entryp = chxj_apply_convrule(r, dconf->convrules);
68 if (entryp->encoding == NULL) {
69 DBG(r,"none encoding.");
73 if ((*(entryp->encoding) == 'n' || *(entryp->encoding) == 'N')
74 && strcasecmp(entryp->encoding, "NONE") == 0) {
75 DBG(r,"none encoding.");
79 ibuf = apr_palloc(r->pool, ilen+1);
81 DBG(r,"end chxj_encoding()");
84 memset(ibuf, 0, ilen+1);
85 memcpy(ibuf, src, ilen);
88 spos = obuf = apr_palloc(r->pool, olen);
90 DBG(r,"memory allocation failure. end chxj_encoding()");
94 memset(obuf, 0, olen);
96 if (IS_EUCJP_STRING(entryp->encoding)) {
97 DBG(r,"try encode convert [%s] -> [%s]",
98 "EUCJP-WIN", MOD_CHXJ_INTERNAL_ENCODING);
105 MOD_CHXJ_INTERNAL_ENCODING);
106 DBG(r, "rtn:[%s]", rtn);
109 DBG(r,"encode convert [%s] -> [%s]",
110 entryp->encoding,MOD_CHXJ_INTERNAL_ENCODING);
117 MOD_CHXJ_INTERNAL_ENCODING);
120 ERR(r, "error: convert charactor encoding failure.[%s]", ibuf);
124 DBG(r,"end chxj_encoding() len=[%d] obuf=[%.*s]", (int)*len, (int)*len, spos);
125 DBG(r,"end chxj_encoding() obuf=[%s]", spos);
131 chxj_encoding_by_spec(
144 DBG(r,"start chxj_encoding_by_spec() len=[%d] input[%.*s]", (int)*len, (int)*len, src);
147 ibuf = apr_palloc(r->pool, ilen+1);
149 ERR(r, "%s:%d allocation error: not enough memory", __FILE__,__LINE__);
152 memset(ibuf, 0, ilen+1);
153 memcpy(ibuf, src, ilen);
156 obuf = apr_palloc(r->pool, olen);
158 ERR(r, "%s:%d allocation error: not enough memory", __FILE__,__LINE__);
162 memset(obuf, 0, (int)olen);
163 rtn = do_encoding(r, &ibuf, &ilen, &obuf, &olen, MOD_CHXJ_INTERNAL_ENCODING, spec->charset);
165 ERR(r, "%s:%d error: convert charactor encoding failure.[%s]",__FILE__,__LINE__,ibuf);
169 DBG(r,"end chxj_encoding() len=[%d] obuf=[%.*s]", (int)*len, (int)*len, rtn);
175 chxj_convert_encoding(
177 const char *from_encoding,
178 const char *to_encoding,
189 DBG(r,"start chxj_convert_encoding() From:[%s] To:[%s] len=[%d] input[%.*s]", from_encoding, to_encoding, (int)*len, (int)*len, src);
192 ibuf = apr_palloc(r->pool, ilen+1);
194 ERR(r, "%s:%d allocation error: not enough memory", __FILE__,__LINE__);
197 memset(ibuf, 0, ilen+1);
198 memcpy(ibuf, src, ilen);
201 obuf = apr_palloc(r->pool, olen);
203 ERR(r, "%s:%d allocation error: not enough memory", __FILE__,__LINE__);
207 memset(obuf, 0, (int)olen);
208 rtn = do_encoding(r, &ibuf, &ilen, &obuf, &olen, from_encoding, to_encoding);
210 ERR(r, "%s:%d error: convert charactor encoding failure.[%s]",__FILE__,__LINE__,ibuf);
214 DBG(r,"end chxj_convert_encoding() len=[%d] obuf=[%.*s]", (int)*len, (int)*len, rtn);
226 const char *from_code,
236 DBG(r,"start do_encoding() from:[%s] --> to:[%s]", from_code, to_code);
237 if ( (IS_SJIS_STRING(from_code) && IS_SJIS_STRING(to_code))
238 || (IS_EUCJP_STRING(from_code) && IS_EUCJP_STRING(to_code))
239 || (IS_UTF8_STRING(from_code) && IS_UTF8_STRING(to_code))) {
240 memcpy(*obuf, *ibuf, *ilenp);
247 if (IS_EUCJP_STRING(from_code)) {
248 fp = apr_pstrdup(r->pool, "EUCJP-WIN");
250 else if (IS_SJIS_STRING(from_code)) {
251 fp = apr_pstrdup(r->pool, "CP932");
253 else if (IS_UTF8_STRING(from_code)) {
254 fp = apr_pstrdup(r->pool, "UTF-8");
257 fp = apr_pstrdup(r->pool, "CP932");
260 if (IS_EUCJP_STRING(to_code)) {
261 tp = apr_pstrdup(r->pool, "EUCJP-WIN");
263 else if (IS_SJIS_STRING(to_code)) {
264 tp = apr_pstrdup(r->pool, "CP932");
266 else if (IS_UTF8_STRING(to_code)) {
267 tp = apr_pstrdup(r->pool, "UTF-8");
270 tp = apr_pstrdup(r->pool, "CP932");
274 memset(*obuf, 0, olen);
276 cd = iconv_open(tp, fp);
277 if (cd == (iconv_t)-1) {
278 ERR(r, "try iconv_open failure. cd:[%d] to:[%s] from:[%s]", (int)cd, tp, fp);
279 cd = iconv_open(to_code, from_code);
280 if (cd == (iconv_t)-1) {
281 ERR(r, "iconv_open failure. cd:[%d] to:[%s] from:[%s]", (int)cd, to_code, from_code);
287 result = iconv(cd, ibuf, &ilen, obuf, &olen);
288 if (result == (size_t)(-1)) {
289 if (errno == E2BIG) {
290 ERR(r, "outbuf is not an enough size. ");
293 else if (errno == EILSEQ) {
294 ERR(r, "%s:%d invalid multi byte character string to the input. [%.2s]", APLOG_MARK, *ibuf);
297 else if (errno == EINVAL) {
298 ERR(r, "Imperfect character string in the input.");
305 *olenp = strlen(spos);
306 DBG(r, "end do_encoding() from:[%s] --> to:[%s] spos:[%s]", from_code, to_code, spos);
325 mod_chxj_config *dconf;
326 chxjconvrule_entry *entryp;
328 DBG(r,"start chxj_rencoding() input:[%s] len:[%d]", src, *len);
330 dconf = ap_get_module_config(r->per_dir_config, &chxj_module);
332 DBG(r,"none encoding.");
333 DBG(r,"end chxj_rencoding()");
337 entryp = chxj_apply_convrule(r, dconf->convrules);
338 if (! entryp->encoding) {
339 DBG(r,"none encoding.");
340 DBG(r,"end chxj_rencoding()");
344 if (STRCASEEQ('n','N', "none", entryp->encoding)) {
345 DBG(r,"none encoding.");
346 DBG(r,"end chxj_rencoding() no convert.");
347 return (char*)apr_pstrdup(r->pool, src);
351 ibuf = apr_palloc(r->pool, ilen+1);
353 DBG(r,"end chxj_rencoding()");
354 ERR(r,"memory allocation error.");
358 memset(ibuf, 0, ilen+1);
359 memcpy(ibuf, src, ilen+0);
362 spos = obuf = apr_palloc(r->pool, olen);
364 DBG(r,"end chxj_rencoding()");
365 ERR(r,"memory allocation error.");
368 DBG(r,"encode convert [%s] -> [%s]", MOD_CHXJ_INTERNAL_ENCODING, entryp->encoding);
370 memset(obuf, 0, olen);
372 cd = iconv_open(entryp->encoding, MOD_CHXJ_INTERNAL_ENCODING);
373 if (cd == (iconv_t)-1) {
374 DBG(r,"end chxj_rencoding()");
379 result = iconv(cd, &ibuf, &ilen, &obuf, &olen);
380 if (result == (size_t)(-1)) {
381 if (errno == E2BIG) {
382 ERR(r, "outbuf is not an enough size. ");
385 else if (errno == EILSEQ) {
386 ERR(r, "%s:%d invalid multi byte character string to the input. [%s]", APLOG_MARK, ibuf);
389 else if (errno == EINVAL) {
390 ERR(r, "Imperfect character string in the input.");
399 DBG(r,"end chxj_rencoding() len=[%d] obuf=[%.*s]", (int)*len, (int)*len, spos);
406 chxj_encoding_parameter(request_rec *r, const char *value)
420 DBG(r, "start chxj_encoding_parameter()");
422 src = apr_pstrdup(r->pool, value);
424 spos = strchr(src, '?');
426 DBG(r, "end chxj_encoding_parameter()");
431 src_sv = apr_pstrdup(r->pool, src);
432 param = apr_palloc(r->pool, 1);
440 pair = apr_strtok(spos, "&", &pstat);
443 if (strncasecmp(pair, "amp;", 4) == 0) {
447 key = apr_strtok(pair, "=", &vstat);
448 val = apr_strtok(NULL, "=", &vstat);
450 val = chxj_url_decode(r, val);
451 len = (apr_size_t)strlen(val);
452 val = chxj_encoding(r, val, &len);
453 val = chxj_url_encode(r, val);
454 if (strlen(param) == 0) {
455 param = apr_pstrcat(r->pool, param, key, "=", val, NULL);
459 param = apr_pstrcat(r->pool, param, "&", key, "=", val, NULL);
462 param = apr_pstrcat(r->pool, param, "&", key, "=", val, NULL);
467 if (strlen(param) == 0) {
468 param = apr_pstrcat(r->pool, param, key, NULL);
472 param = apr_pstrcat(r->pool, param, "&", key, NULL);
475 param = apr_pstrcat(r->pool, param, "&", key, NULL);
480 DBG(r, "end chxj_encoding_parameter()");
482 return apr_pstrcat(r->pool, src_sv, "?", param, NULL);