my nginx regular expression routing is not working - regex

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

Related

Nginx rewrite rule is not working if hash in the url

I have written nginx rewrite rule to redirect all request for /path/category except subcategory1. I am using below regular expression for match and it is working fine in regex tester. However, when I am providing same regex in Nginx conf then it is not working for negative lookahead if url contains the # character. Do you have any suggestions?
Regex tried so far:
^\/path\/category(?!.*(\bsubcategory1\b)).*$
^\/path\/category(([\/#]*)(?!.*(subcategory1))).*$
Rewrite Rule:
rewrite ^\/path\/category(?!.*(\bsubcategory1\b)).*$ https://new.host.com permanent;
Path Details:
It should redirect to https://new.host.com which is working fine
/path/category
/path/category/
/path/category#/
/path/category/#/
skip the redirection for subcategory1 . It is not working for last 3 urls that contains hash.
/path/category/subcategory1
/path/category/subcategory1/
/path/category/subcategory1/dsadasd
/path/category#/subcategory1
/path/category/#/subcategory1
/path/category#/subcategory1/dadsd
Anything in the URI after # is ignored because it is supposed to be client side so it never gets to HTTP server (Nginx for instance).
Nginx regex will show abnormal behavior if a # is in the string under processing.
The part after # is called fragment.
The fragment can be processed at client side.
You can use window.location.hash to access and process fragments.
This Javascript example transform fragment in parameters in a request to process.html :
let param = window.location.hash;
param = param.substring(1); // remove #
param = '?' + param;
console.log('param=',param);
location.href = '/process.html' + param;

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

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.

match and redirect "http://" (double slash) from URI path with nginx

I want nginx return 'http://example.com' with request url 'http://mydomain/url=http://example.com' use conf blow, but it give me 'http:/xxx.com'.
what's wrong, can someone give some help! thanks.
this is my nginx conf
location ~ url=(.*)$ {
return 301 $1;
}
In addition to the suggestion of Alexey Ten to use http://nginx.org/r/merge_slashes, which indeed may cause security issues, you can also use the following, which is probably a better approach anyways (if you are aleady set at the URL structure, that is):
location /url= {
if ($request_uri ~ ^/url=(.*)$) {
return 301 $1;
}
return 403;
}
Another option would be:
location /url=http:/ {
rewrite ^/url=http:/(.*)$ http://$1;
}
BTW, I would avoid using regular expressions in top-level locations, as it's generally less efficient than using the approaches above, but you can basically do the same thing with your approach as well.
Note, however, that in any case, unconditionally redirecting users to a user-supplied string may itself make your site vulnerable to certain attacks.

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.