I am setting up an Azure function app where I'm proxying all requests for a subdomain to one specific function. My proxies.json
looks like this:
{
"$schema": "http://json.schemastore.org/proxies",
"proxies": {
"Root URI to Trigger Function": {
"matchCondition": {
"route": "/{*path}",
"methods": [
"GET",
"POST"
]
},
"backendUri": "http://example.com/api/myfunc"
}
}
}
Inside my myfunc
function, I'm trying to access the URL of the original request using req.originalUrl
- however it's always set to http://example.com/api/myfunc
.
I tried adding request override to add an extra header, something like this:
"requestOverrides": {
"backend.request.headers.X-Original-URL": "{request.originalUrl}"
}
Yet, this doesn't work and the X-Original-Url
header contains \n\u000fx-forwarded-for\u0012\texample.com
value
How can I reliably get the original URL that my function app received?
Turns out, the original intent of originalUrl
was exactly this, to preserve the original URL as called by the user. This is how it would work if we really dealt with a node.js application without any MS proxies on it, but possible with rewrites.
So in my case I had to use requestOverrides
and custom headers to give me what I need. My proxies.json
now has this:
And in my function, I can reconstruct the URL this way:
let origHost = req.headers.hasOwnProperty('x-original-host') ? req.headers['x-original-host'] : req.headers['host'];
let origPath = req.headers.hasOwnProperty('x-original-path') ? req.headers['x-original-path'] : ''
let search = new URL(req.url).search;
let originalUrl = 'https://' + origHost + '/' + origPath + (search ? '?' : '') + search;
There doesn't seem to be a way to get the original protocol (http vs https), but in my case it doesn't matter, because I'm using https everywhere anyway.