Reputation: 30501
I have a path which starts with ~* /api/v1/(?<endpoint>.*)
. But I realize this can be misused. Is there a way to limit the number of path segments after the /api/v1
to only 3 while still being able to retain any GET variables if any?
So these will pass:
/api/v1/foo
/api/v1/foo/bar
/api/v1/foo/bar/baz
/api/v1/foo/bar/baz?x=hello&y=world
these won't:
/api/v1/foo/bar/baz/aaa
/api/v1/foo/bar/baz/aaa/n
I'm only looking at a total of 3 path segments max after /api/v1
. Anything more than that shouldn't match. Is this possible in a location block? I'm open to suggestions.
After this I use proxy_pass
on the capture group to pass it on to my FastAPI backend along with any GET variables which might exist so /api/v1/foo/bar
gets received as /foo/bar
.
Update: Added GET variables I forgot earlier.
Upvotes: 2
Views: 182
Reputation: 49792
Looking at the regular expression in your question, you will need to change the .*
sequence (which matches anything), into a sequence that only matches one, two, or three path elements.
For example:
[^/]+(/[^/]+){0,2}
For completeness, you should use the ^
and $
anchors as you are matching to an entire string. Note that the query string is not part of the normalised URI tested by a location statement.
Finally, Nginx requires any expression containing braces to be protected by quotes.
So, you could use a regular expression location as follows to match only the permitted URLs:
location ~* "^/api/v1/(?<endpoint>[^/]+(/[^/]+){0,2})$" {
...
}
A URL with too many path elements will be processed by some other location block. Generally, if no regular expression location matches a URL, the prefix location with the longest matching prefix will be used.
So, the following prefix location will match any URL that begins with /api/v1/
but does not match the regular expression location above, including those URLs with too many path elements:
location /api/v1/ {
return 444;
}
Upvotes: 0