azureazure-functionsazure-function-app-proxy

In Azure function with proxy, get original URL


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?


Solution

  • 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.