Using XSLT and FastCGI together

Michael Nachbaur mike at nachbaur.com
Tue May 12 23:36:34 MSD 2009


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

> On Sun, Apr 19, 2009 at 07:54:34AM -0700, Michael Nachbaur wrote:
>
>> On 17-Apr-09, at 11:22 AM, Igor Sysoev wrote:
>>
>>> On Wed, Apr 15, 2009 at 12:26:15PM -0700, Michael Nachbaur wrote:
>>>
>>>> On 15-Apr-09, at 11:17 AM, Igor Sysoev wrote:
>>>>
>>>>> On Wed, Apr 15, 2009 at 10:10:07AM -0700, Michael Nachbaur wrote:
>>>>>
>>>>>> 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?
>>>>>
>>>>> 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 ?
>>
>> 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?
>
> 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;
> }

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





More information about the nginx mailing list