Custom RedirectHandler and .history support.
authorKenneth Reitz <me@kennethreitz.com>
Sun, 15 May 2011 03:00:40 +0000 (23:00 -0400)
committerKenneth Reitz <me@kennethreitz.com>
Sun, 15 May 2011 03:01:13 +0000 (23:01 -0400)
Closes #23

requests/models.py
requests/monkeys.py

index 9707fc4764ddf66496a6e6cae0a7b7c875667f0b..e236f40e2c40149230be2e6d4a98bdf5b0d40ea8 100644 (file)
@@ -15,7 +15,7 @@ import zlib
 from urllib2 import HTTPError
 from urlparse import urlparse
 
-from .monkeys import Request as _Request, HTTPBasicAuthHandler, HTTPDigestAuthHandler
+from .monkeys import Request as _Request, HTTPBasicAuthHandler, HTTPDigestAuthHandler, HTTPRedirectHandler
 from .structures import CaseInsensitiveDict
 from .packages.poster.encode import multipart_encode
 from .packages.poster.streaminghttp import register_openers, get_handlers
@@ -30,7 +30,7 @@ class Request(object):
     _METHODS = ('GET', 'HEAD', 'PUT', 'POST', 'DELETE')
 
     def __init__(self, url=None, headers=dict(), files=None, method=None,
-                 data=dict(), auth=None, cookiejar=None, timeout=None):
+                 data=dict(), auth=None, cookiejar=None, timeout=None, redirect=True):
 
         socket.setdefaulttimeout(timeout)
 
@@ -38,7 +38,8 @@ class Request(object):
         self.headers = headers
         self.files = files
         self.method = method
-        self.data = {}
+        self.data = dict()
+        self.redirect = redirect
 
         # self.data = {}
         if hasattr(data, 'items'):
@@ -101,10 +102,18 @@ class Request(object):
 
             _handlers.append(self.auth.handler)
 
+
+        _handlers.append(HTTPRedirectHandler)
+        # print _handlers
+        # print '^^'
+        # print '!'
+
         if not _handlers:
             return urllib2.urlopen
 
-        _handlers.extend(get_handlers())
+        if self.data or self.files:
+            _handlers.extend(get_handlers())
+
         opener = urllib2.build_opener(*_handlers)
 
         if self.headers:
@@ -121,21 +130,50 @@ class Request(object):
     def _build_response(self, resp):
         """Build internal Response object from given response."""
 
-        self.response.status_code = getattr(resp, 'code', None)
+        def build(resp):
 
-        try:
-            self.response.headers = CaseInsensitiveDict(getattr(resp.info(), 'dict', None))
-            self.response.content = resp.read()
-        except AttributeError:
-            pass
+            response = Response()
+            response.status_code = getattr(resp, 'code', None)
 
-        if self.response.headers['content-encoding'] == 'gzip':
             try:
-                self.response.content = zlib.decompress(self.response.content, 16+zlib.MAX_WBITS)
-            except zlib.error:
+                response.headers = CaseInsensitiveDict(getattr(resp.info(), 'dict', None))
+                response.content = resp.read()
+            except AttributeError:
                 pass
 
-        self.response.url = getattr(resp, 'url', None)
+            if response.headers['content-encoding'] == 'gzip':
+                try:
+                    response.content = zlib.decompress(response.content, 16+zlib.MAX_WBITS)
+                except zlib.error:
+                    pass
+
+            response.url = getattr(resp, 'url', None)
+
+            return response
+
+
+        history = []
+
+        r = build(resp)
+
+        if self.redirect:
+
+            while 'location' in r.headers:
+
+                history.append(r)
+
+                url = r.headers['location']
+
+                request = Request(
+                    url, self.headers, self.files, self.method,
+                    self.data, self.auth, self.cookiejar, redirect=False
+                )
+                request.send()
+                r = request.response
+
+            r.history = history
+
+        self.response = r
 
 
     @staticmethod
@@ -227,6 +265,7 @@ class Response(object):
         self.ok = False
         self.error = None
         self.cached = False
+        self.history = []
 
 
     def __repr__(self):
index 145838f2009ea1228c8d71dcac37636fbd173cb1..83353c18320cc744ad91002ba4f86119e3b4702d 100644 (file)
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+#-*- coding: utf-8 -*-
 
 """
 requests.monkeys
@@ -27,8 +27,19 @@ class Request(urllib2.Request):
         return urllib2.Request.get_method(self)
 
 
+class HTTPRedirectHandler(urllib2.HTTPRedirectHandler):
+
+    def http_error_301(self, req, fp, code, msg, headers):
+        # print "Cookie Manip Right Here"
+        # print 'HEY'
+        pass
+        # return urllib2.HTTPRedirectHandler.http_error_302(self, req, fp, code, msg, headers)
+
+    http_error_302 = http_error_303 = http_error_307 = http_error_301
+
+
+
 class HTTPBasicAuthHandler(urllib2.HTTPBasicAuthHandler):
-    # from mercurial
 
     def __init__(self, *args, **kwargs):
         urllib2.HTTPBasicAuthHandler.__init__(self, *args, **kwargs)
@@ -45,8 +56,10 @@ class HTTPBasicAuthHandler(urllib2.HTTPBasicAuthHandler):
         if req is not self.retried_req:
             self.retried_req = req
             self.retried = 0
+
         return urllib2.HTTPBasicAuthHandler.http_error_auth_reqed(
-                        self, auth_header, host, req, headers)
+            self, auth_header, host, req, headers
+        )