Forum: NGINX EXSLT func:function not registered for XSLT filter module

4a9ad756d92bdf75252b9296e27fc8ad?d=identicon&s=25 Kate F (Guest)
on 2013-07-13 12:20
(Received via mailing list)
Hi,

I'm trying to use EXSLT's <func:function> with nginx's xslt filter
module. The effect I think I'm seeing is that my functions are
seemingly ignored.

I made a test XSLT stylesheet:

    iona% cat xsl/fish.xsl
    <?xml version="1.0"?>

    <xsl:stylesheet version="1.0"
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:x="http://xml.elide.org/fish"
         xmlns:func="http://exslt.org/functions"

        extension-element-prefixes="func">

        <func:function name="x:fish">
            <func:result select="123"/>
        </func:function>

        <xsl:output method="text" encoding="utf-8"
            media-type="plain/text"/>

        <xsl:template match="/">
            <xsl:value-of select="x:fish()"/>
            <xsl:text>&#10;</xsl:text>
        </xsl:template>

    </xsl:stylesheet>

    iona% xsltproc xsl/fish.xsl vhost/blog.libfsm.org/index.xhtml5
    123
    iona%

I would expect my <xsl:value-of select="x:fish()"/> there to give the
same result as under xsltproc. But running the same under nginx gives:

    xmlXPathCompOpEval: function fish not found
    XPath error : Unregistered function
    xmlXPathCompiledEval: evaluation failed
    runtime error: file /home/kate/svn/www/xsl/fish.xsl line 19 element
value-of
    XPath evaluation returned no result.

Looking at ngx_http_xslt_filter_module.c I see exsltRegisterAll() is
called, which is what should register libexslt's handler for
func:function and friends:

    #if (NGX_HAVE_EXSLT)
        exsltRegisterAll();
    #endif

I know NGX_HAVE_EXSLT is defined because other EXSLT functions (such
as things in the date: and str: namespaces) work fine.

I'm using nginx 1.4.1, which is linked to the same libexslt as my
xsltproc.

Any suggestions, please?

--
Kate
A8108a0961c6087c43cda32c8616dcba?d=identicon&s=25 Maxim Dounin (Guest)
on 2013-07-15 19:32
(Received via mailing list)
Hello!

On Sat, Jul 13, 2013 at 12:19:51PM +0200, Kate F wrote:

> Hi,
>
> I'm trying to use EXSLT's <func:function> with nginx's xslt filter
> module. The effect I think I'm seeing is that my functions are
> seemingly ignored.

[...]

> Looking at ngx_http_xslt_filter_module.c I see exsltRegisterAll() is
> called, which is what should register libexslt's handler for
> func:function and friends:
>
>     #if (NGX_HAVE_EXSLT)
>         exsltRegisterAll();
>     #endif
>
> I know NGX_HAVE_EXSLT is defined because other EXSLT functions (such
> as things in the date: and str: namespaces) work fine.

It looks like exsltRegisterAll() is called too late for EXSLT
Functions extension.

Please try the following patch:

# HG changeset patch
# User Maxim Dounin <mdounin@mdounin.ru>
# Date 1373909466 -14400
# Node ID bc1cf51a5b0a5e8512a8170dc7991f9e966c5533
# Parent  8e7db77e5d88b20d113e77b574e676737d67bf0e
Xslt: exsltRegisterAll() moved to preconfiguration.

The exsltRegisterAll() needs to be called before XSLT stylesheets
are compiled, else stylesheet compilation hooks will not work.  This
change fixes EXSLT Functions extension.

diff --git a/src/http/modules/ngx_http_xslt_filter_module.c
b/src/http/modules/ngx_http_xslt_filter_module.c
--- a/src/http/modules/ngx_http_xslt_filter_module.c
+++ b/src/http/modules/ngx_http_xslt_filter_module.c
@@ -104,6 +104,7 @@ static void *ngx_http_xslt_filter_create
 static void *ngx_http_xslt_filter_create_conf(ngx_conf_t *cf);
 static char *ngx_http_xslt_filter_merge_conf(ngx_conf_t *cf, void
*parent,
     void *child);
+static ngx_int_t ngx_http_xslt_filter_preconfiguration(ngx_conf_t *cf);
 static ngx_int_t ngx_http_xslt_filter_init(ngx_conf_t *cf);
 static void ngx_http_xslt_filter_exit(ngx_cycle_t *cycle);

@@ -163,7 +164,7 @@ static ngx_command_t


 static ngx_http_module_t  ngx_http_xslt_filter_module_ctx = {
-    NULL,                                  /* preconfiguration */
+    ngx_http_xslt_filter_preconfiguration, /* preconfiguration */
     ngx_http_xslt_filter_init,             /* postconfiguration */

     ngx_http_xslt_filter_create_main_conf, /* create main configuration
*/
@@ -1111,7 +1112,7 @@ ngx_http_xslt_filter_merge_conf(ngx_conf


 static ngx_int_t
-ngx_http_xslt_filter_init(ngx_conf_t *cf)
+ngx_http_xslt_filter_preconfiguration(ngx_conf_t *cf)
 {
     xmlInitParser();

@@ -1119,6 +1120,13 @@ ngx_http_xslt_filter_init(ngx_conf_t
     exsltRegisterAll();
 #endif

+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_xslt_filter_init(ngx_conf_t *cf)
+{
     ngx_http_next_header_filter = ngx_http_top_header_filter;
     ngx_http_top_header_filter = ngx_http_xslt_header_filter;



--
Maxim Dounin
http://nginx.org/en/donation.html
4a9ad756d92bdf75252b9296e27fc8ad?d=identicon&s=25 Kate F (Guest)
on 2013-07-17 18:18
(Received via mailing list)
On 15 July 2013 19:32, Maxim Dounin <mdounin@mdounin.ru> wrote:
> [...]
>> as things in the date: and str: namespaces) work fine.
> # Parent  8e7db77e5d88b20d113e77b574e676737d67bf0e
> Xslt: exsltRegisterAll() moved to preconfiguration.
>
> The exsltRegisterAll() needs to be called before XSLT stylesheets
> are compiled, else stylesheet compilation hooks will not work.  This
> change fixes EXSLT Functions extension.

Awesome! Good catch.

Thanks for that. Your patch works fine.

--
Kate
A8108a0961c6087c43cda32c8616dcba?d=identicon&s=25 Maxim Dounin (Guest)
on 2013-07-19 14:04
(Received via mailing list)
Hello!

On Wed, Jul 17, 2013 at 06:18:03PM +0200, Kate F wrote:

> >
> >> I know NGX_HAVE_EXSLT is defined because other EXSLT functions (such
> > # Node ID bc1cf51a5b0a5e8512a8170dc7991f9e966c5533
> > # Parent  8e7db77e5d88b20d113e77b574e676737d67bf0e
> > Xslt: exsltRegisterAll() moved to preconfiguration.
> >
> > The exsltRegisterAll() needs to be called before XSLT stylesheets
> > are compiled, else stylesheet compilation hooks will not work.  This
> > change fixes EXSLT Functions extension.
>
> Awesome! Good catch.
>
> Thanks for that. Your patch works fine.

Committed, thanks for testing.

--
Maxim Dounin
http://nginx.org/en/donation.html
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.