<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<div name="messageBodySection">
<div dir="auto">Is there a good way to reliably filter the response body from a FastCGI script via NJS? I’ve done this with Lua before but NJS seems to be a bit different in terms of how the response body process works. The end goal is basically that we just have a way to grab the text back from a FastCGI/PHP script and can then edit that response. There’s a very specific end goal that we are trying to achieve that has to go through Nginx and can’t be done with PHP.<br />
<br />
Initially I tried just using something like r.responseText since the call to FastCGI in Nginx should be its own subrequest but that doesn’t seem to work. I’ve tried via js_body_filter but that keeps returning what looks like either encrypted or compressed data even though PHP compression is off and the FastCGI upstream is for a socket on the same server defined as another location in the same vhost (so the connection to the socket shouldn’t be suffering from encryption in that layer).<br />
<br />
I’ve tried a few different options:<br />
<br />
location = /index.php {<br />
<span style="white-space:pre"> include includes/fastcgi.conf;</span><br />
<br />
<span style="white-space:pre"> js_body_filter db.failed;</span><br />
<br />
<span style="white-space:pre"> fastcgi_pass unix:/var/run/php-fpm/account.sock;</span><br />
}<br />
<br />
With this being the function in db.js<br />
<br />
<span style="color:#cd8d4e;background-color:#383939">function</span><span style="color:#ffffff;background-color:#383939"> </span><span style="color:#a97a8c;background-color:#383939">failed</span><span style="color:#ffffff;background-color:#383939">(</span><em style="color:#d9dbfc;background-color:#383939">r</em><span style="color:#ffffff;background-color:#383939">, </span><em style="color:#d9dbfc;background-color:#383939">data</em><span style="color:#ffffff;background-color:#383939">, </span><em style="color:#d9dbfc;background-color:#383939">flags</em><span style="color:#ffffff;background-color:#383939">){</span><br />
<span style="color:#ffffff;background-color:#383939"> </span><span style="color:#d9dbfc;background-color:#383939">r</span><span style="color:#c4bc3c;background-color:#383939">.</span><span style="color:#a97a8c;background-color:#383939">error</span><span style="color:#ffffff;background-color:#383939">(</span><span style="color:#d9dbfc;background-color:#383939">data</span><span style="color:#ffffff;background-color:#383939">);</span><br />
<span style="color:#ffffff;background-color:#383939"> </span><span style="color:#d9dbfc;background-color:#383939">r</span><span style="color:#c4bc3c;background-color:#383939">.</span><span style="color:#a97a8c;background-color:#383939">sendBuffer</span><span style="color:#ffffff;background-color:#383939">(</span><span style="color:#d9dbfc;background-color:#383939">data</span><span style="color:#ffffff;background-color:#383939">);</span><br />
<span style="color:#ffffff;background-color:#383939">}</span><br />
<br />
<span style="color:#ffffff;background-color:rgba(0, 0, 0, 0)">r.error is just there to log the response as a test to see what it is structured like to code further from there. That logs data like this:</span><br />
<span style="white-space:pre">2022/02/16 11:56:20 [error] 18589#18589: *61 js: �Z�r���) (ڕ��;�����LB��,��Y�;�rMa�3�b��!E�\��9/�C�KN�J�>%����()`fwv��%��A�,�u����n�4�{����?���^>;�ljI9�Dē&�&�LM�ܨ&�8�zҌ%S@Ű���� �S0E Q��f����+�Ia�LA)PERf��lU���2�F�`���fKȩ�\^V�1Y</span><br />
^��b��n�:h�4#����O�i<br />
��Fߏ=��93��O0���(Q0��)��?�,���<br />
<br />
The response from the PHP file is just basic HTML so it shouldn’t look like this. <br />
<br />
I’ve also tried using a js_content filter to try to use a subrequest to the PHP location block in the vhost, but that doesn’t seem to work at all. It just errs out. Here’s a very basic attempt to try to use that location. I’ve tried this both with the named location block and a custom named internal block that I called /fastcgi to try to use the URI style syntax in the sub request.<br />
<br />
The js_content filter is in a location block and is calling successfully but the code that it runs fails when trying to sub request to FastCGI. Here’s a rough example that I’ve tried.<br />
<br />
location = /fastcgi {<br />
<span style="white-space:pre"> internal;</span><br />
<span style="white-space:pre"> include includes/fastcgi.conf;</span><br />
<br />
<span style="white-space:pre"> fastcgi_pass unix:/var/run/php-fpm/dbadmin.sock;</span><br />
}<br />
<br />
<span style="color:#cd8d4e;background-color:#383939">async</span><span style="color:#ffffff;background-color:#383939"> </span><span style="color:#cd8d4e;background-color:#383939">function</span><span style="color:#ffffff;background-color:#383939"> </span><span style="color:#a97a8c;background-color:#383939">content</span><span style="color:#ffffff;background-color:#383939">(</span><em style="color:#d9dbfc;background-color:#383939">r</em><span style="color:#ffffff;background-color:#383939">){</span><br />
<span style="color:#ffffff;background-color:#383939"> </span><span style="color:#cd8d4e;background-color:#383939">await</span><span style="color:#ffffff;background-color:#383939"> </span><span style="color:#d9dbfc;background-color:#383939">r</span><span style="color:#c4bc3c;background-color:#383939">.</span><span style="color:#a97a8c;background-color:#383939">subrequest</span><span style="color:#ffffff;background-color:#383939">(</span><span style="color:#b9c87f;background-color:#383939">'/fastcgi'</span><span style="color:#ffffff;background-color:#383939">, {</span><br />
<span style="color:#ffffff;background-color:#383939"> </span><span style="color:#d9dbfc;background-color:#383939">body</span><span style="color:#c4bc3c;background-color:#383939">:</span><span style="color:#ffffff;background-color:#383939"> </span><span style="color:#d9dbfc;background-color:#383939">r</span><span style="color:#c4bc3c;background-color:#383939">.</span><span style="color:#d9dbfc;background-color:#383939">requestBuffer</span><span style="color:#ffffff;background-color:#383939">,</span><br />
<span style="color:#ffffff;background-color:#383939"> </span><span style="color:#d9dbfc;background-color:#383939">method</span><span style="color:#c4bc3c;background-color:#383939">:</span><span style="color:#ffffff;background-color:#383939"> </span><span style="color:#d9dbfc;background-color:#383939">r</span><span style="color:#c4bc3c;background-color:#383939">.</span><span style="color:#d9dbfc;background-color:#383939">method</span><span style="color:#ffffff;background-color:#383939">,</span><br />
<span style="color:#ffffff;background-color:#383939"> </span><span style="color:#d9dbfc;background-color:#383939">detached</span><span style="color:#c4bc3c;background-color:#383939">:</span><span style="color:#ffffff;background-color:#383939"> </span><span style="color:#86a9c4;background-color:#383939">false</span><br />
<span style="color:#ffffff;background-color:#383939"> }, </span><span style="color:#cd8d4e;background-color:#383939">function</span><span style="color:#ffffff;background-color:#383939">(</span><em style="color:#d9dbfc;background-color:#383939">r</em><span style="color:#ffffff;background-color:#383939">){</span><br />
<span style="color:#ffffff;background-color:#383939"> </span><span style="color:#cd8d4e;background-color:#383939">return</span><span style="color:#ffffff;background-color:#383939"> </span><span style="color:#d9dbfc;background-color:#383939">r</span><span style="color:#c4bc3c;background-color:#383939">.</span><span style="color:#d9dbfc;background-color:#383939">responseText</span><span style="color:#ffffff;background-color:#383939">;</span><br />
<span style="color:#ffffff;background-color:#383939"> });</span><br />
<span style="color:#ffffff;background-color:#383939">}</span><br />
<br />
<br />
<span style="color:#ffffff;background-color:rgba(0, 0, 0, 0)">That just seems to err like this:</span><br />
<br />
<span style="background-color:rgba(0, 0, 0, 0)">2022/02/16 11:53:37 [error] 16995#16995: *54 FastCGI sent in stderr: "Access to the script '/home/account/www/fastcgi' has been denied (see security.limit_extensions)" while reading response header from upstream, client: 68.109.218.131, server:</span><a style="background-color:rgba(0, 0, 0, 0)" href="http://db-ngxtest.wordkeeper.net" target="_blank">t</a><span style="background-color:rgba(0, 0, 0, 0)">request: "GET /index.php HTTP/2.0", subrequest: "/fastcgi", upstream: "fastcgi://unix:/var/run/php-fpm/account.sock:"</span><br />
<br />
<span style="color:#ffffff;background-color:rgba(0, 0, 0, 0)">The specific solution strategy doesn’t particularly matter as long as the end result is that we can receive and interact with the response body from a FastCGI request.</span><br />
<br />
<span style="color:#ffffff;background-color:rgba(0, 0, 0, 0)">Does anyone have any ideas of how to just get the response body from a FastCGI request in NJS? </span><br />
<br />
<span style="color:#ffffff;background-color:rgba(0, 0, 0, 0)">Any insights would be a huge help.</span></div>
</div>
<div name="messageSignatureSection"><br />
<div class="matchFont"><br />
--<br />
Lance Dockins<br />
<br /></div>
</div>
</body>
</html>