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