Last active
February 23, 2023 17:39
-
-
Save 4141done/e23c52cd9803b366212dfcc2226c12d6 to your computer and use it in GitHub Desktop.
Example of choosing an upstream based on request body and proxying with subrequest
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#user nobody; | |
worker_processes 1; | |
#error_log logs/error.log; | |
#error_log logs/error.log notice; | |
#error_log logs/error.log info; | |
#pid logs/nginx.pid; | |
load_module modules/ngx_http_js_module.so; | |
error_log /tmp/dev.log debug; | |
events { | |
worker_connections 1024; | |
} | |
http { | |
js_import script from script.js; | |
include mime.types; | |
default_type application/json; | |
js_var $machine; | |
js_var $nodename; | |
js_var $redirectKey; | |
log_format my_custom_log_format ‘$machine - $nodename’; | |
server { | |
listen 4000; | |
access_log /tmp/nginx-access.log my_custom_log_format; | |
location /foo { | |
js_content script.handleRequest; | |
} | |
location /upstream_one { | |
js_content script.upstreamOne; | |
} | |
location /upstream_two { | |
return 200 "this is upstream two"; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
async function handleRequest (r) { | |
// Since this handler is invoked with `js_content`, r.requestText | |
// is guaranteed to be present | |
const body = r.requestText; | |
// some logic to process the body | |
// the below variable is a stand-in for the result of that | |
// processing | |
const parsedRequestBody = { | |
machine: "the machine", | |
nodename: "the nodename", | |
redirectKey: "upstream_one" // change this to see different upstreams | |
}; | |
for (const key in parsedRequestBody) { | |
r.variables[key] = parsedRequestBody[key]; | |
} | |
// Here's the redirect. r.subrequest mirrors the headers | |
// and body of the parent response to the target of the subrequest | |
let upstreamResponse; | |
if (parsedRequestBody.redirectKey === "upstream_one") { | |
upstreamResponse = await r.subrequest("/upstream_one"); | |
} else { | |
upstreamResponse = await r.subrequest("/upstream_two"); | |
} | |
// The following code passes the response from the upstream back including | |
// status, body, and headers | |
// Doing this makes sure headers added in the upstream get passed back | |
r.headersOut = Object.assign(r.headersOut, upstreamResponse.headersOut); | |
// Mirror the upstream response status and body | |
r.return(upstreamResponse.status, upstreamResponse.responseText); | |
} | |
// Just adding this as a njs handler so we can easily see what the upstream | |
// will receive in terms of body and headers | |
function upstreamOne(r) { | |
r.error(`headers received in upstream_one: ${JSON.stringify(r.rawHeadersIn)}`); | |
r.error(`body received in upstream_one: ${r.requestText}`); | |
r.headersOut['upstream-one-added'] = "Upstream one added this header"; | |
r.return(200, "This is the body of the response from upstream_one"); | |
} | |
export default { handleRequest, upstreamOne }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment