0

I have a Web Application that uses Django as backend and Nginx along with Gunicorn for the reverse proxy. I have already set up the Nginx configuration and it works perfectly when requests are sent over HTTPS. But it fails when HTTP requests are made.

I want the application to work for both HTTP and HTTPS requests.

Some of my Django Views contain internal requests that are made over HTTP as they have to be compatible with the Development as well as Production Server

class LoginView(APIView):
   ...
        http_host = request.META["HTTP_HOST"]
        url = f"http://{http_host}/o/token/"
        headers = {'Content-Type': 'application/x-www-form-urlencoded'}
        data = {
            'username': req_data['username'],
            'password': req_data['password'],
        }

        response = requests.post(url, headers=headers, data=data)
   ...

My nginx configuration is as follows

server {
    listen 8000 ssl;

    server_name backend.test.com www.backend.test.com;

    access_log /var/log/nginx/app_backend.access.log;
    error_log /var/log/nginx/app_backend.error.log;

    location = /favicon.ico { access_log off; log_not_found off; }
    
    location /static/ {
        root /home/testuser/app_backend/app_backend;
    }
    
    location /media/ {
        root /home/testuser/app_backend/app_backend;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/home/testuser/app_backend/app_backend/app_backend.sock;
    }


    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/backend.test.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/backend.test.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

I have hosted the VPS on digital ocean.

How do I make the server work for http requests also that are made internally by the backend views

Note: I tried to redirect all HTTP request to HTTPS only in production in Nginx by doing this return 301 https://$host$request_uri;, but that did not work

7
  • browsers will block http requests from https pages .... you should use the "url for" helper or whatever its called ... or just change it to url='/o/token/' ... but look up http redirect nginx to see how to have http requests rewritten as https ... Commented Jan 14, 2022 at 7:04
  • When I try that I get the error Invalid URL '/o/token/': No schema supplied. Perhaps you meant http:///o/token/. So it is not automatically adding the host and schema Commented Jan 14, 2022 at 7:09
  • I tried to convert any http request to https in Nginx by using return 301 https://$host$request_uri; also but that did not work Commented Jan 14, 2022 at 7:11
  • ahh your right with the o/token thing... sorry I want paying close enough attention ... and the redirect probably breaks with post data .... why are you posting it to http? Commented Jan 14, 2022 at 7:14
  • @JoranBeasley I could POST to HTTPS directly, but that would only work in production. When I am running the app in Development on localhost, then POST to HTTPS would not work Commented Jan 14, 2022 at 7:16

1 Answer 1

2

Im going to go out on a limb here and assume you dont actually want what you asked for... instead you just need to use the same schema, which should be available in the request as well

url = f"{request.scheme}://{request.META['HTTP_HOST']}/o/token"

note... that Im not 100% sure this would not preserve the port (if needed it should be in META['SERVER_PORT'])

alternatively define a second HTTP server (make sure you remove the :8000 from the first server)

server {
    listen 8000 80; 

    server_name backend.test.com www.backend.test.com;

    access_log /var/log/nginx/app_backend.access.log;
    error_log /var/log/nginx/app_backend.error.log;

    location = /favicon.ico { access_log off; log_not_found off; }
    
    location /static/ {
        root /home/testuser/app_backend/app_backend;
    }
    
    location /media/ {
        root /home/testuser/app_backend/app_backend;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/home/testuser/app_backend/app_backend/app_backend.sock;
    }
}

but i think this is generally deemed bad practice

Sign up to request clarification or add additional context in comments.

4 Comments

Yes I could do that and it works, but I have several such views in the backend, where this would have to be done. I was just wondering if it was possible to make any change to the Nginx Configuration which could solve my problem?
@dracarys see edit ... if you really want to do that i think you can just do this ....
Thanks for the help. I just think request.META['HTTP_HOST'] does preserve the port. request.META['SERVER_NAME'] does not preserve the port. Kindly confirm?
lol i believe you ... :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.