Using XSLT and FastCGI together


#1

I’m developing a web application that makes heavy use of nginx’s XSLT
support (Thank you for that!) About half of the content is in static
XML files that describes the application’s state. But when people
click on and interact with the forms and links on the page, those make
calls to URLs which get dispatched to fastcgi daemons using
fastcgi_pass.

What I’d like to do is output XML from my FastCGI daemon and feed that
through nginx’s XSLT stylesheets in order to render the dynamically-
generated page. But I’m finding that even though my fastcgi_pass
directive lives in the same location block where my xslt is defined,
nginx is sending the raw XML to the browser.

Is there a way to tell nginx to process the output of my FastCGI
script with XSLT?

Thanks.


#2

this would be a neat feature and i could possibly leverage it too,
depending on how fast nginx’s xsl transforms work. i assume pretty
fast. :slight_smile:


#3

On Wed, Apr 15, 2009 at 10:10:07AM -0700, Michael Nachbaur wrote:

directive lives in the same location block where my xslt is defined,
nginx is sending the raw XML to the browser.

Is there a way to tell nginx to process the output of my FastCGI
script with XSLT?

By default nginx processes only “text/xml” with XSLT. Probably you
send some different type. You may add it in xslt_types.


#4

On Wed, Apr 15, 2009 at 10:30:05AM -0700, Michael S. wrote:

this would be a neat feature and i could possibly leverage it too,
depending on how fast nginx’s xsl transforms work. i assume pretty
fast. :slight_smile:

No faster than libxml2/libxslt.


#5

On an Ubuntu VMWare image on my MacBook Pro, nginx+xslt was able to
perform at about 1200 r/s according to ab, with a concurrency of 500
IIRC. I couldn’t believe how fast it is. In the production
environment that I’m developing for now, we’re doing SSL so the r/s
drops significantly due to that. But still, libxslt and libxml2 are
really fast, since nginx pre-loads the stylesheets at startup.


#6

On 15-Apr-09, at 11:17 AM, Igor S. wrote:

What I’d like to do is output XML from my FastCGI daemon and feed
send some different type. You may add it in xslt_types.
I’m generating my response with XML::LibXML, and am printing the
content verbatim. My content-type is text/xml, and the content of the
request has the <?xml version=… preamble all properly set.

Have you ever seen FastCGI + XSLT working?


#7

Hello!

On Wed, Apr 15, 2009 at 10:10:07AM -0700, Michael Nachbaur wrote:

nginx is sending the raw XML to the browser.

Is there a way to tell nginx to process the output of my FastCGI script
with XSLT?

Make sure your fastcgi script returns correct Content-Type, and
this type is listed in xslt_types directive. By default
xslt_types lists text/xml only.

See http://wiki.nginx.org/NginxHttpXsltModule#xslt_types for
details.

Maxim D.


#8

On Wed, Apr 15, 2009 at 12:26:15PM -0700, Michael Nachbaur wrote:

fastcgi_pass.

By default nginx processes only “text/xml” with XSLT. Probably you
send some different type. You may add it in xslt_types.

I’m generating my response with XML::LibXML, and am printing the
content verbatim. My content-type is text/xml, and the content of the
request has the <?xml version=… preamble all properly set.

Have you ever seen FastCGI + XSLT working?

I did not test this, but it should work as XSLT is just a filter that
should work with any output. Could you show the confiration part related
to FastCGI and XSLT ?


#9

On 17-Apr-09, at 11:22 AM, Igor S. wrote:

XML files that describes the application’s state. But when people
directive lives in the same location block where my xslt is
content verbatim. My content-type is text/xml, and the content of
the
request has the <?xml version=… preamble all properly set.

Have you ever seen FastCGI + XSLT working?

I did not test this, but it should work as XSLT is just a filter that
should work with any output. Could you show the confiration part
related
to FastCGI and XSLT ?

location ^~ /replies/ {
root /persist/cluster/;
index message.xml;
if ($uri ~ /replies/(…/././././([^/]+))) {
set $message_path ‘/persist/cluster/replies/$1’;
set $reply_token $2;
}
if ($uri ~ header.$) {
error_page 404 /templates/default/header.gif;
}
if ($uri ~ footer.
$) {
error_page 404 /templates/default/footer.gif;
}
include /opt/nginx/etc/fastcgi_params;

 if ($uri ~ /send$) {
     fastcgi_pass unix://var/run/sock/fcgi-reply.sock;
 }

 xslt_stylesheet /var/www/layouts/layout1/template.xsl

reply_token
=’$reply_token’:message_path=’$message_path’:status=’$arg_status’;
xslt_stylesheet /var/www/layouts/layout2/template.xsl
reply_token
=’$reply_token’:message_path=’$message_path’:status=’$arg_status’;

 xslt_types text/xml;

}

And my FastCGI daemon that listens to that socket uses XML::LibXML to
create its response, and its content-type is text/xml. And all I get
is the plain XML back, unaltered by XSLT. Any ideas?


#10

On 11-May-09, at 11:04 PM, Igor S. wrote:

I’m developing a web application that makes heavy use of nginx’s
What I’d like to do is output XML from my FastCGI daemon and feed

I did not test this, but it should work as XSLT is just a filter
set $reply_token $2;
fastcgi_pass unix://var/run/sock/fcgi-reply.sock;
}
set $message_path ‘/persist/cluster/replies/$1’;
message_path=’$message_path’
status=’$arg_status’;

xslt_stylesheet /var/www/layouts/layout2/template.xsl
        reply_token='$reply_token'
        message_path='$message_path'
        status='$arg_status';

xslt_types text/xml;

}

Igor, you rock! Thank you, that did the trick.


#11

On Sun, Apr 19, 2009 at 07:54:34AM -0700, Michael Nachbaur wrote:

support (Thank you for that!) About half of the content is in
dynamically-

to FastCGI and XSLT ?
}
reply_token
create its response, and its content-type is text/xml. And all I get
is the plain XML back, unaltered by XSLT. Any ideas?

The problem is in “if” blocks. Try the following:

location ~ “^/replies/(.{8}/././././([^/]+))” {

 set $message_path '/persist/cluster/replies/$1';
 set $reply_token $2;

 root /persist/cluster/;
 index message.xml;

 fastcgi_pass unix://var/run/sock/fcgi-reply.sock;
 include /opt/nginx/etc/fastcgi_params;

 xslt_stylesheet /var/www/layouts/layout1/template.xsl
         reply_token='$reply_token'
         message_path='$message_path'
         status='$arg_status';

 xslt_stylesheet /var/www/layouts/layout2/template.xsl
         reply_token='$reply_token'
         message_path='$message_path'
         status='$arg_status';

 xslt_types text/xml;

}