[PATCH] xslt: return http status code from XSLT via variable

Samuel Behan dob-devel at dob.sk
Thu Aug 15 16:25:09 UTC 2019


# HG changeset patch
# User Samuel Behan <dob-devel at dob.sk>
# Date 1565880799 -7200
#      Thu Aug 15 16:53:19 2019 +0200
# Node ID bd497930fa90aee4a5c3d90917c6706fe93b73be
# Parent  d30b1a99fcd053def84517d47654767548c827c9
xslt: return http status code from XSLT via variable

This patch introduces possibility to modify http status code of the response using
xslt variable named HTTP_STATUS_CODE. This is usefull ie. when processing results
from some search engine (SOLR in my case) and when 0 matching results has been found
the page is able to return 'hard' 404 response.

Example usage:

<xsl:variable name="HTTP_STATUS_CODE" select="404"/>

diff -r d30b1a99fcd0 -r bd497930fa90 src/http/modules/ngx_http_xslt_filter_module.c
--- a/src/http/modules/ngx_http_xslt_filter_module.c	Tue Aug 13 15:45:57 2019 +0300
+++ b/src/http/modules/ngx_http_xslt_filter_module.c	Thu Aug 15 16:53:19 2019 +0200
@@ -491,9 +491,11 @@
     int                               len, rc, doc_type;
     u_char                           *type, *encoding;
     ngx_buf_t                        *b;
+    ngx_int_t                         status;
     ngx_uint_t                        i;
-    xmlChar                          *buf;
+    xmlChar                          *buf, *status_str;
     xmlDocPtr                         doc, res;
+    xmlXPathObjectPtr                 obj;
     ngx_http_xslt_sheet_t            *sheet;
     ngx_http_xslt_filter_loc_conf_t  *conf;
 
@@ -536,6 +538,31 @@
                                       ctx->params.elts, NULL, NULL,
                                       ctx->transform);
 
+        obj = xsltVariableLookup(ctx->transform,
+                                 (const xmlChar *) "HTTP_STATUS_CODE",
+                                 NULL);
+        if (obj) {
+            status_str = xmlXPathCastToString(obj);
+            xmlXPathFreeObject(obj);
+
+            if (status_str) {
+                status = strtol((const char *) status_str, NULL, 10);
+                xmlFree(status_str);
+
+                if (status <= 99
+                    || status >= 1000)
+                {
+                    ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                          "xslt response var HTTP_STATUS_CODE value invalid");
+                    return NULL;
+
+                } else if (r->headers_out.status != (ngx_uint_t) status) {
+                    r->headers_out.status = (ngx_uint_t) status;
+                    r->headers_out.status_line.len = 0;
+                }
+            }
+        }
+
         xsltFreeTransformContext(ctx->transform);
         xmlFreeDoc(doc);
 


More information about the nginx-devel mailing list