NJS Body File Access Race Condition?

Lance Dockins lance at wordkeeper.com
Sat Feb 11 02:24:38 UTC 2023


NJS seems to be throwing an error when trying to access the temp body file
created for POST bodies that are larger than the client body buffer size.

I've verified that Nginx and NJS have access to this folder location.  As a
test, I placed a permanent file in the body temp folder location and can
read from that file without an issue in NJS code.  But if I grab the full
path to the temp body file from Nginx and then try to read that file's
contents, NJS throws an error indicating that the file doesn't exist.

Here's a code sample:
let body = '';
if(!r.variables.request_body_file){

body = r.requestText;

}
else{

log.write(logpath, r.variables.request_body_file, r);
let fs = require('fs');
body = fs.readFileSync(r.variables.request_body_file);

}

The log.write call is a utility function that just allows me to log the
contents of the variable in the sample.  In this code,
r.variables.request_body_file logs a full file path to the temp file for
the POST body.  Something like this:
/var/lib/nginx/body/0000000128

But trying to access and read that file immediately following that
yields an error:
2023/02/10 20:14:05 [error] 609307#609307: *1555 js exception: Error: No
such file or directory
    at fs.readFileSync (native)

Again, it's not a permissions issue as a permanent test file exists in the
same folder and is readable in the same code block without an issue.

This code is currently inside of a js_content filter.  Since js_content
runs very late in the process, the temp file seems like it "should" still
be in place.  After all, reading r.requestText works just fine.  The only
time the problem surfaces is when the client body exceeds the buffer size
(even if the buffer size is high) as that's where file access has to
occur.  Since the POST bodies can sometimes be very large in this
particular route, it's not really a viable option to try to match the
client body buffer size to the client body max size.  So being able to
access and read the POST body temp file is important since there are bound
to be situations where a request crosses beyond the buffer size regardless
of how high it goes (not that higher is necessarily always a good idea).

This sort of NJS behavior "seems" like some sort of race condition where
NJS is trying to access the file after Nginx has already disposed of it.
Since this is a js_content directive, it should be blocking and it seems to
be one of the few stages where access to the POST body is even possible.
So it's unclear why the client body buffer file wouldn't exist at the time
that this code runs.

Is this a bug in NJS?  Or is there some sort of alternative solution (e.g.
settings adjustment in Nginx itself) that might resolve the problem?

Thanks in advance for any insights.


-- 
Lance Dockins
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx/attachments/20230210/0562c4c8/attachment.htm>


More information about the nginx mailing list