Skip to content

Commit

Permalink
Merge pull request #1963 from sigmavirus24/fix-redirect-methods
Browse files Browse the repository at this point in the history
Fix #1955: Do not use original request in redirect
  • Loading branch information
kennethreitz committed Mar 24, 2014
2 parents a3cd2f3 + 8d693a2 commit 5f48e4a
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 1 deletion.
5 changes: 4 additions & 1 deletion requests/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,11 @@ def resolve_redirects(self, resp, req, stream=False, timeout=None,
proxies = self.rebuild_proxies(prepared_request, proxies)
self.rebuild_auth(prepared_request, resp)

# Override the original request.
req = prepared_request

resp = self.send(
prepared_request,
req,
stream=stream,
timeout=timeout,
verify=verify,
Expand Down
61 changes: 61 additions & 0 deletions test_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import os
import pickle
import unittest
import collections

import requests
import pytest
Expand All @@ -19,6 +20,7 @@
from requests.exceptions import InvalidURL, MissingSchema
from requests.models import PreparedRequest, Response
from requests.structures import CaseInsensitiveDict
from requests.sessions import SessionRedirectMixin

try:
import StringIO
Expand Down Expand Up @@ -1204,5 +1206,64 @@ def test_stream_timeout(self):
assert 'Read timed out' in e.args[0].args[0]


SendCall = collections.namedtuple('SendCall', ('args', 'kwargs'))


class RedirectSession(SessionRedirectMixin):
def __init__(self, order_of_redirects):
self.redirects = order_of_redirects
self.calls = []
self.max_redirects = 30
self.cookies = {}
self.trust_env = False

def send(self, *args, **kwargs):
self.calls.append(SendCall(args, kwargs))
return self.build_response()

def build_response(self):
request = self.calls[-1].args[0]
r = requests.Response()

try:
r.status_code = int(self.redirects.pop(0))
except IndexError:
r.status_code = 200

r.headers = CaseInsensitiveDict({'Location': '/'})
r.raw = self._build_raw()
r.request = request
return r

def _build_raw(self):
string = StringIO.StringIO('')
setattr(string, 'release_conn', lambda *args: args)
return string


class TestRedirects:
default_keyword_args = {
'stream': False,
'verify': True,
'cert': None,
'timeout': None,
'allow_redirects': False,
'proxies': None,
}

def test_requests_are_updated_each_time(self):
session = RedirectSession([303, 307])
prep = requests.Request('POST', 'http://httpbin.org/post').prepare()
r0 = session.send(prep)
assert r0.request.method == 'POST'
assert session.calls[-1] == SendCall((r0.request,), {})
redirect_generator = session.resolve_redirects(r0, prep)
for response in redirect_generator:
assert response.request.method == 'GET'
send_call = SendCall((response.request,),
TestRedirects.default_keyword_args)
assert session.calls[-1] == send_call


if __name__ == '__main__':
unittest.main()

0 comments on commit 5f48e4a

Please sign in to comment.