18

After I deployed my Django App last night I got tons of strange Emails saying:

ERROR: Invalid HTTP_HOST header: '/webapps/example_com/run/gunicorn.sock

I'm sure this is somehow related to the following nginx config:

upstream example_app_server {
  server unix:/webapps/example_com/run/gunicorn.sock fail_timeout=0;
}

server {

    listen   80;
    server_name example.com;

    client_max_body_size 4G;

    access_log /webapps/example_com/logs/nginx-access.log;
    error_log /webapps/example_com/logs/nginx-error.log;


    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_set_header Host $http_host;

        proxy_redirect off;

        if (!-f $request_filename) {
            proxy_pass http://example_app_server;
            break;
        }
    }
}
WhatIsName
  • 2,294
  • 4
  • 24
  • 36

3 Answers3

33

I found the answer to my my question in a django bug report.

    proxy_set_header Host $http_host;

has to be replaced with:

    proxy_set_header Host $host;

to make nginx pass the correct headers from that on instead of the gunicorn socket the requested page was in the django alerts.

WhatIsName
  • 2,294
  • 4
  • 24
  • 36
  • 1
    Could you please link a reference to the bug report and any possible extra information as to _why_ the first causes the issue? I have been using the first approach on multiple websites, and never had an issue. One of my most recent websites however is affected. – Andre Jun 11 '14 at 09:16
  • 3
    @Andre, I searched it via http://search.aol.com/aol/search?q=proxy_set_header+site%3Acode.djangoproject.com&s_it=opensearch. and https://code.djangoproject.com/ticket/19867 seems to be the one, pay attention to the last comment. – flyingfoxlee Nov 24 '14 at 07:05
  • Thank you @flyingfoxlee I'll test this on our next iteration. :) – Andre Nov 25 '14 at 07:38
5

This person explains a bit more what is going on based on this very same post. Here's his/her explanation:

...when a request is made to the server and the HTTP Host is empty, nginx sets the HTTP host to the gunicorn sock.

I can generate this error using curl:

curl -H "HOST:" MY_DOMAIN_NAME -0 -v

This sends a request without a HTTP Host. The -0 causes curl to use HTTP version 1.0. If you do not set this, the request will use HTTP version 1.1, which will cause the request to be rejected immediately and not generate the error.

The solution is to replace $http_host with $host (as pointed out on Stackoverflow). When HTTP Host is missing, $host will take on the value of the “server_name” directive. This is a valid domain name and is the one that should be used.

BringBackCommodore64
  • 4,910
  • 3
  • 27
  • 30
0

Add this in your settings.py file:

from django.http.request import HttpRequest
HttpRequest.get_host = HttpRequest._get_raw_host