Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Missing custom header with django, nginx and gunicorn

Disclaimer:

I'm working in a project where exist an "huge" webapp that have an api for mobiles, so change the api is not an option.

This application was developed time ago and several developers have worked on it,

Having said that, the problem is this;

In the api for mobile of this site (just views than returns json data), the code is looking for a token but does in the headers of request:

token = request.META.get('HTTP_TOKEN')

When I test this api locally, works fine, but in production doesn't, so, I try to figure out whats going on and found this:

django converts headers, even custom headers to keys in request.META, I use urllib2 and requests for test the api and the problem in production is that in production server the request.META never has a key called HTTP_TOKEN, so, doing a little of debug I seriously think the problem is the way we serve the django application.

We are using django1.3, nginx, gunicorn, virtualenvwrapper, python2.7.

My prime suspect is nginx, I think, in someway nginx receive the header but don' forward it to django, I try to do some research about this, but I only found infor about security headers and custom headers from nginx, but I dont find doc or something about how to tell nginx that allows that header and don't remove it.

I need help here, the first thing is test if nginx receives the header, but I just know a little about nginx and I don't know how to tell it to log the headers of requests.

Thanks

Update

nginx conf file

like image 373
diegueus9 Avatar asked Nov 04 '11 14:11

diegueus9


People also ask

What is the difference between Gunicorn and nginx?

Gunicorn implements the Web Server Gateway Interface (WSGI), which is a standard interface between web server software and web applications. Nginx is a web server. It's the public handler, more formally called the reverse proxy, for incoming requests and scales to thousands of simultaneous connections.

How do you run Gunicorn in Django?

Running Django in Gunicorn as a generic WSGI application This will start one process running one thread listening on 127.0. 0.1:8000 . It requires that your project be on the Python path; the simplest way to ensure that is to run this command from the same directory as your manage.py file.

What is header in nginx?

The HTTP headers in NGINX are split in two parts: the input request headers (headers_in structure) and the output request headers (headers_out structure). There is no such an entity as a response, all the data is stored in the same single request structure.


2 Answers

If Django is accessed using uwsgi_pass, then in the appropriate location(s) ...

# All request headers should be passed on by default     
# Make sure "Token" response header is passed to user 
uwsgi_pass_header  Token;

If Django is accessed using fastcgi_pass, then in the appropriate location(s) ...

# All request headers should be passed on by default     
# Make sure "Token" response header is passed to user 
fastcgi_pass_header  Token;

If Django is accessed using proxy_pass, then in the appropriate location(s) ...

# All request headers should be passed on by default
# but we can make sure "Token" request header is passed to Django 
proxy_set_header Token $http_token;

# Make sure "Token" response header is passed to user 
proxy_pass_header  Token;

These should help eliminate the possibility that Nginx is not passing things along from your issue.

like image 83
Dayo Avatar answered Nov 03 '22 17:11

Dayo


In your nginx configuration file (f.e. mysite_nginx.conf) in the server section add this parameter: uwsgi_pass_request_headers on;.

For example:

server {
    # the port your site will be served on
    listen      8000;

    ...

    underscores_in_headers on;
}

And if access to Django goes through uwsgi_pass, you need to add this one parameter uwsgi_pass_request_headers on; in location section.

For example:

location / {
    include     /etc/nginx/uwsgi_params; # the uwsgi_params file you installed
    uwsgi_pass_request_headers on;
    uwsgi_pass  django;
}
like image 24
M.Void Avatar answered Nov 03 '22 16:11

M.Void