comparison src/http/modules/ngx_http_xslt_filter_module.c @ 394:05981f639d21 NGINX_0_7_9

nginx 0.7.9 *) Change: now ngx_http_charset_module works by default with following MIME types: text/html, text/css, text/xml, text/plain, text/vnd.wap.wml, application/x-javascript, and application/rss+xml. *) Feature: the "charset_types" and "addition_types" directives. *) Feature: now the "gzip_types", "ssi_types", and "sub_filter_types" directives use hash. *) Feature: the ngx_cpp_test_module. *) Feature: the "expires" directive supports daily time. *) Feature: the ngx_http_xslt_module improvements and bug fixing. Thanks to Denis F. Latypoff and Maxim Dounin. *) Bugfix: the "log_not_found" directive did not work for index files tests. *) Bugfix: HTTPS connections might hang, if kqueue, epoll, rtsig, or eventport methods were used; the bug had appeared in 0.7.7. *) Bugfix: if the "server_name", "valid_referers", and "map" directives used an "*.domain.tld" wildcard and exact name "domain.tld" was not set, then the exact name was matched by the wildcard; the bugs had appeared in 0.3.18.
author Igor Sysoev <http://sysoev.ru>
date Tue, 12 Aug 2008 00:00:00 +0400
parents 34fb3a573548
children 6ebbca3d5ed7
comparison
equal deleted inserted replaced
393:040b8c84d040 394:05981f639d21
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 void *data;
27 } ngx_http_xslt_file_t;
28
29
30 typedef struct {
31 ngx_array_t dtd_files; /* ngx_http_xslt_file_t */
32 ngx_array_t sheet_files; /* ngx_http_xslt_file_t */
33 } ngx_http_xslt_filter_main_conf_t;
34
35
36 typedef struct {
25 ngx_array_t *lengths; 37 ngx_array_t *lengths;
26 ngx_array_t *values; 38 ngx_array_t *values;
27 } ngx_http_xslt_param_t; 39 } ngx_http_xslt_param_t;
28 40
29 41
33 } ngx_http_xslt_sheet_t; 45 } ngx_http_xslt_sheet_t;
34 46
35 47
36 typedef struct { 48 typedef struct {
37 xmlDtdPtr dtd; 49 xmlDtdPtr dtd;
38 ngx_array_t sheets; /* ngx_http_xslt_sheet_t */ 50 ngx_array_t sheets; /* ngx_http_xslt_sheet_t */
39 ngx_hash_t types_hash; 51 ngx_hash_t types;
40 ngx_array_t *keys; 52 ngx_array_t *types_keys;
41 } ngx_http_xslt_filter_conf_t; 53 } ngx_http_xslt_filter_loc_conf_t;
42 54
43 55
44 typedef struct { 56 typedef struct {
45 xmlDocPtr doc; 57 xmlDocPtr doc;
46 xmlParserCtxtPtr ctxt; 58 xmlParserCtxtPtr ctxt;
47 xmlSAXHandler *sax; 59 xmlSAXHandler *sax;
48 ngx_http_request_t *request; 60 ngx_http_request_t *request;
49 ngx_array_t params; 61 ngx_array_t params;
50 unsigned done:1; 62
51 unsigned html:1; 63 ngx_uint_t done; /* unsigned done:1; */
52 } ngx_http_xslt_filter_ctx_t; 64 } ngx_http_xslt_filter_ctx_t;
53 65
54 66
55 static ngx_int_t ngx_http_xslt_send(ngx_http_request_t *r, 67 static ngx_int_t ngx_http_xslt_send(ngx_http_request_t *r,
56 ngx_http_xslt_filter_ctx_t *ctx, ngx_buf_t *b); 68 ngx_http_xslt_filter_ctx_t *ctx, ngx_buf_t *b);
107 119
108 static ngx_buf_t *ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r, 120 static ngx_buf_t *ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r,
109 ngx_http_xslt_filter_ctx_t *ctx); 121 ngx_http_xslt_filter_ctx_t *ctx);
110 static ngx_int_t ngx_http_xslt_params(ngx_http_request_t *r, 122 static ngx_int_t ngx_http_xslt_params(ngx_http_request_t *r,
111 ngx_http_xslt_filter_ctx_t *ctx, ngx_array_t *params); 123 ngx_http_xslt_filter_ctx_t *ctx, ngx_array_t *params);
124 static u_char *ngx_http_xslt_content_type(xsltStylesheetPtr s);
125 static u_char *ngx_http_xslt_encoding(xsltStylesheetPtr s);
112 static void ngx_http_xslt_cleanup(void *data); 126 static void ngx_http_xslt_cleanup(void *data);
113 127
114 static char *ngx_http_xslt_entities(ngx_conf_t *cf, ngx_command_t *cmd, 128 static char *ngx_http_xslt_entities(ngx_conf_t *cf, ngx_command_t *cmd,
115 void *conf); 129 void *conf);
116 static char *ngx_http_xslt_stylesheet(ngx_conf_t *cf, ngx_command_t *cmd, 130 static char *ngx_http_xslt_stylesheet(ngx_conf_t *cf, ngx_command_t *cmd,
117 void *conf); 131 void *conf);
132 static void ngx_http_xslt_cleanup_dtd(void *data);
118 static void ngx_http_xslt_cleanup_stylesheet(void *data); 133 static void ngx_http_xslt_cleanup_stylesheet(void *data);
134 static void *ngx_http_xslt_filter_create_main_conf(ngx_conf_t *cf);
119 static void *ngx_http_xslt_filter_create_conf(ngx_conf_t *cf); 135 static void *ngx_http_xslt_filter_create_conf(ngx_conf_t *cf);
120 static char *ngx_http_xslt_filter_merge_conf(ngx_conf_t *cf, void *parent, 136 static char *ngx_http_xslt_filter_merge_conf(ngx_conf_t *cf, void *parent,
121 void *child); 137 void *child);
122 static ngx_int_t ngx_http_xslt_filter_init(ngx_conf_t *cf); 138 static ngx_int_t ngx_http_xslt_filter_init(ngx_conf_t *cf);
123 139
129 145
130 146
131 static ngx_command_t ngx_http_xslt_filter_commands[] = { 147 static ngx_command_t ngx_http_xslt_filter_commands[] = {
132 148
133 { ngx_string("xml_entities"), 149 { ngx_string("xml_entities"),
134 NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1, 150 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
135 ngx_http_xslt_entities, 151 ngx_http_xslt_entities,
136 NGX_HTTP_LOC_CONF_OFFSET, 152 NGX_HTTP_LOC_CONF_OFFSET,
137 0, 153 0,
138 NULL }, 154 NULL },
139 155
140 { ngx_string("xslt_stylesheet"), 156 { ngx_string("xslt_stylesheet"),
141 NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_1MORE, 157 NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
142 ngx_http_xslt_stylesheet, 158 ngx_http_xslt_stylesheet,
143 NGX_HTTP_LOC_CONF_OFFSET, 159 NGX_HTTP_LOC_CONF_OFFSET,
144 0, 160 0,
145 NULL }, 161 NULL },
146 162
147 { ngx_string("xslt_types"), 163 { ngx_string("xslt_types"),
148 NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_1MORE, 164 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
149 ngx_http_types_slot, 165 ngx_http_types_slot,
150 NGX_HTTP_LOC_CONF_OFFSET, 166 NGX_HTTP_LOC_CONF_OFFSET,
151 offsetof(ngx_http_xslt_filter_conf_t, keys), 167 offsetof(ngx_http_xslt_filter_loc_conf_t, types_keys),
152 &ngx_http_xslt_default_types[0] }, 168 &ngx_http_xslt_default_types[0] },
153 169
154 ngx_null_command 170 ngx_null_command
155 }; 171 };
156 172
157 173
158 static ngx_http_module_t ngx_http_xslt_filter_module_ctx = { 174 static ngx_http_module_t ngx_http_xslt_filter_module_ctx = {
159 NULL, /* preconfiguration */ 175 NULL, /* preconfiguration */
160 ngx_http_xslt_filter_init, /* postconfiguration */ 176 ngx_http_xslt_filter_init, /* postconfiguration */
161 177
162 NULL, /* create main configuration */ 178 ngx_http_xslt_filter_create_main_conf, /* create main configuration */
163 NULL, /* init main configuration */ 179 NULL, /* init main configuration */
164 180
165 NULL, /* create server configuration */ 181 NULL, /* create server configuration */
166 NULL, /* merge server configuration */ 182 NULL, /* merge server configuration */
167 183
191 207
192 208
193 static ngx_int_t 209 static ngx_int_t
194 ngx_http_xslt_header_filter(ngx_http_request_t *r) 210 ngx_http_xslt_header_filter(ngx_http_request_t *r)
195 { 211 {
196 ngx_http_xslt_filter_ctx_t *ctx; 212 ngx_http_xslt_filter_ctx_t *ctx;
197 ngx_http_xslt_filter_conf_t *conf; 213 ngx_http_xslt_filter_loc_conf_t *conf;
198 214
199 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 215 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
200 "xslt filter header"); 216 "xslt filter header");
201 217
202 if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED) { 218 if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED) {
204 } 220 }
205 221
206 conf = ngx_http_get_module_loc_conf(r, ngx_http_xslt_filter_module); 222 conf = ngx_http_get_module_loc_conf(r, ngx_http_xslt_filter_module);
207 223
208 if (conf->sheets.nelts == 0 224 if (conf->sheets.nelts == 0
209 || ngx_http_test_content_type(r, &conf->types_hash) == NULL) 225 || ngx_http_test_content_type(r, &conf->types) == NULL)
210 { 226 {
211 return ngx_http_next_header_filter(r); 227 return ngx_http_next_header_filter(r);
212 } 228 }
213 229
214 ctx = ngx_http_get_module_ctx(r, ngx_http_xslt_filter_module); 230 ctx = ngx_http_get_module_ctx(r, ngx_http_xslt_filter_module);
314 ngx_free(b->pos); 330 ngx_free(b->pos);
315 return ngx_http_special_response_handler(r, 331 return ngx_http_special_response_handler(r,
316 NGX_HTTP_INTERNAL_SERVER_ERROR); 332 NGX_HTTP_INTERNAL_SERVER_ERROR);
317 } 333 }
318 334
319 if (ctx->html) { 335 if (r == r->main) {
320 r->headers_out.content_type_len = sizeof("text/html") - 1; 336 r->headers_out.content_length_n = b->last - b->pos;
321 r->headers_out.content_type.len = sizeof("text/html") - 1; 337
322 r->headers_out.content_type.data = (u_char *) "text/html"; 338 if (r->headers_out.content_length) {
323 } 339 r->headers_out.content_length->hash = 0;
324 340 r->headers_out.content_length = NULL;
325 r->headers_out.content_length_n = b->last - b->pos; 341 }
326 342
327 if (r->headers_out.content_length) { 343 ngx_http_clear_last_modified(r);
328 r->headers_out.content_length->hash = 0; 344 }
329 r->headers_out.content_length = NULL;
330 }
331
332 r->allow_ranges = 1;
333 345
334 rc = ngx_http_next_header_filter(r); 346 rc = ngx_http_next_header_filter(r);
335 347
336 if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { 348 if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
337 ngx_free(b->pos); 349 ngx_free(b->pos);
479 ngx_http_xslt_sax_external_subset(void *data, const xmlChar *name, 491 ngx_http_xslt_sax_external_subset(void *data, const xmlChar *name,
480 const xmlChar *externalId, const xmlChar *systemId) 492 const xmlChar *externalId, const xmlChar *systemId)
481 { 493 {
482 ngx_http_xslt_filter_ctx_t *ctx = data; 494 ngx_http_xslt_filter_ctx_t *ctx = data;
483 495
484 xmlDocPtr doc; 496 xmlDocPtr doc;
485 xmlDtdPtr dtd; 497 xmlDtdPtr dtd;
486 ngx_http_request_t *r; 498 ngx_http_request_t *r;
487 ngx_http_xslt_filter_conf_t *conf; 499 ngx_http_xslt_filter_loc_conf_t *conf;
488 500
489 r = ctx->request; 501 r = ctx->request;
490 502
491 conf = ngx_http_get_module_loc_conf(r, ngx_http_xslt_filter_module); 503 conf = ngx_http_get_module_loc_conf(r, ngx_http_xslt_filter_module);
492 504
509 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, 521 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
510 "xmlCopyDtd() failed"); 522 "xmlCopyDtd() failed");
511 return; 523 return;
512 } 524 }
513 525
514 dtd->name = xmlStrdup(name);
515
516 if (doc->children == NULL) { 526 if (doc->children == NULL) {
517 xmlAddChild((xmlNodePtr) doc, (xmlNodePtr) dtd); 527 xmlAddChild((xmlNodePtr) doc, (xmlNodePtr) dtd);
518 528
519 } else { 529 } else {
520 xmlAddPrevSibling(doc->children, (xmlNodePtr) dtd); 530 xmlAddPrevSibling(doc->children, (xmlNodePtr) dtd);
730 740
731 static ngx_buf_t * 741 static ngx_buf_t *
732 ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r, 742 ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r,
733 ngx_http_xslt_filter_ctx_t *ctx) 743 ngx_http_xslt_filter_ctx_t *ctx)
734 { 744 {
735 int len, rc; 745 int len, rc, doc_type;
736 ngx_buf_t *b; 746 u_char *type, *encoding;
737 ngx_uint_t i; 747 ngx_buf_t *b;
738 xmlChar *buf; 748 ngx_uint_t i;
739 xmlDocPtr doc, res; 749 xmlChar *buf;
740 ngx_http_xslt_sheet_t *sheet; 750 xmlDocPtr doc, res;
741 ngx_http_xslt_filter_conf_t *conf; 751 ngx_http_xslt_sheet_t *sheet;
752 ngx_http_xslt_filter_loc_conf_t *conf;
742 753
743 conf = ngx_http_get_module_loc_conf(r, ngx_http_xslt_filter_module); 754 conf = ngx_http_get_module_loc_conf(r, ngx_http_xslt_filter_module);
744 sheet = conf->sheets.elts; 755 sheet = conf->sheets.elts;
745 doc = ctx->doc; 756 doc = ctx->doc;
746 757
774 785
775 /* reset array elements */ 786 /* reset array elements */
776 ctx->params.nelts = 0; 787 ctx->params.nelts = 0;
777 } 788 }
778 789
779 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 790 /* there must be at least one stylesheet */
780 "xslt filter doc type: %d", doc->type); 791
781 792 if (r == r->main) {
782 ctx->html = (doc->type == XML_HTML_DOCUMENT_NODE) ? 1 : 0; 793 type = ngx_http_xslt_content_type(sheet[i - 1].stylesheet);
794
795 } else {
796 type = NULL;
797 }
798
799 encoding = ngx_http_xslt_encoding(sheet[i - 1].stylesheet);
800 doc_type = doc->type;
801
802 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
803 "xslt filter type: %d t:%s e:%s",
804 doc_type, type ? type : (u_char *) "(null)",
805 encoding ? encoding : (u_char *) "(null)");
783 806
784 rc = xsltSaveResultToString(&buf, &len, doc, sheet[i - 1].stylesheet); 807 rc = xsltSaveResultToString(&buf, &len, doc, sheet[i - 1].stylesheet);
785 808
786 xmlFreeDoc(doc); 809 xmlFreeDoc(doc);
787 810
805 828
806 b->pos = buf; 829 b->pos = buf;
807 b->last = buf + len; 830 b->last = buf + len;
808 b->memory = 1; 831 b->memory = 1;
809 b->last_buf = 1; 832 b->last_buf = 1;
833
834 if (encoding) {
835 r->headers_out.charset.len = ngx_strlen(encoding);
836 r->headers_out.charset.data = encoding;
837 }
838
839 if (r != r->main) {
840 return b;
841 }
842
843 if (type) {
844 len = ngx_strlen(type);
845
846 r->headers_out.content_type_len = len;
847 r->headers_out.content_type.len = len;
848 r->headers_out.content_type.data = type;
849
850 } else if (doc_type == XML_HTML_DOCUMENT_NODE) {
851
852 r->headers_out.content_type_len = sizeof("text/html") - 1;
853 r->headers_out.content_type.len = sizeof("text/html") - 1;
854 r->headers_out.content_type.data = (u_char *) "text/html";
855 }
810 856
811 return b; 857 return b;
812 } 858 }
813 859
814 860
904 950
905 return NGX_OK; 951 return NGX_OK;
906 } 952 }
907 953
908 954
955 static u_char *
956 ngx_http_xslt_content_type(xsltStylesheetPtr s)
957 {
958 u_char *type;
959
960 if (s->mediaType) {
961 return s->mediaType;
962 }
963
964 for (s = s->imports; s; s = s->next) {
965
966 type = ngx_http_xslt_content_type(s);
967
968 if (type) {
969 return type;
970 }
971 }
972
973 return NULL;
974 }
975
976
977 static u_char *
978 ngx_http_xslt_encoding(xsltStylesheetPtr s)
979 {
980 u_char *encoding;
981
982 if (s->encoding) {
983 return s->encoding;
984 }
985
986 for (s = s->imports; s; s = s->next) {
987
988 encoding = ngx_http_xslt_encoding(s);
989
990 if (encoding) {
991 return encoding;
992 }
993 }
994
995 return NULL;
996 }
997
998
909 static void 999 static void
910 ngx_http_xslt_cleanup(void *data) 1000 ngx_http_xslt_cleanup(void *data)
911 { 1001 {
912 ngx_free(data); 1002 ngx_free(data);
913 } 1003 }
914 1004
915 1005
916 static char * 1006 static char *
917 ngx_http_xslt_entities(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 1007 ngx_http_xslt_entities(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
918 { 1008 {
919 ngx_http_xslt_filter_conf_t *xlcf = conf; 1009 ngx_http_xslt_filter_loc_conf_t *xlcf = conf;
920 1010
921 ngx_str_t *value; 1011 ngx_str_t *value;
1012 ngx_uint_t i;
1013 ngx_pool_cleanup_t *cln;
1014 ngx_http_xslt_file_t *file;
1015 ngx_http_xslt_filter_main_conf_t *xmcf;
922 1016
923 if (xlcf->dtd) { 1017 if (xlcf->dtd) {
924 return "is duplicate"; 1018 return "is duplicate";
925 } 1019 }
926 1020
927 value = cf->args->elts; 1021 value = cf->args->elts;
1022
1023 xmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_xslt_filter_module);
1024
1025 file = xmcf->dtd_files.elts;
1026 for (i = 0; i < xmcf->dtd_files.nelts; i++) {
1027 if (ngx_strcmp(file[i].name, &value[1].data) == 0) {
1028 xlcf->dtd = file[i].data;
1029 return NGX_CONF_OK;
1030 }
1031 }
1032
1033 cln = ngx_pool_cleanup_add(cf->pool, 0);
1034 if (cln == NULL) {
1035 return NGX_CONF_ERROR;
1036 }
928 1037
929 xlcf->dtd = xmlParseDTD(NULL, (xmlChar *) value[1].data); 1038 xlcf->dtd = xmlParseDTD(NULL, (xmlChar *) value[1].data);
930 1039
931 if (xlcf->dtd == NULL) { 1040 if (xlcf->dtd == NULL) {
932 ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "xmlParseDTD() failed"); 1041 ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "xmlParseDTD() failed");
933 return NGX_CONF_ERROR; 1042 return NGX_CONF_ERROR;
934 } 1043 }
935 1044
1045 cln->handler = ngx_http_xslt_cleanup_dtd;
1046 cln->data = xlcf->dtd;
1047
1048 file = ngx_array_push(&xmcf->dtd_files);
1049 if (file == NULL) {
1050 return NGX_CONF_ERROR;
1051 }
1052
1053 file->name = value[1].data;
1054 file->data = xlcf->dtd;
1055
936 return NGX_CONF_OK; 1056 return NGX_CONF_OK;
937 } 1057 }
938 1058
939 1059
940 1060
941 static char * 1061 static char *
942 ngx_http_xslt_stylesheet(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 1062 ngx_http_xslt_stylesheet(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
943 { 1063 {
944 ngx_http_xslt_filter_conf_t *xlcf = conf; 1064 ngx_http_xslt_filter_loc_conf_t *xlcf = conf;
945 1065
946 ngx_str_t *value; 1066 ngx_str_t *value;
947 ngx_uint_t i, n; 1067 ngx_uint_t i, n;
948 ngx_pool_cleanup_t *cln; 1068 ngx_pool_cleanup_t *cln;
949 ngx_http_xslt_sheet_t *sheet; 1069 ngx_http_xslt_file_t *file;
950 ngx_http_xslt_param_t *param; 1070 ngx_http_xslt_sheet_t *sheet;
951 ngx_http_script_compile_t sc; 1071 ngx_http_xslt_param_t *param;
1072 ngx_http_script_compile_t sc;
1073 ngx_http_xslt_filter_main_conf_t *xmcf;
952 1074
953 value = cf->args->elts; 1075 value = cf->args->elts;
954 1076
955 if (xlcf->sheets.elts == NULL) { 1077 if (xlcf->sheets.elts == NULL) {
956 if (ngx_array_init(&xlcf->sheets, cf->pool, 1, 1078 if (ngx_array_init(&xlcf->sheets, cf->pool, 1,
970 1092
971 if (ngx_conf_full_name(cf->cycle, &value[1], 0) != NGX_OK) { 1093 if (ngx_conf_full_name(cf->cycle, &value[1], 0) != NGX_OK) {
972 return NGX_CONF_ERROR; 1094 return NGX_CONF_ERROR;
973 } 1095 }
974 1096
1097 xmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_xslt_filter_module);
1098
1099 file = xmcf->sheet_files.elts;
1100 for (i = 0; i < xmcf->sheet_files.nelts; i++) {
1101 if (ngx_strcmp(file[i].name, &value[1].data) == 0) {
1102 sheet->stylesheet = file[i].data;
1103 goto found;
1104 }
1105 }
1106
975 cln = ngx_pool_cleanup_add(cf->pool, 0); 1107 cln = ngx_pool_cleanup_add(cf->pool, 0);
976 if (cln == NULL) { 1108 if (cln == NULL) {
977 return NGX_CONF_ERROR; 1109 return NGX_CONF_ERROR;
978 } 1110 }
979 1111
985 return NGX_CONF_ERROR; 1117 return NGX_CONF_ERROR;
986 } 1118 }
987 1119
988 cln->handler = ngx_http_xslt_cleanup_stylesheet; 1120 cln->handler = ngx_http_xslt_cleanup_stylesheet;
989 cln->data = sheet->stylesheet; 1121 cln->data = sheet->stylesheet;
1122
1123 file = ngx_array_push(&xmcf->sheet_files);
1124 if (file == NULL) {
1125 return NGX_CONF_ERROR;
1126 }
1127
1128 file->name = value[1].data;
1129 file->data = sheet->stylesheet;
1130
1131 found:
990 1132
991 n = cf->args->nelts; 1133 n = cf->args->nelts;
992 1134
993 if (n == 2) { 1135 if (n == 2) {
994 return NGX_CONF_OK; 1136 return NGX_CONF_OK;
1029 return NGX_CONF_OK; 1171 return NGX_CONF_OK;
1030 } 1172 }
1031 1173
1032 1174
1033 static void 1175 static void
1176 ngx_http_xslt_cleanup_dtd(void *data)
1177 {
1178 xmlFreeDtd(data);
1179 }
1180
1181
1182 static void
1034 ngx_http_xslt_cleanup_stylesheet(void *data) 1183 ngx_http_xslt_cleanup_stylesheet(void *data)
1035 { 1184 {
1036 xsltStylesheetPtr stylesheet = data; 1185 xsltFreeStylesheet(data);
1037 1186 }
1038 xsltFreeStylesheet(stylesheet); 1187
1039 } 1188
1040 1189 static void *
1190 ngx_http_xslt_filter_create_main_conf(ngx_conf_t *cf)
1191 {
1192 ngx_http_xslt_filter_main_conf_t *conf;
1193
1194 conf = ngx_palloc(cf->pool, sizeof(ngx_http_xslt_filter_main_conf_t));
1195 if (conf == NULL) {
1196 return NGX_CONF_ERROR;
1197 }
1198
1199 if (ngx_array_init(&conf->dtd_files, cf->pool, 1,
1200 sizeof(ngx_http_xslt_file_t))
1201 != NGX_OK)
1202 {
1203 return NULL;
1204 }
1205
1206 if (ngx_array_init(&conf->sheet_files, cf->pool, 1,
1207 sizeof(ngx_http_xslt_file_t))
1208 != NGX_OK)
1209 {
1210 return NULL;
1211 }
1212
1213 return conf;
1214 }
1041 1215
1042 1216
1043 static void * 1217 static void *
1044 ngx_http_xslt_filter_create_conf(ngx_conf_t *cf) 1218 ngx_http_xslt_filter_create_conf(ngx_conf_t *cf)
1045 { 1219 {
1046 ngx_http_xslt_filter_conf_t *conf; 1220 ngx_http_xslt_filter_loc_conf_t *conf;
1047 1221
1048 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_xslt_filter_conf_t)); 1222 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_xslt_filter_loc_conf_t));
1049 if (conf == NULL) { 1223 if (conf == NULL) {
1050 return NGX_CONF_ERROR; 1224 return NGX_CONF_ERROR;
1051 } 1225 }
1052 1226
1053 /* 1227 /*
1054 * set by ngx_pcalloc(): 1228 * set by ngx_pcalloc():
1055 * 1229 *
1056 * conf->dtd 1230 * conf->dtd = NULL;
1057 * conf->sheets 1231 * conf->sheets = { NULL };
1232 * conf->types = { NULL };
1233 * conf->types_keys = NULL;
1058 */ 1234 */
1059 1235
1060 return conf; 1236 return conf;
1061 } 1237 }
1062 1238
1063 1239
1064 static char * 1240 static char *
1065 ngx_http_xslt_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child) 1241 ngx_http_xslt_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child)
1066 { 1242 {
1067 ngx_http_xslt_filter_conf_t *prev = parent; 1243 ngx_http_xslt_filter_loc_conf_t *prev = parent;
1068 ngx_http_xslt_filter_conf_t *conf = child; 1244 ngx_http_xslt_filter_loc_conf_t *conf = child;
1069 1245
1070 if (conf->dtd == NULL) { 1246 if (conf->dtd == NULL) {
1071 conf->dtd = prev->dtd; 1247 conf->dtd = prev->dtd;
1072 } 1248 }
1073 1249
1074 if (conf->sheets.nelts == 0) { 1250 if (conf->sheets.nelts == 0) {
1075 conf->sheets = prev->sheets; 1251 conf->sheets = prev->sheets;
1076 } 1252 }
1077 1253
1078 if (ngx_http_merge_types(cf, conf->keys, &conf->types_hash, prev->keys, 1254 if (ngx_http_merge_types(cf, conf->types_keys, &conf->types,
1079 &prev->types_hash, ngx_http_xslt_default_types) 1255 prev->types_keys, &prev->types,
1256 ngx_http_xslt_default_types)
1080 != NGX_OK) 1257 != NGX_OK)
1081 { 1258 {
1082 return NGX_CONF_ERROR; 1259 return NGX_CONF_ERROR;
1083 } 1260 }
1084 1261