How to use RegExp in a location path on my nginx config? - regex

I have a navigation route that looks like:
/book/bookname-1234/
I have an API route to purchase the book at:
/book/1234/purchase
For the navigation route, I want my Nextjs server to handle it, but the API route I want be handled by our python server.
In my nginx config I have defined Nextjs routes with the catchall going to python.
For the navigation route, I have it set as:
location ~ /book/^[a-z]+(?:-[0-9]+)$ {
try_files $uri #nextjs;
}
I have also tried putting double quotes around the "/book/^[a-z]+(?:-[0-9]+)$"
What am I doing wrong here?

To match the url, you can use:
/book/[a-z]+-[0-9]+/$
If you want to reuse the capture group values, you can use 2 capture groups.
Note that there is an ending / in the example string, and using ^ denotes the end of the string.
/book/a-z]+-[0-9]+/$
Regex demo
Then you could use the 2 capture groups followed by the word purchase to get /book/1234/purchase

Related

my nginx regular expression routing is not working

location ~* "/mypath/([a-zA-Z0-9_.-]{12}$)" {
return 301 https://new-domain.com;
}
Above regular express is when user type https://mywebsite.com/mypath/uy2hgy12jer2 in browser, it will be redirect to https://new-domain.com. But problem is when they type https://mywebsite.com/mypath/uy2hgy12jer2?params=1287612, it's also redirected. What I want is I want to make redirect only to https://mywebsite.com/mypath/uy2hgy12jer2. Please let me know how to do it. Thanks.
Location blocks in NGINX will only match the URI part but not the query string.
Alternatively, you can use below inside location block.
if ($is_args) {
break;
}
I found this behavior after few trails in https://nginx.viraptor.info/. Any character you type after 12th character doesn't get matched except when it is a query string. Next I found the alternative I mentioned and the link below.
For more info - https://serverfault.com/questions/237517/nginx-query-keyword-matching-in-location

nginx location regex setting to return 404 only on specified url

I have wordpress pagination and I want that the www.site.com/page/1235x returning me a 404.
At the same time I don't want to disable the pagination for the entire site because I use it with other url, like /categories/page/2 or /page/2/?s=search-item .
So, I thought I need to write a nginx regex that match only a piece of the url.
I have three example url:
1. www.site.com/page/2/
2. www.site.com/page/2
3. www.site.com/page/2/?s=term-of-search
For the first and second I want to return 404 with something like this:
location ~* ^/page/\d+/?$ { return 404; }
And this matched.
For the third I don't want nothing, but that normally goes the search result.
Unfortunately, my test always select the part www.site.com/page/2/ returning 404.
I've done a lot of test with ngnix regex, also with order of them,
but I can't find a solution to this.
Any idea?
Thanks

Regex capture group in Varnish VCL

