Mercurial > hg > nginx
comparison src/http/modules/ngx_http_xslt_filter_module.c @ 2154:4f48a2765da0
reuse compiled XSLT tree in different locations
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 05 Aug 2008 14:27:49 +0000 |
parents | 6476e445d6ce |
children | 0c6d0bd60579 |
comparison
equal
deleted
inserted
replaced
2153:6476e445d6ce | 2154:4f48a2765da0 |
---|---|
20 #define NGX_HTTP_XSLT_REUSE_DTD 1 | 20 #define NGX_HTTP_XSLT_REUSE_DTD 1 |
21 #endif | 21 #endif |
22 | 22 |
23 | 23 |
24 typedef struct { | 24 typedef struct { |
25 u_char *name; | |
26 xsltStylesheetPtr stylesheet; | |
27 } ngx_http_xslt_sheet_file_t; | |
28 | |
29 | |
30 typedef struct { | |
31 ngx_array_t sheet_files; /* ngx_http_xslt_sheet_file_t */ | |
32 } ngx_http_xslt_filter_main_conf_t; | |
33 | |
34 | |
35 typedef struct { | |
25 ngx_array_t *lengths; | 36 ngx_array_t *lengths; |
26 ngx_array_t *values; | 37 ngx_array_t *values; |
27 } ngx_http_xslt_param_t; | 38 } ngx_http_xslt_param_t; |
28 | 39 |
29 | 40 |
36 typedef struct { | 47 typedef struct { |
37 xmlDtdPtr dtd; | 48 xmlDtdPtr dtd; |
38 ngx_array_t sheets; /* ngx_http_xslt_sheet_t */ | 49 ngx_array_t sheets; /* ngx_http_xslt_sheet_t */ |
39 ngx_hash_t types; | 50 ngx_hash_t types; |
40 ngx_array_t *types_keys; | 51 ngx_array_t *types_keys; |
41 } ngx_http_xslt_filter_conf_t; | 52 } ngx_http_xslt_filter_loc_conf_t; |
42 | 53 |
43 | 54 |
44 typedef struct { | 55 typedef struct { |
45 xmlDocPtr doc; | 56 xmlDocPtr doc; |
46 xmlParserCtxtPtr ctxt; | 57 xmlParserCtxtPtr ctxt; |
116 static char *ngx_http_xslt_entities(ngx_conf_t *cf, ngx_command_t *cmd, | 127 static char *ngx_http_xslt_entities(ngx_conf_t *cf, ngx_command_t *cmd, |
117 void *conf); | 128 void *conf); |
118 static char *ngx_http_xslt_stylesheet(ngx_conf_t *cf, ngx_command_t *cmd, | 129 static char *ngx_http_xslt_stylesheet(ngx_conf_t *cf, ngx_command_t *cmd, |
119 void *conf); | 130 void *conf); |
120 static void ngx_http_xslt_cleanup_stylesheet(void *data); | 131 static void ngx_http_xslt_cleanup_stylesheet(void *data); |
132 static void *ngx_http_xslt_filter_create_main_conf(ngx_conf_t *cf); | |
121 static void *ngx_http_xslt_filter_create_conf(ngx_conf_t *cf); | 133 static void *ngx_http_xslt_filter_create_conf(ngx_conf_t *cf); |
122 static char *ngx_http_xslt_filter_merge_conf(ngx_conf_t *cf, void *parent, | 134 static char *ngx_http_xslt_filter_merge_conf(ngx_conf_t *cf, void *parent, |
123 void *child); | 135 void *child); |
124 static ngx_int_t ngx_http_xslt_filter_init(ngx_conf_t *cf); | 136 static ngx_int_t ngx_http_xslt_filter_init(ngx_conf_t *cf); |
125 | 137 |
148 | 160 |
149 { ngx_string("xslt_types"), | 161 { ngx_string("xslt_types"), |
150 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, | 162 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, |
151 ngx_http_types_slot, | 163 ngx_http_types_slot, |
152 NGX_HTTP_LOC_CONF_OFFSET, | 164 NGX_HTTP_LOC_CONF_OFFSET, |
153 offsetof(ngx_http_xslt_filter_conf_t, types_keys), | 165 offsetof(ngx_http_xslt_filter_loc_conf_t, types_keys), |
154 &ngx_http_xslt_default_types[0] }, | 166 &ngx_http_xslt_default_types[0] }, |
155 | 167 |
156 ngx_null_command | 168 ngx_null_command |
157 }; | 169 }; |
158 | 170 |
159 | 171 |
160 static ngx_http_module_t ngx_http_xslt_filter_module_ctx = { | 172 static ngx_http_module_t ngx_http_xslt_filter_module_ctx = { |
161 NULL, /* preconfiguration */ | 173 NULL, /* preconfiguration */ |
162 ngx_http_xslt_filter_init, /* postconfiguration */ | 174 ngx_http_xslt_filter_init, /* postconfiguration */ |
163 | 175 |
164 NULL, /* create main configuration */ | 176 ngx_http_xslt_filter_create_main_conf, /* create main configuration */ |
165 NULL, /* init main configuration */ | 177 NULL, /* init main configuration */ |
166 | 178 |
167 NULL, /* create server configuration */ | 179 NULL, /* create server configuration */ |
168 NULL, /* merge server configuration */ | 180 NULL, /* merge server configuration */ |
169 | 181 |
193 | 205 |
194 | 206 |
195 static ngx_int_t | 207 static ngx_int_t |
196 ngx_http_xslt_header_filter(ngx_http_request_t *r) | 208 ngx_http_xslt_header_filter(ngx_http_request_t *r) |
197 { | 209 { |
198 ngx_http_xslt_filter_ctx_t *ctx; | 210 ngx_http_xslt_filter_ctx_t *ctx; |
199 ngx_http_xslt_filter_conf_t *conf; | 211 ngx_http_xslt_filter_loc_conf_t *conf; |
200 | 212 |
201 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 213 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
202 "xslt filter header"); | 214 "xslt filter header"); |
203 | 215 |
204 if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED) { | 216 if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED) { |
475 ngx_http_xslt_sax_external_subset(void *data, const xmlChar *name, | 487 ngx_http_xslt_sax_external_subset(void *data, const xmlChar *name, |
476 const xmlChar *externalId, const xmlChar *systemId) | 488 const xmlChar *externalId, const xmlChar *systemId) |
477 { | 489 { |
478 ngx_http_xslt_filter_ctx_t *ctx = data; | 490 ngx_http_xslt_filter_ctx_t *ctx = data; |
479 | 491 |
480 xmlDocPtr doc; | 492 xmlDocPtr doc; |
481 xmlDtdPtr dtd; | 493 xmlDtdPtr dtd; |
482 ngx_http_request_t *r; | 494 ngx_http_request_t *r; |
483 ngx_http_xslt_filter_conf_t *conf; | 495 ngx_http_xslt_filter_loc_conf_t *conf; |
484 | 496 |
485 r = ctx->request; | 497 r = ctx->request; |
486 | 498 |
487 conf = ngx_http_get_module_loc_conf(r, ngx_http_xslt_filter_module); | 499 conf = ngx_http_get_module_loc_conf(r, ngx_http_xslt_filter_module); |
488 | 500 |
724 | 736 |
725 static ngx_buf_t * | 737 static ngx_buf_t * |
726 ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r, | 738 ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r, |
727 ngx_http_xslt_filter_ctx_t *ctx) | 739 ngx_http_xslt_filter_ctx_t *ctx) |
728 { | 740 { |
729 int len, rc, doc_type; | 741 int len, rc, doc_type; |
730 u_char *type, *encoding; | 742 u_char *type, *encoding; |
731 ngx_buf_t *b; | 743 ngx_buf_t *b; |
732 ngx_uint_t i; | 744 ngx_uint_t i; |
733 xmlChar *buf; | 745 xmlChar *buf; |
734 xmlDocPtr doc, res; | 746 xmlDocPtr doc, res; |
735 ngx_http_xslt_sheet_t *sheet; | 747 ngx_http_xslt_sheet_t *sheet; |
736 ngx_http_xslt_filter_conf_t *conf; | 748 ngx_http_xslt_filter_loc_conf_t *conf; |
737 | 749 |
738 conf = ngx_http_get_module_loc_conf(r, ngx_http_xslt_filter_module); | 750 conf = ngx_http_get_module_loc_conf(r, ngx_http_xslt_filter_module); |
739 sheet = conf->sheets.elts; | 751 sheet = conf->sheets.elts; |
740 doc = ctx->doc; | 752 doc = ctx->doc; |
741 | 753 |
978 | 990 |
979 | 991 |
980 static char * | 992 static char * |
981 ngx_http_xslt_entities(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 993 ngx_http_xslt_entities(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
982 { | 994 { |
983 ngx_http_xslt_filter_conf_t *xlcf = conf; | 995 ngx_http_xslt_filter_loc_conf_t *xlcf = conf; |
984 | 996 |
985 ngx_str_t *value; | 997 ngx_str_t *value; |
986 | 998 |
987 if (xlcf->dtd) { | 999 if (xlcf->dtd) { |
988 return "is duplicate"; | 1000 return "is duplicate"; |
1003 | 1015 |
1004 | 1016 |
1005 static char * | 1017 static char * |
1006 ngx_http_xslt_stylesheet(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 1018 ngx_http_xslt_stylesheet(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
1007 { | 1019 { |
1008 ngx_http_xslt_filter_conf_t *xlcf = conf; | 1020 ngx_http_xslt_filter_loc_conf_t *xlcf = conf; |
1009 | 1021 |
1010 ngx_str_t *value; | 1022 ngx_str_t *value; |
1011 ngx_uint_t i, n; | 1023 ngx_uint_t i, n; |
1012 ngx_pool_cleanup_t *cln; | 1024 ngx_pool_cleanup_t *cln; |
1013 ngx_http_xslt_sheet_t *sheet; | 1025 ngx_http_xslt_sheet_t *sheet; |
1014 ngx_http_xslt_param_t *param; | 1026 ngx_http_xslt_param_t *param; |
1015 ngx_http_script_compile_t sc; | 1027 ngx_http_script_compile_t sc; |
1028 ngx_http_xslt_sheet_file_t *file; | |
1029 ngx_http_xslt_filter_main_conf_t *xmcf; | |
1016 | 1030 |
1017 value = cf->args->elts; | 1031 value = cf->args->elts; |
1018 | 1032 |
1019 if (xlcf->sheets.elts == NULL) { | 1033 if (xlcf->sheets.elts == NULL) { |
1020 if (ngx_array_init(&xlcf->sheets, cf->pool, 1, | 1034 if (ngx_array_init(&xlcf->sheets, cf->pool, 1, |
1034 | 1048 |
1035 if (ngx_conf_full_name(cf->cycle, &value[1], 0) != NGX_OK) { | 1049 if (ngx_conf_full_name(cf->cycle, &value[1], 0) != NGX_OK) { |
1036 return NGX_CONF_ERROR; | 1050 return NGX_CONF_ERROR; |
1037 } | 1051 } |
1038 | 1052 |
1053 xmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_xslt_filter_module); | |
1054 | |
1055 file = xmcf->sheet_files.elts; | |
1056 for (i = 0; i < xmcf->sheet_files.nelts; i++) { | |
1057 if (ngx_strcmp(file[i].name, &value[1].data) == 0) { | |
1058 sheet->stylesheet = file[i].stylesheet; | |
1059 goto found; | |
1060 } | |
1061 } | |
1062 | |
1039 cln = ngx_pool_cleanup_add(cf->pool, 0); | 1063 cln = ngx_pool_cleanup_add(cf->pool, 0); |
1040 if (cln == NULL) { | 1064 if (cln == NULL) { |
1041 return NGX_CONF_ERROR; | 1065 return NGX_CONF_ERROR; |
1042 } | 1066 } |
1043 | 1067 |
1049 return NGX_CONF_ERROR; | 1073 return NGX_CONF_ERROR; |
1050 } | 1074 } |
1051 | 1075 |
1052 cln->handler = ngx_http_xslt_cleanup_stylesheet; | 1076 cln->handler = ngx_http_xslt_cleanup_stylesheet; |
1053 cln->data = sheet->stylesheet; | 1077 cln->data = sheet->stylesheet; |
1078 | |
1079 file = ngx_array_push(&xmcf->sheet_files); | |
1080 if (file == NULL) { | |
1081 return NGX_CONF_ERROR; | |
1082 } | |
1083 | |
1084 file->name = value[1].data; | |
1085 file->stylesheet = sheet->stylesheet; | |
1086 | |
1087 found: | |
1054 | 1088 |
1055 n = cf->args->nelts; | 1089 n = cf->args->nelts; |
1056 | 1090 |
1057 if (n == 2) { | 1091 if (n == 2) { |
1058 return NGX_CONF_OK; | 1092 return NGX_CONF_OK; |
1101 | 1135 |
1102 xsltFreeStylesheet(stylesheet); | 1136 xsltFreeStylesheet(stylesheet); |
1103 } | 1137 } |
1104 | 1138 |
1105 | 1139 |
1140 static void * | |
1141 ngx_http_xslt_filter_create_main_conf(ngx_conf_t *cf) | |
1142 { | |
1143 ngx_http_xslt_filter_main_conf_t *conf; | |
1144 | |
1145 conf = ngx_palloc(cf->pool, sizeof(ngx_http_xslt_filter_main_conf_t)); | |
1146 if (conf == NULL) { | |
1147 return NGX_CONF_ERROR; | |
1148 } | |
1149 | |
1150 if (ngx_array_init(&conf->sheet_files, cf->pool, 1, | |
1151 sizeof(ngx_http_xslt_sheet_file_t)) | |
1152 != NGX_OK) | |
1153 { | |
1154 return NULL; | |
1155 } | |
1156 | |
1157 return conf; | |
1158 } | |
1159 | |
1106 | 1160 |
1107 static void * | 1161 static void * |
1108 ngx_http_xslt_filter_create_conf(ngx_conf_t *cf) | 1162 ngx_http_xslt_filter_create_conf(ngx_conf_t *cf) |
1109 { | 1163 { |
1110 ngx_http_xslt_filter_conf_t *conf; | 1164 ngx_http_xslt_filter_loc_conf_t *conf; |
1111 | 1165 |
1112 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_xslt_filter_conf_t)); | 1166 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_xslt_filter_loc_conf_t)); |
1113 if (conf == NULL) { | 1167 if (conf == NULL) { |
1114 return NGX_CONF_ERROR; | 1168 return NGX_CONF_ERROR; |
1115 } | 1169 } |
1116 | 1170 |
1117 /* | 1171 /* |
1128 | 1182 |
1129 | 1183 |
1130 static char * | 1184 static char * |
1131 ngx_http_xslt_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child) | 1185 ngx_http_xslt_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child) |
1132 { | 1186 { |
1133 ngx_http_xslt_filter_conf_t *prev = parent; | 1187 ngx_http_xslt_filter_loc_conf_t *prev = parent; |
1134 ngx_http_xslt_filter_conf_t *conf = child; | 1188 ngx_http_xslt_filter_loc_conf_t *conf = child; |
1135 | 1189 |
1136 if (conf->dtd == NULL) { | 1190 if (conf->dtd == NULL) { |
1137 conf->dtd = prev->dtd; | 1191 conf->dtd = prev->dtd; |
1138 } | 1192 } |
1139 | 1193 |