comparison src/http/modules/ngx_http_xslt_filter_module.c @ 2153:6476e445d6ce

xsl:output's media-type and encoding support
author Igor Sysoev <igor@sysoev.ru>
date Tue, 05 Aug 2008 14:24:16 +0000
parents b23e83f5b182
children 4f48a2765da0
comparison
equal deleted inserted replaced
2152:b23e83f5b182 2153:6476e445d6ce
33 } ngx_http_xslt_sheet_t; 33 } ngx_http_xslt_sheet_t;
34 34
35 35
36 typedef struct { 36 typedef struct {
37 xmlDtdPtr dtd; 37 xmlDtdPtr dtd;
38 ngx_array_t sheets; /* ngx_http_xslt_sheet_t */ 38 ngx_array_t sheets; /* ngx_http_xslt_sheet_t */
39 ngx_hash_t types; 39 ngx_hash_t types;
40 ngx_array_t *types_keys; 40 ngx_array_t *types_keys;
41 } ngx_http_xslt_filter_conf_t; 41 } ngx_http_xslt_filter_conf_t;
42 42
43 43
45 xmlDocPtr doc; 45 xmlDocPtr doc;
46 xmlParserCtxtPtr ctxt; 46 xmlParserCtxtPtr ctxt;
47 xmlSAXHandler *sax; 47 xmlSAXHandler *sax;
48 ngx_http_request_t *request; 48 ngx_http_request_t *request;
49 ngx_array_t params; 49 ngx_array_t params;
50 unsigned done:1; 50
51 unsigned html:1; 51 ngx_uint_t done; /* unsigned done:1; */
52 } ngx_http_xslt_filter_ctx_t; 52 } ngx_http_xslt_filter_ctx_t;
53 53
54 54
55 static ngx_int_t ngx_http_xslt_send(ngx_http_request_t *r, 55 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); 56 ngx_http_xslt_filter_ctx_t *ctx, ngx_buf_t *b);
107 107
108 static ngx_buf_t *ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r, 108 static ngx_buf_t *ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r,
109 ngx_http_xslt_filter_ctx_t *ctx); 109 ngx_http_xslt_filter_ctx_t *ctx);
110 static ngx_int_t ngx_http_xslt_params(ngx_http_request_t *r, 110 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); 111 ngx_http_xslt_filter_ctx_t *ctx, ngx_array_t *params);
112 static u_char *ngx_http_xslt_content_type(xsltStylesheetPtr s);
113 static u_char *ngx_http_xslt_encoding(xsltStylesheetPtr s);
112 static void ngx_http_xslt_cleanup(void *data); 114 static void ngx_http_xslt_cleanup(void *data);
113 115
114 static char *ngx_http_xslt_entities(ngx_conf_t *cf, ngx_command_t *cmd, 116 static char *ngx_http_xslt_entities(ngx_conf_t *cf, ngx_command_t *cmd,
115 void *conf); 117 void *conf);
116 static char *ngx_http_xslt_stylesheet(ngx_conf_t *cf, ngx_command_t *cmd, 118 static char *ngx_http_xslt_stylesheet(ngx_conf_t *cf, ngx_command_t *cmd,
314 ngx_free(b->pos); 316 ngx_free(b->pos);
315 return ngx_http_special_response_handler(r, 317 return ngx_http_special_response_handler(r,
316 NGX_HTTP_INTERNAL_SERVER_ERROR); 318 NGX_HTTP_INTERNAL_SERVER_ERROR);
317 } 319 }
318 320
319 if (ctx->html) {
320 r->headers_out.content_type_len = sizeof("text/html") - 1;
321 r->headers_out.content_type.len = sizeof("text/html") - 1;
322 r->headers_out.content_type.data = (u_char *) "text/html";
323 }
324
325 r->headers_out.content_length_n = b->last - b->pos; 321 r->headers_out.content_length_n = b->last - b->pos;
326 322
327 if (r->headers_out.content_length) { 323 if (r->headers_out.content_length) {
328 r->headers_out.content_length->hash = 0; 324 r->headers_out.content_length->hash = 0;
329 r->headers_out.content_length = NULL; 325 r->headers_out.content_length = NULL;
728 724
729 static ngx_buf_t * 725 static ngx_buf_t *
730 ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r, 726 ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r,
731 ngx_http_xslt_filter_ctx_t *ctx) 727 ngx_http_xslt_filter_ctx_t *ctx)
732 { 728 {
733 int len, rc; 729 int len, rc, doc_type;
730 u_char *type, *encoding;
734 ngx_buf_t *b; 731 ngx_buf_t *b;
735 ngx_uint_t i; 732 ngx_uint_t i;
736 xmlChar *buf; 733 xmlChar *buf;
737 xmlDocPtr doc, res; 734 xmlDocPtr doc, res;
738 ngx_http_xslt_sheet_t *sheet; 735 ngx_http_xslt_sheet_t *sheet;
772 769
773 /* reset array elements */ 770 /* reset array elements */
774 ctx->params.nelts = 0; 771 ctx->params.nelts = 0;
775 } 772 }
776 773
777 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 774 /* there must be at least one stylesheet */
778 "xslt filter doc type: %d", doc->type); 775
779 776 type = ngx_http_xslt_content_type(sheet[i - 1].stylesheet);
780 ctx->html = (doc->type == XML_HTML_DOCUMENT_NODE) ? 1 : 0; 777 encoding = ngx_http_xslt_encoding(sheet[i - 1].stylesheet);
778 doc_type = doc->type;
779
780 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
781 "xslt filter type: %d t:%s e:%s",
782 doc_type, type ? type : (u_char *) "(null)",
783 encoding ? encoding : (u_char *) "(null)");
781 784
782 rc = xsltSaveResultToString(&buf, &len, doc, sheet[i - 1].stylesheet); 785 rc = xsltSaveResultToString(&buf, &len, doc, sheet[i - 1].stylesheet);
783 786
784 xmlFreeDoc(doc); 787 xmlFreeDoc(doc);
785 788
803 806
804 b->pos = buf; 807 b->pos = buf;
805 b->last = buf + len; 808 b->last = buf + len;
806 b->memory = 1; 809 b->memory = 1;
807 b->last_buf = 1; 810 b->last_buf = 1;
811
812 if (type) {
813 len = ngx_strlen(type);
814
815 r->headers_out.content_type_len = len;
816 r->headers_out.content_type.len = len;
817 r->headers_out.content_type.data = type;
818
819 } else if (doc_type == XML_HTML_DOCUMENT_NODE) {
820
821 r->headers_out.content_type_len = sizeof("text/html") - 1;
822 r->headers_out.content_type.len = sizeof("text/html") - 1;
823 r->headers_out.content_type.data = (u_char *) "text/html";
824 }
825
826 if (encoding) {
827 r->headers_out.charset.len = ngx_strlen(encoding);
828 r->headers_out.charset.data = encoding;
829 }
808 830
809 return b; 831 return b;
810 } 832 }
811 833
812 834
902 924
903 return NGX_OK; 925 return NGX_OK;
904 } 926 }
905 927
906 928
929 static u_char *
930 ngx_http_xslt_content_type(xsltStylesheetPtr s)
931 {
932 u_char *type;
933
934 if (s->mediaType) {
935 return s->mediaType;
936 }
937
938 for (s = s->imports; s; s = s->next) {
939
940 type = ngx_http_xslt_content_type(s);
941
942 if (type) {
943 return type;
944 }
945 }
946
947 return NULL;
948 }
949
950
951 static u_char *
952 ngx_http_xslt_encoding(xsltStylesheetPtr s)
953 {
954 u_char *encoding;
955
956 if (s->encoding) {
957 return s->encoding;
958 }
959
960 for (s = s->imports; s; s = s->next) {
961
962 encoding = ngx_http_xslt_encoding(s);
963
964 if (encoding) {
965 return encoding;
966 }
967 }
968
969 return NULL;
970 }
971
972
907 static void 973 static void
908 ngx_http_xslt_cleanup(void *data) 974 ngx_http_xslt_cleanup(void *data)
909 { 975 {
910 ngx_free(data); 976 ngx_free(data);
911 } 977 }