I have a URL in the form of:
http://some-site.com/api/v2/portal-name/some/webservice/call
The data I want to fetch needs
http://portal-name.com/webservices/v2/some/webservice/call
(Yes I can rewrite the application so it uses other URL's but we are testing varnish at the moment so for now it cannot be intrusive.)
But I'm having trouble getting the URL correctly in varnish VCL. The api part is replaced by an empty string, no worries but now the portal-name.
Things I've tried:
if (req.url ~ ".*/(.*)/") {
set req.http.portalhostname = re.group.0;
set req.http.portalhostname = $1;
}
From https://docs.fastly.com/guides/vcl/vcl-regular-expression-cheat-sheet and Extracting capturing group contents in Varnish regex
And yes, std is imported.
But this gives me either a
Syntax error at
('/etc/varnish/default.vcl' Line 36 Pos 35)
set req.http.portalhostname = $1;
or a
Symbol not found: 're.group.0' (expected type STRING_LIST):
So: how can I do this? When I have extracted the portalhostname I should be able to simply do a regsub to replace that value with an empty string and then prepend "webservices" and my URL is complete.
The varnish version i'm using: varnish-4.1.8 revision d266ac5c6
Sadly re.group seems to have been removed at some version. Similar functionality appears to be accessible via one of several vmods. See https://varnish-cache.org/vmods/

How to redirect in nginx if request URI does not contain certain words

I'm using nginx to serve static news-like pages.
On the top-level there is
https://example.com/en/news/ with an overview of the articles.
Individual items have a URL similar to this: https://example.com/en/news/some-article
All URLs contain the language, i.e. /en/ or /de/.
I would like to create a rule that redirects requests that don't contain the language to the correct URL (the language is mapped based on IP an available via $lang).
The following should work (en example):
/news/ --- redirect ---> /en/news/
/news/some-article --- redirect ---> /en/news/some-article
My attempts looked something like this
location ~* /news/.*$ {
if ($request_uri !~* /(de|en)/$) {
return 302 https://example.com/$lang/$request_uri;
}
}
So far this resulted in infinite redirects.
Your solution seems overly complicated to me. And testing $request_uri with a trailing $ will never match the rewritten URIs (hence the loop).
You could use a prefix location to only match URIs that begin with /news/.
Assuming that you have calculated a value for $lang elsewhere, this may work for you:
location ^~ /news/ {
return 302 /$lang$request_uri;
}
The ^~ modifier is only necessary if you have regular expression location blocks within your configuration that may conflict. See this document for more.

How to configure Fiddler's Autoresponder to "map" a host to a folder?

I'm already using Fiddler to intercept requests for specific remote files while I'm working on them (so I can tweak them locally without touching the published contents).
i.e. I use many rules like this
match: regex:(?insx).+/some_file([?a-z0-9-=&]+\.)*
respond: c:\somepath\some_file
This works perfectly.
What I'd like to do now is taking this a step further, with something like this
match: regex:http://some_dummy_domain/(anything)?(anything)
respond: c:\somepath\(anything)?(anything)
or, in plain text,
Intercept any http request to 'some_dummy_domain', go inside 'c:\somepath' and grab the file with the same path and name that was requested originally. Query string should pass through.
Some scenarios to further clarify:
http://some_domain/somefile --> c:\somepath\somefile
http://some_domain/path1/somefile --> c:\somepath\path1\somefile
http://some_domain/path1/somefile?querystring --> c:\somepath\path1\somefile?querystring
I tried to leverage what I already had:
match: regex:(?insx).+//some_dummy_domain/([?a-z0-9-=&]+\.)*
respond: ...
Basically, I'm looking for //some_dummy_domain/ in requests. This seems to match correctly when testing, but I'm missing how to respond.
Can Fiddler use matches in responses, and how could I set this up properly ?
I tried to respond c:\somepath\$1 but Fiddler seems to treat it verbatim:
match: regex:(?insx).+//some_domain/([?a-z0-9-=&]+\.)*
respond: c:\somepath\$1
request: http://some_domain/index.html
response: c:\somepath\$1html <-----------
The problem is your use of insx at the front of your expression; the n means that you want to require explicitly-named capture groups, meaning that a group $1 isn't automatically created. You can either omit the n or explicitly name the capture group.
From the Fiddler Book:
Use RegEx Replacements in Action Text
Fiddler’s AutoResponder permits you to use regular expression group replacements to map text from the Match Condition into the Action Text. For instance, the rule:
Match Text: REGEX:.+/assets/(.*)
Action Text: http://example.com/mockup/$1
...maps a request for http://example.com/assets/Test1.gif to http://example.com/mockup/Test1.gif.
The following rule:
Match Text: REGEX:.+example\.com.*
Action Text: http://proxy.webdbg.com/p.cgi?url=$0
...rewrites the inbound URL so that all URLs containing example.com are passed as a URL parameter to a page on proxy.webdbg.com.
Match Text: REGEX:(?insx).+/assets/(?'fname'[^?]*).*
Action Text C:\src\${fname}
...maps a request for http://example.com/‌assets/img/1.png?bunnies to C:\src\‌img\‌1.png.