django url pattern strips forward slash when running in nginx+uwsgi - django

For the following url pattern:
re_path(r'proxy/(?P<url>.*)', myview)
When I send proxy/http://www.google.com
myview function receives url as http:/www.google.com (with single /)
It happens with uwsgi+nginx setup , when running with runserver url is http://www.google.com .

This is because nginx will automatically merge double slashes in URLs into a single one:
http://nginx.org/en/docs/http/ngx_http_core_module.html#merge_slashes
Enables or disables compression of two or more adjacent slashes in a URI into a single slash.
Note that compression is essential for the correct matching of prefix string and regular expression locations. Without it, the “//scripts/one.php” request would not match
You should disable it in your nginx.conf:
merge_slashes off;

Related

Nginx redirect dynamic URLs one path to another

I want to check if a parameter is present in a url in nginx and then rewrite. How can i do that?
The color is dynamic in the URLs
For e.g
If url is http://website.com/lunch-box/xxxxxabc then redirect user to http://website.com/lunch-box/.
If URL is http://website.com/lunch-box/xxxxxabc/ABCD123 no need to redirect. Need to load as it is.
I want to redirect if URL is matched. and xxxxxabc is dynamic text.
nginx version: nginx/1.16.1
# rewrite direct children of /lunch-box but not grandchildren+
rewrite ^(/lunch-box/)[^/]+/?$ $1 last;
Walking through the regex ^(/lunch-box/)[^/]+/?$
^ matches the start of a string (rewrite rules match against the path, not the full URI)
(/lunch-box/) matches the literal text /lunch-box/ and saves it for $1
[^/]+ matches one or more characters that are not a forward slash
/? matches zero or one forward slash
$ matches the end of the string
This strips off the path past what we've saved as $1, but only when that path is a direct child.

Nginx, redirection's regular expression not working properly

I've a wordpress page on a VPS with nginx and plesk. I was using this directive to remove trailing slashes from the url so everything works properly:
rewrite ^(.+)/+$ $1;
It removes trailing slashes, and I wanted, but then I couldn't access the "wp-admin" url due to too many redirects.
So I changed it to this:
rewrite ^(?!wp-admin)(.+)/+$ $1;
But it keeps removing trailing slashes from the "wp-admin" url.
Thank you all so much for your time and help.

Nginx rewrite: add trailing slash, preserve anchors and query strings

I need to ensure that all permalinks on a given site end with a trailing slash. That is, any URL that refers to a location that doesn't correspond to an actual, individual file. I also need to preserve any query strings and/or anchors that are passed with the URL.
Example
Say I have a page at the following location:
example.com/about/
If I get the following requests, I want them to rewrite as shown:
example.com/about > example.com/about/
example.com/about?src=fb > example.com/about/?src=fb
example.com/about#contact > example.com/about/#contact
example.com/about#contact?src=fb > example.com/about/#contact?src=fb
However, I want to make sure that I do not rewrite for any actual file paths - anything with a file extension.
What I have so far
This is the regex I have come up with thus far, which only addresses excluding real file paths, and adding a trailing slash when the end of the string doesn't have one:
^([^\.]*$(?<!\/))
I have not yet been able to figure how how to determine whether a trailing slash is present when there are anchors or query strings, and once that's established how to separately capture the parts that should be before the trailing slash and after it in order to assemble the final rewrite.
As it turns out, the regex I came up with does in fact address all of my rewrite needs. Here is the final result in my Nginx server configuration:
location / {
try_files $uri $uri/ #rewrites;
}
# Rewrite rules to sanitize and canonicalize URLs
location #rewrites {
rewrite ^([^\.]*$(?<!\/)) $1/ last;
}

Django greedy characters missing in reverse urls

I am trying to use the following rule to map urls in django
url(r'^(?P<permalink>[a-zA-Z0-9_-]*)/?$', views.page, name='page'),
This should match pages like
site.com
site.com/super-awesome-page/
This works however the reverse urls provided by the url template tag are missing the trailing / i.e. "site.com/page" these do get captured pattern but I want my links to show up in my page correctly how can I get this to work correctly.
I would have expected since the trailing slash is greedy it should be included in the reverse url.
The trailing slash is optional in your regex, so django doesn't generate it for you for the reverse URL.
The easiest solution is probably to make the trailing slash non-optional. With the default settings, django will redirect the non-slash version to the slash-version. Easiest to just standardize on that.

Nginx: Escaping # in url rewrite

I have a MVC JavaScript application that needs to support Facebook sharing, which means it needs to support unique OG meta HTML tags.
I'm doing an Nginx rewrite that will detect the Facebook crawler to server a custom version of the app with the proper OG tag for that section but Apache is ignore everything after the # sign (as server-side should do since that's a browser feature.) I would like to escape the "#" in my rewrite but am not sure how to do it in Nginx:
location / {
if ($http_user_agent ~* 'facebookexternalhit') {
rewrite ^(.*)$ /og.php?url=http://$host$uri;
proxy_pass http://127.0.0.1:8080;
break;
}
root /var/www/html/site.net;
}
Thanks for taking a look!
You cannot or don't have to. If you have an URL in your browser like http://www.example.tld/site.html#anchor then your browser's request will only consist of the non-anchor part: http://www.example.tld/site.html. After receiving the content the browser will look for a named anchor called anchor and scroll the page so that its content is visible.
Meaning nginx will never see the character #.
If, on the other hand, a website contains a link with # being part of the path part of the URL (and this is rather rare) then it has to be escaped with the usual URL escaping of %xx with xx being the hexadecimal number of that chacter -- %23 in the case of #.