[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