nginx-0.7.8

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


On Tue, Aug 05, 2008 at 04:44:24PM +0400, Igor Sysoev wrote:

> On Tue, Aug 05, 2008 at 07:33:37PM +0700, Denis F. Latypoff wrote:
> 
> > >> Да, еще, если в xsl файле ошибка синтаксиса, то nginx пишет об ошибке
> > >> компиляции, но стартует. При запросе - segfault.
> > >> 
> > >> Проверить не сложно...
> 
> > > У меня выдаётся "xsltParseStylesheetFile(...) failed" и выходит.
> > 
> > Да, у меня также, если не закрыть элемент etc..
> > 
> > > Можно пример ?
> > 
> > Пишу <xsl:output method="wml" /> без media-type, перезапускаю, пишет:
> > 
> > compilation error: file /path/layout.xsl line 15 element output
> > invalid value for method: wml
> > 
> > и стартует, но segfault при запросе скорее всего из-за патча.
> 
> Понятно. У меня не падает.

Вот мой патч. 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,7 @@
     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 void ngx_http_xslt_cleanup(void *data);
 
 static char *ngx_http_xslt_entities(ngx_conf_t *cf, ngx_command_t *cmd,
@@ -131,21 +132,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 +317,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 +506,6 @@
         return;
     }
 
-    dtd->name = xmlStrdup(name);
-
     if (doc->children == NULL) {
         xmlAddChild((xmlNodePtr) doc, (xmlNodePtr) dtd);
 
@@ -732,7 +725,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 +770,17 @@
         ctx->params.nelts = 0;
     }
 
+    /* there must be at least one stylesheet */
+
+    type = ngx_http_xslt_content_type(sheet[i - 1].stylesheet);
+    encoding = sheet[i - 1].stylesheet->encoding;
+    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 +808,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 +925,28 @@
 }
 
 
+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 void
 ngx_http_xslt_cleanup(void *data)
 {


More information about the nginx-ru mailing list