request.post() does not work properly generating a 301 redirect on Nginx

Asked

Viewed 281 times

0

I have a problem when I use request.post('url', data), for some reason when the server receives this request, it redirects (301) the request to the same url losing the POST data, ending as a GET method.

Python:

>>> r = requests.post('http://meusite.com/teste', data={'a': 'teste'})
>>> r.request.method
'GET'
>>> r.request.headers
{'Accept': '*/*', 'Content-Type': 'application/x-www-form-urlencoded', 'Connection': 'keep-alive', 'Accept-Encoding': 'gzip, deflate', 'User-Agent': 'python-requests/2.9.1'}
>>> r.request.body  # nao tem nada no body

>>> r.history  # analisando a historia do request é encontrado um redirecionamento 301
[<Response [301]>]
>>> history = r.history[0]
>>> history.request.method
'POST'
>>> history.request.headers
{'Accept': '*/*', 'Content-Type': 'application/x-www-form-urlencoded', 'Connection': 'keep-alive', 'Accept-Encoding': 'gzip, deflate', 'User-Agent': 'python-requests/2.9.1', 'Content-Length': '7'}
>>> history.request.body
'a=teste'

As you can see, when sending a POST, there is a 301 (as in r.history) redirecting with a GET (losing the data that had been passed by POST).

Log of the Nginx:

[01/Apr/2016:19:48:46 +0000] "POST /teste HTTP/1.1" 301 5 "-" "python-requests/2.9.1"
[01/Apr/2016:19:48:46 +0000] "GET /teste/ HTTP/1.1" 200 66 "-" "python-requests/2.9.1"

I tried to send this data via request.post() both from localhost to the target server, and through the target server itself and continues to present the same problem.

My Nginx is configured as follows:

Nginx:

upstream hello_django_app_server {
    server unix:/home/ubuntu/virtualenvs/hello_django/sockfile/gunicorn.sock fail_timeout=0;
}

server {
   listen 80;
   server_name hello_django.com;
   client_max_body_size 4G;
   keepalive_timeout 5;

   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://hello_django_app_server;
           break;
       }
   }
}

He’s using Gunicorn to serve Django.

Gunicorn:

#!/bin/bash

NAME="hello_app"                                  # Name of the application
DJANGODIR=/webapps/hello_django/hello             # Django project directory
SOCKFILE=/webapps/hello_django/run/gunicorn.sock  # we will communicte using this unix socket
USER=hello                                        # the user to run as
GROUP=webapps                                     # the group to run as
NUM_WORKERS=3                                     # how many worker processes should Gunicorn spawn
DJANGO_SETTINGS_MODULE=hello.settings             # which settings file should Django use
DJANGO_WSGI_MODULE=hello.wsgi                     # WSGI module name

echo "Starting $NAME as `whoami`"

# Activate the virtual environment
cd $DJANGODIR
source ../bin/activate
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
export PYTHONPATH=$DJANGODIR:$PYTHONPATH

# Create the run directory if it doesn't exist
RUNDIR=$(dirname $SOCKFILE)
test -d $RUNDIR || mkdir -p $RUNDIR

# Start your Django Unicorn
# Programs meant to be run under supervisor should not daemonize themselves (do not use --daemon)
exec ../bin/gunicorn ${DJANGO_WSGI_MODULE}:application \
  --name $NAME \
  --workers $NUM_WORKERS \
  --user=$USER --group=$GROUP \
  --bind=unix:$SOCKFILE \
  --log-level=debug \
  --log-file=-
view rawgunicorn_start.bash

My project is working normally (including following this site as reference: http://michal.karzynski.pl/blog/2013/06/09/django-nginx-gunicorn-virtualenv-supervisor/). I can send forms internally via POST without problems. But when I use requests.post() does not work, seems a problem of Nginx.

I need to receive notifications from Amazon SNS, through HTTP it sends data via POST and I treat this data on my server.

My EC2 instance is configured both inbound and outbound to receive access of any type (alltrafic), so there are no instance access problems.

Everything indicates that the problem is in Nginx or Gunicorn, I do not know. How to solve this problem?

1 answer

1


After writing the question in detail, I was able to find the problem. URL requests.post() has to end with \, the fact that it is not finishing, there is a redirection to the same URL with bars at the end, which ends up losing the data sent via POST.

After running the code generated a 403 permission-related error, which is nothing more than the lack of the csrf for sending the POST, placing the Developer @csrf_exempt (from django.views.decorators.csrf import csrf_exempt) in view solved the problem.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.