How to redirect static files requests to https in Nginx? - regex

I have two versions of site with urls: http://example.com and https://example.com.
I want to redirect all requests to static content (files that is ended with .html, .htm, .js) to https version of my site.
So, I created the rule:
location ~ "\.(htm|html|js|css|svg|png)$" {
return 307 https://example.com$request_uri;
}
With this rule browser changes address of my site to https://example.com.
But I don't want to change address, I want that all requests to static files but not to index.html (main html of my site) will be redirected to https version.
How can I add something like AND NOT index.html to regex ~ "\.(htm|html|js|css|svg|png)$"?

Try:
root /path/to/root;
location = /index.html {
}
location ~ "\.(htm|html|js|css|svg|png)$" {
return 307 https://example.com$request_uri;
}
The location = block has highest precedence (the order is not important).
Because of an explicit or implicit index index.html statement, the URI / causes nginx to look for /index.html. The empty location block will cause the static file to be served, and the return 307 avoided.
See this document for more.

Related

NGINX 301 remove .html from url, but not for files from a specific path (folder)

In my location / directive I have added the following if statement to redirect all requests with the .html extension to the non-extension url:
if ($request_uri ~ ^/(.*)\.html) {
return 301 /$1$is_args$args;
}
This works fine, but actual .html files are also being redirected which results in a 404. I want to avoid this by adding an exception for all requests if the the url contains the directory "/static/", but I am not sure how to do that. I tried to add the following if statement before the if statement above:
if ($request_uri ~ /static/) {
}
But I'm not sure what to put in it to stop it from executing the .html if statement. Return $host$request_uri doesn't work, unfortunately.
How would I be able to do this? I cannot use location directives due to limitations of my host. Everything is being done in in the location / directive.

Nginx Redirect based on what is contained in the url

I am a noob when it comes to redirect and rewrites and such... My goal is to do a redirect based on what is sent to the server.
Example of the urls that will be sent:
https://example.org/git/#123
https://example.org/git/!123
and redirect to url based if ! or # is part of it
if ! then it would go to
https://git.example2.com/userhere/repohere/merge_requests/123
if # then it would go to
https://git.example2.com/userhere/repohere/issues/123
Some help with a nginx location block would be nice.
You can’t match #123. So you need to use different character i.e &
Use below sample rule.
if ($request_uri ~ "^(.*)/!123)"{
return 301 https://git.example2.com/userhere/repohere/merge_requests/123;
}
if ($request_uri ~ "^(.*)/!456)"{
return 301 https://git.example2.com/userhere/repohere/merge_requests/456;
}

Redirect old domain to new domain, including /en/

Little stuck but I'm trying to redirect an old domain name to a new domain, which is working to a point. However, we have a long list of URLs from our old website (using the old domain). Which have /en/ appended at the end.
So the issue is when I link olddomain.com/en/old-url to newdomain.com/new-url it throws a 404 as it's not picking up the '/en/'. I've compiled a long list of 301 redirects inside the Django admin, but they don't include the '/en/'. Which is where the issue is. Ideally, I want to add something to my nginx config that tells the domain to redirect even if the /en/ is included.
So Far I have something like this:
server {
listen 80;
server_name olddomain.co.uk www.olddomain.co.uk olddomain.co.uk/en/
return 301 https://www.newdomain.co.uk$request_uri;
}
server {
HTTPS
server_name olddomain.co.uk www.olddomain.co.uk olddomain.co.uk/en/;
#return 301 https://www.newdomain.co.uk$request_uri;
listen 443;
}
Thanks in advance.

Can NGINX change the response code after a proxy_pass?

So I have an internal API server namespaced under /api/, and I want to pass all other requests to an Amazon S3 static site using proxy_pass. This all works fine, it's just since Amazon is serving a single page app, I want to always return the same HTML file. They way I did this with the S3 server, was to set the index and error page as the same file. It all looks fine on the surface, but for all other requests besides /, the S3 instance returns a 404. Can I use NGINX to change this to a 200 before returning it to the client?
server {
listen 80;
server_name example.com;
location /api/ {
# serve internal app
}
location / {
proxy_pass http://example.amazonaws.com/;
# ALWAYS RETURN A 200
}
}
You should be able to use the error_page and proxy_intercept_errors directives to achieve this. Something like this should do the trick.
location / {
proxy_pass http://example.amazonaws.com/;
proxy_intercept_errors on;
error_page 404 =302 /your_html_file
}
error_page
proxy_intercept_errors
You can internally rewrite all URLs to the document you want served. This avoids the error handling cycle and problematic redirects.
It would be something like (untested):
location / {
proxy_pass http://example.amazonaws.com/;
rewrite ^.* /index.html
}
Note that you will want to only use full or root-relative URLs in your doc, because you don't know if the docs is served from a subdirectory.
You'd also be wise to have JS code validate the URL and optionally redirect to one you consider valid. Otherwise 3rd party sites could link to offensive URLs and get them in search indexes!

Django Nginx X-Accel-Redirect for protected files on Webfaction

If you want to torment someone until the end of time, just get them to configure Django and Nginx X-Accel-Redirect. This is literally impossible, I have been trying for days.
I am trying to only allow certain files to be downloaded from logged in views in django using Nginx on webfaction. Here is what I have:
Custom Nginx app listening on port 27796 under /static. Here is the conf.
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 27796;
server_name myurl.com;
root /home/ucwsri/webapps/static_media_ucwsri_nginx;
location / {
autoindex on;
}
location ^.*/protected-files {
internal;
alias /home/ucwsri/webapps/static_media_ucwsri_nginx/protected;
}
All static content is in /home/ucwsri/webapps/static_media_ucwsri_nginx, and is being correctly served by this Nginx app.
The files I want protected are here:
/home/ucwsri/webapps/static_media_ucwsri_nginx/protected
Which is the alias listed under the location ^.*/protected-files block in Nginx.
The view simply makes an Http Response thus:
response = HttpResponse()
url = "/static/protected-files/some-file.pdf"
response['X-Accel-Redirect'] = url
return response
Where the 'some-file.pdf' file exists in
/home/ucwsri/webapps/static_media_ucwsri_nginx/protected
Whatever I try I get a 404 from Nginx when trying to get that file as a POST request that goes to that view. I have tried everything I can think of, every location combination block, nothing works. Always a 404.
Someone please put me out of my misery and tell me what I have done wrong. This is truly brutal for something seemingly so simple.
First, your location ^.*/protected-files is nonsense. I guess, you've missed ~ modifier, but even in that case it would be useless.
Second, you have not protected /protected/ folder. Direct request to /protected/some-file.pdf will download that file without any protection.
Third, you have /static/protected-files/some-file.pdf in X-Accel-Redirect, but you didn't mention any static folder before.
So, I would suggest following config:
server {
listen 27796;
server_name myurl.com;
root /home/ucwsri/webapps/static_media_ucwsri_nginx;
location / {
autoindex on;
}
location ^~ /protected/ {
internal;
}
And django should be:
response = HttpResponse()
url = "/protected/some-file.pdf"
response['X-Accel-Redirect'] = url
return response
Summary:
Protect real folder.
X-Accel-Redirect is URI, just think about it as if user put that URI in browser address bar. The only difference is that internal will allow access with X-Accel-Redirect while forbid direct user access from browser.