Azure-Functions
Azure-Functions copied to clipboard
Routing fails if parameters contains slash
Hi, I see this was reported a while back and resolved, but i cannot find the resolution.
I need to be able to pass slashes in the final segment of my route:
i.e for a department called 'A/P'for i want to be able
https://somefunction/api/departments/A%2FP
I set up my route like this: Route = "departments/{dept}"
it works fine if there are no slashes (encoded as %2F) in the department, but if there is a slash it returns a 404.
How can I fix this?
@mattchenderson to redirect
@ColbyTresness I am facing the same issue. @mattchenderson can you please add something here?
The question did not specify whether its a proxy or a function, nor the programming language, but with a js function, this function.json works:
{
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"route": "departments/{*segments}",
"methods": [
"get"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
Then, in the function, you can access the segment in req.params.segments
. This is a string, and it can contain forward slashes (not sure about back slashes).
The workaround suggested by engineering- try modifying the rule like /code/{*code}
Modify the client to send requests as https://
We're deliberately url-encoding the slashes in order to not affect the request path, so I'm trying to understand why the %2F
is decoded before route matching.
With a function route /get-resources/{keyVaultUri}
a request like /get-resources/https%3A%2F%2Fsomeurl.net
works fine when debugging on a local running environment (eg. IIS-express), but will result in status code 404 on a deployed Azure Web App. Why that difference?
The * wildcard suggestion seems useful, but only if you have a single url-encoded string parameter and can control it to the end of the url. But even then, in my case (using an Azure Function V3) with the above example, I receive an argument value https:/someurl.net
(so it swallowed one of the slashes). And even with a request /get-resources/https%3A%2F%2F%2F%2F%2F%2Fsomeurl.net
it gets trimmed down to a single slash / 😞
This has to be a bug in the Azure functions runtime, as it's behaving different in debug locally and when deployed to Azure..
Anyways, I faced this issue today and figured out that it's possible to double encode the values that's sent. When doing this, the slashes in the encoded string are surviving the routing algorithm going on in the background.
Node.js example:
const encode = (id) => encodeURIComponent(encodeURIComponent(id))
const decode = (id) => decodeURIComponent(decodeURIComponent(id))
// Client side:
const id = 'TEST/ABC123'
fetch(`azure-functions-api.com/groups/${encode(id)}/members`)
.then(console.log)
.catch(console.error)
// Azure Functions side:
module.exports = (context, req) => {
const { id: rawId } = req.params
const id = decode(rawId)
// do stuff..
}
We are facing the same issue. Our http triggered functions are connected to Azure API Management and used by our customers. Recently one of our customers noticed that they could not use the identifier they wanted when using the APIs we expose.
After debugging we found that this was tied to the %2F issue others are facing.
Since the APIs we expose are used by our customers we cannot ask them to "double encode" their parameters before using the API.
Aslo, as noted before, the option of using the ${*param}
bindining will not work when there are more than one parameter in question and perhaps said parameter is not the trailing parameter of the url.
As noted by @MatsAnd, this seems only to be the case when running the function in the Azure cloud and not while developing locally.
To solve this issue now, we might need to do the double encoding ourselves in the <inbound>
rules of the API Management.
I have tried with forcing the parameter AZURE_FUNCTION_PROXY_BACKEND_URL_DECODE_SLASHES
to false
even though the documentation says that false
is the default value. No success there.
This issue has been dormant since 2018 and seems to be linked to this https://github.com/Azure/azure-functions-host/issues/2249.
hey @ingenfakir , that sounds like a great idea. hadn’t thought of that since i hadn’t used Apim. I have forgotten the context i asked my question in, but could you please let me know if this fix works for you? thanks russell
Does not seem possible to rewrite the uri in a generic way to support "double encoding" of /
.
There is a directive <find-and-replace />
but that only works for the body otherwise it could have been used as
<find-and-replace from="%2F" to="%252F" />
.
Theres also the <rewrite-uri template="uri template" copy-unmatched-params="true | false" />
but that does not support the usecase.
I've resorted to creating a support ticket from our Tenant to Azure support. Will keep this ticket updated with the answers I receive from them.
After many exchanges back and forth between me and the support team and the product team the solution was:
For resolution, the PG team says that simply, don’t pass a / in the URL part of the HTTP address. You might setup a URL Rewrite rule to look for this and then change it before it gets to the application.
Which means that there's nothing we can do but to prohibit the usage of url-encoded /
characters in our APIs or figure out a way to double encode the parameter.
We will go with the former and ask our customers to avoid encoding /
characters in the URL for now.
The only option here is to perform additional encoding on the URL before you call it, then perform the corresponding decoding on the receiving end. We used Base64 for this.
Yes @IanKemp that is true, and the issue we have is that our APIs are consumed by our customers and we don't feel like communicating to them that "For all path variables please perform two encodings since our API platform does not support single encoded path parameters".
If the consumers of the APIs were internal, this would be fine. But ours are external.
@drownintheloch Yeah, I was just giving a possible solution for anyone who is fortunate enough to not be publishing an external API.
The fact this has been an issue since 2018 and never got any attention is just bizarre to me, but sadly par for the course for Azure Functions. Microsoft honestly doesn't seem to care, the result is that using AF as a web API has gone from "not recommended" in my books to "strongly discouraged".
I've lost an afternoon to this working on dev then breaking on Azure, before finding this slash strip/replace parameter mangling. Double encoding is a potential solution for me, but it will clearly be labelled with // HACK: Remove when Microsoft fixes Azure
Same issue here. Locally everything works fine, but when deploying (over a linux container), I'm getting the bug and need to double encode :-(
Has anyone observed this same behavior with a NodeJS app hosted in Azure App Services?
As a follow up - I ran across this same issue in an Azure-hosted NodeJS container. We had some routes that had parameters with encoded slashes (like: http://our-api.com/first-param/second-param/some%2Fname
). The route worked fine running locally on a NodeJS Windows 11 x64 architecture. But it 404'd in the target Azure environment. I changed the last parameter to an encoded Query String parameter and it worked fine.