I have the following workflow in an nginx.conf file and NJS files:
server, location)js_content)I found that the returning Content-type header is lost. The external server returns application/json while the nginx returns text/plain. I don't see the Content-type field in the NJS code when processing the response of the subrequest (reply.headersOut). But if I call the proxy_pass directly (without NJS subrequest) then the response contains the proper Content-type header.
Edit: I do see the X-Powered-By header in reply.headersOut and others as well. So it's not that all of the headers are lost. But Content-Type and Content-Length are missing indeed.
Maybe I missed something or something avoided my attention in the docs, dunno... but it might as well be a bug.
=== CONFIGS ===
nginx.conf entry:
location /endpoint {
js_content execRequest;
}
In the execRequest implementation. (I tried with and without the commented part.)
r.subrequest('/proxy/endpoint', {
method: method,
body: r.requestBody,
}).then(reply => {
r.status = reply.status;
// No Content-type in the reply.headersOut
// for (var header in reply.headersOut) { // This might or might not required
// r.headersOut[header] = reply.headersOut[header];
// }
r.sendHeader();
r.send(reply.responseBody);
r.finish();
});
And the proxy:
location /proxy {
# internal; // Turned off to check it manually
proxy_pass_request_headers on;
location /proxy/endpoint {
proxy_pass http://$external_service/endpoint;
}
}
Hi, @igabesz
what version of njs are you using?
See this commit https://github.com/nginx/njs/commit/2bd9dc97d3a733f3e81db3296ef3a7361d80b752, it was released as a part of 0.4.0.
The issue is that the Content-Type was available as r.headersOut["Content-type"], but was invisible during iterations over r.headersOut (because nginx stores content_type field in a special way).
The workaround for 0.3.9 and before is to copy Content-Type manually:
r.headersOut['Content-Type'] = reply.headersOut['Content-Type'];
r.headersOut['Content-Length'] = reply.headersOut['Content-Length'];
Also, this change https://github.com/nginx/njs/commit/f9a00172aa17c322f1d930786af00b84821c0c1e solves "Set-Cookie" issue, when only one Set-Cookie headers was available (#298). For "Set-Cookie" issue there is no simple workaround for 0.3.9 and before.
Thanks, it works with 0.4.0! Now it copies all of the headers from the reply of the subrequest to the main response.
I was using nginx:latest (1.17.10 with NJS 3.9), now I moved to nginx:stable (1.18.0 with NJS 0.4.0) and it works smoothly.