[PATCH] Return http status code from XSLT

SamB ja.nginx at mailnull.com
Thu Apr 25 19:59:15 UTC 2013


On 11. 3. 2013 19:20, Maxim Dounin wrote:
> Hello!
>
> On Fri, Mar 08, 2013 at 12:06:48AM +0100, SamB wrote:
>
>> Hi,
>>
>>     this patch provides simple possibility to return http error code
>> from within XSLT transformation result.
>>     This is simple way to quickly and correctly return i.e. 404 error
>> codes instead of producing dummy soft-404 pages.
>>
>> Sample XSLT:
>> <xsl:template match="/">
>> <html xmlns:http="http://www.w3.org/http" status="400">
>>          <xsl:copy-of select="."/>
>> </html>
>> </xsl:template>
> While an ability to alter status code returned is intresting, I
> don't think it should be done this way, abusing output attributes.
> I would rather think of something like an XSLT variable with a
> predefined name queried after a transformation.
>
Hi,
   I've modified my previous patch to use variables as you proposed.
   Global variable HTTP_STATUS_CODE is queried to get new status code - 
maybe it
   should be bound to some namespace also (?) - I will modify patch if 
you mind so.

   Example XSLT :

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:str="http://exslt.org/strings">

<!-- FORCED HTTP STATUS CODE -->
<xsl:variable name="HTTP_STATUS_CODE" select="404"/>

<xsl:template match="/">
NOT FOUND !
</xsl:template>

</xsl:stylesheet>

Best regards
   Sam

diff --git a/src/http/modules/ngx_http_xslt_filter_module.c 
b/src/http/modules/ngx_http_xslt_filter_module.c
index a6ae1ce..b69f130 100644
--- a/src/http/modules/ngx_http_xslt_filter_module.c
+++ b/src/http/modules/ngx_http_xslt_filter_module.c
@@ -477,8 +477,10 @@ ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r,
      ngx_uint_t                        i;
      xmlChar                          *buf;
      xmlDocPtr                         doc, res;
+    xmlXPathObjectPtr                 xpathObj;
      ngx_http_xslt_sheet_t            *sheet;
      ngx_http_xslt_filter_loc_conf_t  *conf;

      conf = ngx_http_get_module_loc_conf(r, ngx_http_xslt_filter_module);
      sheet = conf->sheets.elts;
@@ -519,6 +521,25 @@ ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r,
                                        ctx->params.elts, NULL, NULL,
                                        ctx->transform);

+        xpathObj = xsltVariableLookup(ctx->transform, (const xmlChar 
*)"HTTP_STATUS_CODE", NULL);
+        if (xpathObj)
+        {
+            ngx_uint_t status = 0;
+            xmlChar *statusStr;
+
+            statusStr = xmlXPathCastToString(xpathObj);
+            status = strtoul((const char *)statusStr, NULL, 10);
+
+            if (status > 0
+                && r->headers_out.status != status)
+            {
+                r->headers_out.status =        status;
+                r->headers_out.status_line.len = 0;
+            }
+
+            xmlXPathFreeObject(xpathObj);
+       }
+
          xsltFreeTransformContext(ctx->transform);
          xmlFreeDoc(doc);






More information about the nginx-devel mailing list