nginx-0.7.8

Igor Sysoev is at rambler-co.ru
Tue Aug 5 17:23:03 MSD 2008


On Tue, Aug 05, 2008 at 05:19:20PM +0400, Igor Sysoev wrote:

> > > То есть, нужно искать по импортам до первого ненулевого mediaType ?
> > > Ну, и естественно, сначала проверять mediaType в самом xsl.
> > 
> > Да. И encoding тоже.
> 
> OK.

Патч. Те же и encoding.


-- 
Игорь Сысоев
http://sysoev.ru
-------------- next part --------------
Index: src/http/modules/ngx_http_xslt_filter_module.c
===================================================================
--- src/http/modules/ngx_http_xslt_filter_module.c	(revision 1469)
+++ src/http/modules/ngx_http_xslt_filter_module.c	(working copy)
@@ -35,7 +35,7 @@
 
 typedef struct {
     xmlDtdPtr            dtd;
-    ngx_array_t          sheets;        /* ngx_http_xslt_sheet_t */
+    ngx_array_t          sheets;       /* ngx_http_xslt_sheet_t */
     ngx_hash_t           types;
     ngx_array_t         *types_keys;
 } ngx_http_xslt_filter_conf_t;
@@ -47,8 +47,8 @@
     xmlSAXHandler       *sax;
     ngx_http_request_t  *request;
     ngx_array_t          params;
-    unsigned             done:1;
-    unsigned             html:1;
+
+    ngx_uint_t           done;         /* unsigned  done:1; */
 } ngx_http_xslt_filter_ctx_t;
 
 
@@ -109,6 +109,8 @@
     ngx_http_xslt_filter_ctx_t *ctx);
 static ngx_int_t ngx_http_xslt_params(ngx_http_request_t *r,
     ngx_http_xslt_filter_ctx_t *ctx, ngx_array_t *params);
+static u_char *ngx_http_xslt_content_type(xsltStylesheetPtr s);
+static u_char *ngx_http_xslt_encoding(xsltStylesheetPtr s);
 static void ngx_http_xslt_cleanup(void *data);
 
 static char *ngx_http_xslt_entities(ngx_conf_t *cf, ngx_command_t *cmd,
@@ -131,21 +133,21 @@
 static ngx_command_t  ngx_http_xslt_filter_commands[] = {
 
     { ngx_string("xml_entities"),
-      NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
       ngx_http_xslt_entities,
       NGX_HTTP_LOC_CONF_OFFSET,
       0,
       NULL },
 
     { ngx_string("xslt_stylesheet"),
-      NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_1MORE,
+      NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
       ngx_http_xslt_stylesheet,
       NGX_HTTP_LOC_CONF_OFFSET,
       0,
       NULL },
 
     { ngx_string("xslt_types"),
-      NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_1MORE,
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
       ngx_http_types_slot,
       NGX_HTTP_LOC_CONF_OFFSET,
       offsetof(ngx_http_xslt_filter_conf_t, types_keys),
@@ -316,12 +318,6 @@
                                                NGX_HTTP_INTERNAL_SERVER_ERROR);
     }
 
-    if (ctx->html) {
-        r->headers_out.content_type_len = sizeof("text/html") - 1;
-        r->headers_out.content_type.len = sizeof("text/html") - 1;
-        r->headers_out.content_type.data = (u_char *) "text/html";
-    }
-
     r->headers_out.content_length_n = b->last - b->pos;
 
     if (r->headers_out.content_length) {
@@ -511,8 +507,6 @@
         return;
     }
 
-    dtd->name = xmlStrdup(name);
-
     if (doc->children == NULL) {
         xmlAddChild((xmlNodePtr) doc, (xmlNodePtr) dtd);
 
@@ -732,7 +726,8 @@
 ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r,
     ngx_http_xslt_filter_ctx_t *ctx)
 {
-    int                           len, rc;
+    int                           len, rc, doc_type;
+    u_char                       *type, *encoding;
     ngx_buf_t                    *b;
     ngx_uint_t                    i;
     xmlChar                      *buf;
@@ -776,11 +771,17 @@
         ctx->params.nelts = 0;
     }
 
+    /* there must be at least one stylesheet */
+
+    type = ngx_http_xslt_content_type(sheet[i - 1].stylesheet);
+    encoding = ngx_http_xslt_encoding(sheet[i - 1].stylesheet);
+    doc_type = doc->type;
+
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                   "xslt filter doc type: %d", doc->type);
+                   "xslt filter type: %d t:%s e:%s",
+                   doc_type, type ? type : (u_char *) "(null)",
+                   encoding ? encoding : (u_char *) "(null)");
 
-    ctx->html = (doc->type == XML_HTML_DOCUMENT_NODE) ? 1 : 0;
-
     rc = xsltSaveResultToString(&buf, &len, doc, sheet[i - 1].stylesheet);
 
     xmlFreeDoc(doc);
@@ -808,6 +809,25 @@
     b->memory = 1;
     b->last_buf = 1;
 
+    if (type) {
+        len = ngx_strlen(type);
+
+        r->headers_out.content_type_len = len;
+        r->headers_out.content_type.len = len;
+        r->headers_out.content_type.data = type;
+
+    } else if (doc_type == XML_HTML_DOCUMENT_NODE) {
+
+        r->headers_out.content_type_len = sizeof("text/html") - 1;
+        r->headers_out.content_type.len = sizeof("text/html") - 1;
+        r->headers_out.content_type.data = (u_char *) "text/html";
+    }
+
+    if (encoding) {
+        r->headers_out.charset.len = ngx_strlen(encoding);
+        r->headers_out.charset.data = encoding;
+    }
+
     return b;
 }
 
@@ -906,6 +926,50 @@
 }
 
 
+static u_char *
+ngx_http_xslt_content_type(xsltStylesheetPtr s)
+{
+    u_char  *type;
+
+    if (s->mediaType) {
+        return s->mediaType;
+    }
+
+    for (s = s->imports; s; s = s->next) {
+
+        type = ngx_http_xslt_content_type(s);
+
+        if (type) {
+            return type;
+        }
+    }
+
+    return NULL;
+}
+
+
+static u_char *
+ngx_http_xslt_encoding(xsltStylesheetPtr s)
+{
+    u_char  *encoding;
+
+    if (s->encoding) {
+        return s->encoding;
+    }
+
+    for (s = s->imports; s; s = s->next) {
+
+        encoding = ngx_http_xslt_encoding(s);
+
+        if (encoding) {
+            return encoding;
+        }
+    }
+
+    return NULL;
+}
+
+
 static void
 ngx_http_xslt_cleanup(void *data)
 {


More information about the nginx-ru mailing list