OSDN Git Service

Merge branch 'branch_0.12.0'
[modchxj/mod_chxj.git] / src / chxj_tag_util.c
1 /*
2  * Copyright (C) 2005-2009 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 #include "chxj_tag_util.h"
18 #include "chxj_url_encode.h"
19 #include "chxj_str_util.h"
20 #include "chxj_jreserved_tag.h"
21
22
23 /**
24  * The value of the VALUE attribute that the object tag node maintains is
25  * acquired.
26  *
27  * @param doc  [i] The pointer to the Doc structure to be scanned is
28  *                 specified.
29  * @param node [i] The tag node to be scanned is specified.
30  * @param pool [i] To use POOL.
31  * @return The value of the VALUE attribute that the object tag node maintains
32  *         is returned. NULL is returned when not found.
33  */
34 char *
35 qs_get_value_attr(Doc *doc, Node *node, apr_pool_t *pool)
36 {
37   Attr *attr;
38
39   /*--------------------------------------------------------------------------*/
40   /* The object tag node is scanned.                                          */
41   /*--------------------------------------------------------------------------*/
42   for (attr = qs_get_attr(doc,node);
43        attr;
44        attr = qs_get_next_attr(doc,attr)) {
45     char *name  = qs_get_attr_name(doc,attr);
46     char *value = qs_get_attr_value(doc,attr);
47     if (STRCASEEQ('v','V',"value",name)) {
48       /*----------------------------------------------------------------------*/
49       /* The VALUE attribute was found.                                       */
50       /*----------------------------------------------------------------------*/
51       return apr_pstrdup(pool, value);
52     }
53   }
54   /*--------------------------------------------------------------------------*/
55   /* not found                                                                */
56   /*--------------------------------------------------------------------------*/
57   return NULL;
58 }
59
60
61 /**
62  * The value of the checked tag is acquired.
63  *
64  * @param doc  [i] The pointer to the Doc structure to be scanned is
65  *                 specified.
66  * @param tag  [i] The tag node to be scanned is specified.
67  * @param pool [i] To use POOL(unused).
68  * @return The value of the checked tag is returned. NULL is returned when
69  *         not found.
70  */
71 char *
72 qs_get_checked_attr(Doc *doc, Node *tag, apr_pool_t *UNUSED(pool))
73 {
74   Attr *attr;
75   /*--------------------------------------------------------------------------*/
76   /* The object tag node is scanned.                                          */
77   /*--------------------------------------------------------------------------*/
78   for (attr = qs_get_attr(doc,tag);
79        attr != NULL;
80        attr = qs_get_next_attr(doc,attr)) {
81     char *name  = qs_get_attr_name(doc,attr);
82     if (STRCASEEQ('c','C',"checked",name)) {
83       /*----------------------------------------------------------------------*/
84       /* The VALUE attribute was found.                                       */
85       /*----------------------------------------------------------------------*/
86       return name;
87     }
88   }
89   /*------------------------------------------------------------------------*/
90   /* not found                                                              */
91   /*------------------------------------------------------------------------*/
92   return NULL;
93 }
94
95
96 /**
97  * The value of the type attribute is acquired.
98  *
99  * @param doc  [i] The pointer to the Doc structure to be scanned is
100  *                 specified.
101  * @param tag  [i] The tag node to be scanned is specified.
102  * @param r    [i] To use POOL, the pointer to request_rec is specified.
103  * @return The value of the type attribute is returned. NULL is returned when
104  *         not found.
105  */
106 char *
107 qs_get_type_attr(Doc *doc, Node *tag, apr_pool_t *pool)
108 {
109   Attr *attr;
110   /*--------------------------------------------------------------------------*/
111   /* The object tag node is scanned.                                          */
112   /*--------------------------------------------------------------------------*/
113   for (attr = qs_get_attr(doc,tag);
114        attr != NULL;
115        attr = qs_get_next_attr(doc,attr)) {
116     char *name  = qs_get_attr_name(doc,attr);
117     char *value = qs_get_attr_value(doc,attr);
118     if (STRCASEEQ('t','T',"type",name)) {
119       /*----------------------------------------------------------------------*/
120       /* The VALUE attribute was found.                                       */
121       /*----------------------------------------------------------------------*/
122       return apr_pstrdup(pool, value);
123     }
124   }
125   /*--------------------------------------------------------------------------*/
126   /* not found                                                                */
127   /*--------------------------------------------------------------------------*/
128   return NULL;
129 }
130
131
132 /**
133  * The character string area in 0 bytes is allocated.
134  *
135  * @param pool    [i]   To use POOL.
136  * @return The allocated 0 byte character string is returned.
137  */
138 char *
139 qs_alloc_zero_byte_string(apr_pool_t *pool)
140 {
141   char *tgt;
142
143   if (! pool) {
144     return NULL;
145   }
146   tgt = apr_palloc(pool, 1);
147   tgt[0] = '\0';
148
149   return tgt;
150 }
151
152
153 /**
154  * A consecutive head and the last WHITESPACE are removed.
155  *
156  * @param p    [i]   To use POOL
157  * @param s    [i]   The character string that should be removed is specified.
158  * @return The character string that has been removed is returned.
159  */
160 char *
161 qs_trim_string(apr_pool_t *p, char *s)
162 {
163   char *ss;
164   int len;
165   int ii;
166
167   if (! s) return apr_pstrdup(p, "");
168
169   ss = apr_pstrdup(p, s);
170   len = strlen(s);
171   ii = 0;
172   for (ii = 0;is_white_space(*ss) && ii < len; ss++, ii++);
173
174   ii = strlen(ss);
175   for(;is_white_space(ss[ii-1]) && ii > 0; ii--);
176
177   ss[ii] = '\0';
178
179   return ss;
180 }
181
182
183 /**
184  * The value of child TEXT of tag that maintains the SELECTED attribute is 
185  * returned. 
186  *
187  * @param Doc  [i] The pointer to the Doc structure to be scanned is 
188  *                 specified. 
189  * @param node [i] The tag node to be scanned is specified.
190  * @param pool [i] To use POOL.
191  * @reutrn  The value of child TEXT of tag that maintains the SELECTED 
192  *          attribute is returned. NULL is returned when not found. 
193  */
194 char *
195 qs_get_selected_value_text(Doc *doc, Node *node, apr_pool_t *pool)
196 {
197   Node *child;
198   Node *selchild;
199   char *result   = NULL;
200
201   for (child = qs_get_child_node(doc,node);
202        child != NULL; 
203        child = qs_get_next_node(doc,child)) {
204     char *name = qs_get_node_name(doc,child);
205     /*------------------------------------------------------------------------*/
206     /* <OPTION> tag                                                           */
207     /*------------------------------------------------------------------------*/
208     if (STRCASEEQ('o','O',"option",name)) {
209       Attr *attr;
210       for (attr =  qs_get_attr(doc,child); 
211            attr != NULL; 
212            attr = qs_get_next_attr(doc,attr)) {
213         char *name2  = qs_get_attr_name(doc,attr);
214         if (STRCASEEQ('s','S',"selected",name2)) {
215           /*------------------------------------------------------------------*/
216           /* SELECTED Value Found                                             */
217           /*------------------------------------------------------------------*/
218           selchild = qs_get_child_node(doc, child);
219           if (! selchild) {
220             /* void value */
221             return apr_pstrdup(pool, "");
222           }
223           return qs_get_node_value(doc, selchild);
224         }
225       }
226     }
227
228     if ((result = qs_get_selected_value_text(doc, child, pool)) != NULL) {
229       return result;
230     }
231   }
232
233   /*--------------------------------------------------------------------------*/
234   /* not found                                                                */
235   /*--------------------------------------------------------------------------*/
236   return NULL;
237 }
238
239
240 /**
241  * The value of tag that maintains the SELECTED attribute is acquired. 
242  *
243  * @param doc    [i]  The pointer to the Doc structure to be scanned is 
244  *                    specified. 
245  * @param node   [i]  The SELECT tag node is specified.
246  * @param pool   [i] To use POOL.
247  * @return The value of tag that maintains the SELECTED attribute is 
248  *         returned. NULL is returned when not found. 
249  */
250 char *
251 qs_get_selected_value(Doc *doc, Node *node, apr_pool_t *pool)
252 {
253   Node *child;
254   char *result    = NULL;
255
256   for (child = qs_get_child_node(doc,node); 
257        child != NULL; 
258        child = qs_get_next_node(doc,child)) {
259     char *name = qs_get_node_name(doc,child);
260     /*------------------------------------------------------------------------*/
261     /* <OPTION> tag                                                           */
262     /*------------------------------------------------------------------------*/
263     if (STRCASEEQ('o','O',"option",name)) {
264       Attr *attr;
265       for (attr = qs_get_attr(doc,child); 
266            attr; 
267            attr = qs_get_next_attr(doc,attr)) {
268         char *name2  = qs_get_attr_name(doc,attr);
269         if (STRCASEEQ('s','S',"selected",name2)) {
270           /*------------------------------------------------------------------*/
271           /* SELECTED Value Found                                             */
272           /*------------------------------------------------------------------*/
273           return qs_get_value_attr(doc, child, doc->buf.pool);
274         }
275       }
276     }
277
278     if ((result = qs_get_selected_value(doc, child, pool)) != NULL) {
279       return result;
280     }
281   }
282
283   /*--------------------------------------------------------------------------*/
284   /* not found                                                                */
285   /*--------------------------------------------------------------------------*/
286   return NULL;
287 }
288
289
290 /**
291  * The value of the NAME attribute is acquired.
292  *
293  * @param doc  [i] The pointer to the Doc structure at the output
294  *                 destination is specified.
295  * @param tag  [i] The tag node to want to acquire the SIZE attribute
296  *                 is specified.
297  * @param pool [i] To use POOL.
298  * @return The value of the NAME attribute is returned. NULL is
299  *         returned when not is.
300  */
301 char *
302 qs_get_name_attr(Doc *doc, Node *tag, apr_pool_t *pool)
303 {
304   Attr *attr;
305   for (attr = qs_get_attr(doc,tag); 
306        attr; 
307        attr = qs_get_next_attr(doc,attr)) {
308     char *name  = qs_get_attr_name(doc,attr);
309     char *value = qs_get_attr_value(doc,attr);
310     if (STRCASEEQ('n','N',"name",name)) {
311       return apr_pstrdup(pool, (value ? value : ""));
312     }
313   }
314   return NULL;
315 }
316
317
318 /**
319  * The value of the SIZE attribute is acquired.
320  *
321  * @param doc  [i] The pointer to the Doc structure at the output
322  *                 destination is specified.
323  * @param tag  [i] The tag node to want to acquire the SIZE attribute
324  *                 is specified.
325  * @param pool [i] To use POOL.
326  * @return The value of the SIZE attribute is returned. NULL is
327  *         returned when not is.
328  */
329 char *
330 qs_get_size_attr(Doc *doc, Node *tag, apr_pool_t *pool)
331 {
332   Attr *attr;
333   for (attr = qs_get_attr(doc,tag); 
334        attr; 
335        attr = qs_get_next_attr(doc,attr)) {
336     char *name  = qs_get_attr_name(doc,attr);
337     char *value = qs_get_attr_value(doc,attr);
338     if (STRCASEEQ('s','S',"size",name)) {
339       return apr_pstrdup(pool, (value ? value : ""));
340     }
341   }
342   return NULL;
343 }
344
345
346 /**
347  * The value of the ACCESSKEY attribute is acquired.
348  *
349  * @param doc  [i] The pointer to the Doc structure at the output
350  *                 destination is specified.
351  * @param tag  [i] The tag node to want to acquire the ACCESSKEY attribute
352  *                 is specified.
353  * @param pool [i] To use POOL.
354  * @return The value of the ACCESSKEY attribute is returned. NULL is
355  *         returned when not is.
356  */
357 char *
358 qs_get_accesskey_attr(Doc *doc, Node *tag, apr_pool_t *pool)
359 {
360   Attr *attr;
361   for (attr = qs_get_attr(doc,tag); 
362        attr; 
363        attr = qs_get_next_attr(doc,attr)) {
364     char *name  = qs_get_attr_name(doc,attr);
365     char *value = qs_get_attr_value(doc,attr);
366     if (STRCASEEQ('a','A',"accesskey",name)) {
367       return apr_pstrdup(pool, value);
368     }
369   }
370   return NULL;
371 }
372
373
374 /**
375  * The value of the ISTYLE attribute is acquired.
376  *
377  * @param doc  [i] The pointer to the Doc structure at the output
378  *                 destination is specified.
379  * @param tag  [i] The tag node to want to acquire the ISTYLE attribute
380  *                 is specified.
381  * @param pool [i] To use POOL.
382  * @return The value of the ISTYLE attribute is returned. NULL is
383  *         returned when not is.
384  */
385 char *
386 qs_get_istyle_attr(Doc *doc, Node *tag, apr_pool_t *pool)
387 {
388   Attr *attr;
389   for (attr = qs_get_attr(doc,tag); 
390        attr != NULL; 
391        attr = qs_get_next_attr(doc,attr)) {
392     char *name  = qs_get_attr_name(doc,attr);
393     char *value = qs_get_attr_value(doc,attr);
394     if (STRCASEEQ('i','I',"istyle",name)) {
395       return apr_pstrdup(pool, value);
396     }
397   }
398   return NULL;
399 }
400
401
402 /**
403  * The value of the MAXLENGTH attribute is acquired from the tag node of the
404  * object.
405  *
406  * @param doc  [i] The pointer to the Doc structure at the output
407  *                 destination is specified.
408  * @param tag  [i] The tag node to want to acquire the MAXLENGTH attribute
409  *                 is specified.
410  * @param pool [i] To use POOL.
411  * @return The value of the MAXLENGTH attribute is returned. NULL is
412  *         returned when not is.
413  */
414 char *
415 qs_get_maxlength_attr(Doc *doc, Node *tag, apr_pool_t *pool)
416 {
417   Attr *attr;
418   for (attr = qs_get_attr(doc,tag);
419        attr; 
420        attr = qs_get_next_attr(doc,attr)) {
421     char *name  = qs_get_attr_name(doc,attr);
422     char *value = qs_get_attr_value(doc,attr);
423     if (STRCASEEQ('m','M',"maxlength",name)) {
424       return apr_pstrdup(pool, value);
425     }
426   }
427   return NULL;
428 }
429
430
431 /**
432  * It is scanned whether the CHECKBOX tag of the object is CHECKED. 
433  *
434  * @param doc  [i] The pointer to the Doc structure at the output
435  *                 destination is specified.
436  * @param tag  [i] The tag node to want to acquire the CHECKBOX attribute
437  *                 is specified.
438  * @param pool [i] To use POOL.
439  * @return 1 is returned when it is CHECKED and, additionally, 0 is returned. 
440  */
441 int
442 qs_is_checked_checkbox_attr(Doc *doc, Node *tag, apr_pool_t *UNUSED(pool))
443 {
444   Attr *attr;
445   for (attr = qs_get_attr(doc,tag);
446        attr; 
447        attr = qs_get_next_attr(doc,attr)) {
448     char *name  = qs_get_attr_name(doc,attr);
449     if (STRCASEEQ('c','C',"checked",name)) {
450       return 1;
451     }
452   }
453   return 0;
454 }
455
456
457 int
458 chxj_chxjif_is_mine(device_table *spec, Doc *doc, Node *tag)
459 {
460   request_rec *r = doc->r;
461   Attr        *attr;
462
463   for (attr = qs_get_attr(doc,tag);
464        attr; 
465        attr = qs_get_next_attr(doc,attr)) {
466     char *name  = qs_get_attr_name(doc,attr);
467     char *value = qs_get_attr_value(doc,attr);
468     if ((*name == 'l' || *name == 'L') && strcasecmp(name, "lang") == 0) {
469
470       DBG(r, "lang found [%s] spec [%d]", value, spec->html_spec_type);
471       if (STRCASEEQ('a','A',"all",value)) {
472         return 1;
473       }
474       else if (STRCASEEQ('x','X',"xhtml",value)) {
475         if (spec->html_spec_type == CHXJ_SPEC_XHtml_Mobile_1_0) {
476           /* Yes , it is mine */
477           return 1;
478         }
479       }
480       else if (STRCASEEQ('h','H',"hdml",value)) {
481         if (spec->html_spec_type == CHXJ_SPEC_Hdml) {
482           /* Yes , it is mine */
483           return 1;
484         }
485       }
486       else if (STRCASEEQ('j','J',"jhtml",value)) {
487         if (spec->html_spec_type == CHXJ_SPEC_Jhtml) {
488           /* Yes , it is mine */
489           return 1;
490         }
491       }
492       else if (STRCASEEQ('j','J',"jxhtml",value)) {
493         if (spec->html_spec_type == CHXJ_SPEC_Jxhtml) {
494           /* Yes , it is mine */
495           return 1;
496         }
497       }
498       else if (STRCASEEQ('c','C',"chtml",value)) {
499         switch (spec->html_spec_type) {
500         case CHXJ_SPEC_Chtml_1_0:
501         case CHXJ_SPEC_Chtml_2_0:
502         case CHXJ_SPEC_Chtml_3_0:
503         case CHXJ_SPEC_Chtml_4_0:
504         case CHXJ_SPEC_Chtml_5_0:
505         case CHXJ_SPEC_Chtml_6_0:
506         case CHXJ_SPEC_Chtml_7_0:
507           return 1;
508         default:
509           break;
510         }
511       }
512       else if (STRCASEEQ('i','I',"ixhtml",value)) {
513         switch (spec->html_spec_type) {
514         case CHXJ_SPEC_Chtml_6_0:
515         case CHXJ_SPEC_Chtml_7_0:
516           return 1;
517         default:
518           break;
519         }
520       }
521     }
522   }
523
524   /* No, it is not mine. */
525   return 0;
526 }
527
528
529 /**
530  * The value of the DESTLANG attribute is acquired from the tag node of the
531  * object.
532  *
533  * @param doc  [i] The pointer to the Doc structure at the output
534  *                 destination is specified.
535  * @param tag  [i] The tag node to want to acquire the DESTLANG attribute
536  *                 is specified.
537  * @param pool [i] To use POOL.
538  * @return The value of the DESTLANG attribute is returned. NULL is
539  *         returned when not is.
540  */
541 char *
542 qs_get_destlang_attr(Doc *doc, Node *tag, apr_pool_t *pool)
543 {
544   Attr  *attr;
545   for (attr = qs_get_attr(doc,tag);
546        attr; 
547        attr = qs_get_next_attr(doc,attr)) {
548     char *name  = qs_get_attr_name(doc,attr);
549     char *value = qs_get_attr_value(doc,attr);
550     if (STRCASEEQ('d','D',"destlang",name)) {
551       return apr_pstrdup(pool, value);
552     }
553   }
554
555   return NULL;
556 }
557
558
559 /**
560  * The value of the PARSE attribute is acquired.
561  *
562  * @param doc  [i] The pointer to the Doc structure to be scanned is
563  *                 specified.
564  * @param tag  [i] The tag node to be scanned is specified.
565  * @param pool [i] To use POOL.
566  * @return The value of the PARSE attribute is returned. NULL is returned when
567  *         not found.
568  */
569 char *
570 qs_get_parse_attr(Doc *doc, Node *tag, apr_pool_t *pool)
571 {
572   Attr *attr;
573   /*--------------------------------------------------------------------------*/
574   /* The object tag node is scanned.                                          */
575   /*--------------------------------------------------------------------------*/
576   for (attr = qs_get_attr(doc,tag);
577        attr;
578        attr = qs_get_next_attr(doc,attr)) {
579     char *name  = qs_get_attr_name(doc,attr);
580     char *value = qs_get_attr_value(doc,attr);
581     if (STRCASEEQ('p','P',"parse",name)) {
582       /*----------------------------------------------------------------------*/
583       /* The VALUE attribute was found.                                       */
584       /*----------------------------------------------------------------------*/
585       return apr_pstrdup(pool, value);
586     }
587   }
588
589   /*--------------------------------------------------------------------------*/
590   /* not found                                                                */
591   /*--------------------------------------------------------------------------*/
592   return NULL;
593 }
594
595
596 char *
597 chxj_form_action_to_hidden_tag(
598   request_rec         *r,
599   apr_pool_t          *pool,
600   const char          *str,
601   int                 xmlFlag,
602   int                 post,
603   char                **new_query_string,
604   int                 docomo,
605   int                 softbank,
606   chxjconvrule_entry  *entryp)
607 {
608   char *s = apr_pstrdup(pool, str);
609   *new_query_string = NULL;
610   int no_qsconv_flag = (((unsigned int)entryp->action & CONVRULE_QSCONV_OFF_BIT) != 0);
611   if (!s) return NULL;
612   if (chxj_starts_with(s, "http://") || chxj_starts_with(s, "https://")) {
613     apr_uri_t url;
614     apr_uri_parse(pool, s, &url);
615     if (url.hostname && strcasecmp(url.hostname, r->hostname) != 0) {
616       return NULL;
617     }
618   }
619   s = strchr(s, '?');
620   if (!s) return NULL;
621   s++;
622   char *result = NULL;
623
624   char *pstat;
625   char *pstat2;
626   for (;;) {
627     char *pair = apr_strtok(s, "&", &pstat);
628     if (! pair) break;
629     if (strncasecmp(pair, "amp;", 4) == 0) {
630       pair += 4;
631     }
632     s = NULL;
633     char *key = apr_strtok(pair, "=",  &pstat2);
634     char *val = "";
635     if (key) {
636       val = apr_strtok(NULL, "=", &pstat2);
637       if (!val) val = "";
638     }
639     char *tmp = NULL;
640     
641     if (no_qsconv_flag) {
642       if (*new_query_string) {
643         *new_query_string = apr_psprintf(pool, "%s&%s=%s", *new_query_string, chxj_jreserved_to_safe_tag(r, key, entryp), val);
644       }
645       else {
646         *new_query_string = apr_psprintf(pool, "%s=%s", chxj_jreserved_to_safe_tag(r, key, entryp), val);
647       }
648     }
649     else {
650       if (post && strcasecmp(key, "guid") == 0 && docomo) {
651         *new_query_string = apr_psprintf(pool, "%s=%s", key, val);
652       }
653       else {
654         if (! post || strcasecmp(key, "_chxj_cc") == 0 || strcasecmp(key, "_chxj_nc") == 0) {
655           if (softbank) {
656             tmp = apr_psprintf(pool, 
657                                "<input type=\"hidden\" name=\"%s\" value=\"%s\"%s>", 
658                                chxj_jreserved_to_safe_tag(r, 
659                                                           chxj_url_decode(pool, key), 
660                                                           entryp), 
661                                chxj_url_decode(pool, val), 
662                                (xmlFlag == 1) ? " /" : "");
663           }
664           else {
665             tmp = apr_psprintf(pool, 
666                                "<input type=\"hidden\" name=\"%s\" value=\"%s\"%s>", 
667                                chxj_url_decode(pool, key), 
668                                chxj_url_decode(pool, val), 
669                                (xmlFlag == 1) ? " /" : "");
670           }
671         }
672         else {
673           tmp = apr_psprintf(pool, 
674                              "<input type=\"hidden\" name=\"_chxj_qs_%s\" value=\"%s\"%s>", 
675                              chxj_url_decode(pool, key), 
676                              chxj_url_decode(pool, val), 
677                              (xmlFlag == 1) ? " /" : "");
678         }
679         if (result) {
680           result = apr_pstrcat(pool, result, tmp, NULL);
681         }
682         else {
683           result = tmp;
684         }
685       }
686     }
687   }
688   return result;
689 }
690 /*
691  * vim:ts=2 et
692  */