I have a page on my site (only accessible to logged in users), that looks like the following:
https://www.example.com/forum/new
However, sometimes when users click or refresh they get the page as follows:
https://www.example.com/forum%252fnew
Now %25 decodes to the % symbol, and %2f decodes to the "/", so it seems the URI is getting double-encoded.
I'm not sure how this encoding is happening, but I thought a workaround would be to have Nginx redirect back to the correct URL, with something like the following:
location ~ /forum%252Fnew {
return 301 https://www.example.com/forum/new;
}
I have tried escaping the % in the location with \, but neither seem to be working.
What am I missing?
The URI has been decoded and normalized before being processed by the location and rewrite directives, so the %25 looks like a single %.
The example in your question shows a regular expression location statement. The ~ operator is for case-dependent matching, whereas the ~* operator is for case-independent matching.
To make the example in your question work, you will need to change it to:
location ~* /forum%2Fnew
Or:
location ~ /forum%2fnew
See this document for details.
Related
I'm trying to return 400 status if someone includes this character '<' anywhere in the url request, for example the request might look like
https://example.com/adfg<script
I tried the following in Nginx location block, but obviously this is not how it works,
location /*<* {
return 400;
}
What's the right syntax that i need to write please.
"<" characters is not allowed in a url. Therefore you can't use it, maybe you want to use the url encoded version: "%3C".
Check: Characters allowed in a URL
I'm trying to manually redirect a couple of links from my old blog to my new blog like this:
location = /blog-article-url {
return 301 https://blog.example.com/blog-article-url
}
And this works when i visit https://www.example.com/blog-article-url, i get properly redirected. However it IS case sensitive, if i visit https://www.example.com/BLOG-ARTICLE-URL it will NOT work.
What should i replace the = sign in the nginx config block to make it case insensitive?
You can do a case insensitive location block with regular expressions.
For example:
location ~* ^/blog-article-url$ { ... }
Note that the evaluation order of regular expression locations is significant - so you may need to move this location block towards the top of your server block. See this document for more.
I have a rule which is not working correctly.
I need it so that whenever URL xxx.com/forum/css.php is hit, it is re-written to xxx.com/forum/core/css.php.
I have written the following location block for it:
location ~^ /forum/css.php {
rewrite ^ /forum/core/css.php permanent;
}
Also needing to be taken into account is that the file is a factory so it accepts parameters, the url being hit actually looks like xxx.com/forum/css.php?x=123&y=string. Will this also be taken into account in the re-writes or does it need to be specified? Sorry if the question seems silly I am just beginning to work with servers! Thanks fellow coders!
To rewrite a single URI (with or without query string) you could use a location =:
location = /forum/css.php {
rewrite ^ /forum/core/css.php permanent;
}
The rewrite directive appends the query string (unless terminated with ?). See this and this for more.
Hi I have urls that look like this
http://dansawesomesite.com/123/articlename
I have the following rewrite rule in nginx
location ~* /(\d+)/([\+\w-\ ]+)/?$ {
try_files $uri /wpcontentredir.php?slug=$1;
}
This matches the above URL however the issue comes about when I have the following URL's
http://dansawesomesite.com/posts/630325/like
(as well as a number of similar)
These also end up getting matched which is correct based on my regex, but will mess things up as I dont want these urls parsed through that try_files, I just want them to pass as is.
Just wondering if anyone can help me with only matching the top first URL?
CHeers
Dan
Try to add "^" to the beginning of regexp
location ~* ^/(\d+)/([+\w-\ ]+)/?$
So it will match only if first part of URI contains digits and not "posts" or something
I have a site with two RESTful URL schemes:
foo.com/model/id and
foo.com/model/id/action
The actual pages served by these URLs are in the form of
$model.php?id=$id and
$model_$action.php?id=$id respectively.
I have a single regular expression that will match both cases ^(\w+)s/([A-z0-9]+)(?:/(\w+))?/?$ and I'd like to use a single Nginx rule to rewrite for both types of URLs, but I'm not sure how to do this. In pseudocode I imagine the rule would look something like this
rewrite ^(\w+)s/([A-z0-9]+)(?:/(\w+))?/?$ /(($3) ? $1_$3.php?$id=$2 : $1.php?$id=2)
This isn't valid syntax (so far as I know), but can something like this be done in Nginx?
Rewrite the possible urls in turn starting with the longest to the shortest to that overlapping matching strings, "/model/id" in this case, would be matched in the longer url string first.
location / {
# For "/model/id/action" to "$model_$action.php?id=$id"
rewrite ^/(.+)/(.+)/(.+)(/?)$ $1_$3.php?id=$2 last;
# For "/model/id" to "$model.php?id=$id"
rewrite ^/(.+)/(.+)(/?)$ $1.php?id=$2 last;
}
location ~ .+\.php$ {
# Handle PHP
}
The "(/?)" is just in case the urls sometimes come with an ending slash. If they never do, it can be removed. In this case, it will probably be best to specifically always add a closing slash and have "(/?)" as "/".