From ce64cce14ef5914216fe52a40496f47b4631d13c Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Fri, 26 May 2017 21:07:37 -0400 Subject: [PATCH 1/5] API improvements --- requests/models.py | 8 ++++++++ requests/sessions.py | 40 ++++++++++++++++++++++++---------------- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/requests/models.py b/requests/models.py index 75f16e32..740143b8 100644 --- a/requests/models.py +++ b/requests/models.py @@ -577,6 +577,10 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): for event in hooks: self.register_hook(event, hooks[event]) + def send(self, session): + """Sends the given PreparedRequest to the given session.""" + return session.send(self) + class Response(object): """The :class:`Response ` object, which contains a @@ -593,6 +597,7 @@ class Response(object): self._content = False self._content_consumed = False + self._next = None #: Integer Code of responded HTTP Status, e.g. 404 or 200. self.status_code = None @@ -709,6 +714,9 @@ class Response(object): """True if this Response one of the permanent versions of redirect""" return ('location' in self.headers and self.status_code in (codes.moved_permanently, codes.permanent_redirect)) + def next(self): + if self.is_redirect: + return self._next @property def apparent_encoding(self): """The apparent encoding, provided by the chardet library""" diff --git a/requests/sessions.py b/requests/sessions.py index 3ae42f99..893ed039 100755 --- a/requests/sessions.py +++ b/requests/sessions.py @@ -114,8 +114,8 @@ class SessionRedirectMixin(object): return None def resolve_redirects(self, resp, req, stream=False, timeout=None, - verify=True, cert=None, proxies=None, **adapter_kwargs): - """Receives a Response. Returns a generator of Responses.""" + verify=True, cert=None, proxies=None, yield_responses=True, **adapter_kwargs): + """Receives a Response. Returns a generator of Responses or Requests.""" hist = [] # keep track of history @@ -203,22 +203,26 @@ class SessionRedirectMixin(object): # Override the original request. req = prepared_request - resp = self.send( - req, - stream=stream, - timeout=timeout, - verify=verify, - cert=cert, - proxies=proxies, - allow_redirects=False, - **adapter_kwargs - ) + if not yield_responses: + yield req + else: - extract_cookies_to_jar(self.cookies, prepared_request, resp.raw) + resp = self.send( + req, + stream=stream, + timeout=timeout, + verify=verify, + cert=cert, + proxies=proxies, + allow_redirects=False, + **adapter_kwargs + ) - # extract redirect url, if any, for the next loop - url = self.get_redirect_target(resp) - yield resp + extract_cookies_to_jar(self.cookies, prepared_request, resp.raw) + + # extract redirect url, if any, for the next loop + url = self.get_redirect_target(resp) + yield resp def rebuild_auth(self, prepared_request, response): """When being redirected we may want to strip authentication from the @@ -668,6 +672,10 @@ class Session(SessionRedirectMixin): r = history.pop() r.history = history + # If redirects aren't being followed, store the response on the Request for Response.next(). + if not allow_redirects: + r._next = self.resolve_redirects(r, request, yield_responses=False, **kwargs).next() + if not stream: r.content From f41560c5d46e8cbb8d8f741b2f7d2da29a9d6b94 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Fri, 26 May 2017 21:15:58 -0400 Subject: [PATCH 2/5] fix the tests --- requests/sessions.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/requests/sessions.py b/requests/sessions.py index 893ed039..2b0b7e1a 100755 --- a/requests/sessions.py +++ b/requests/sessions.py @@ -674,7 +674,10 @@ class Session(SessionRedirectMixin): # If redirects aren't being followed, store the response on the Request for Response.next(). if not allow_redirects: - r._next = self.resolve_redirects(r, request, yield_responses=False, **kwargs).next() + try: + r._next = self.resolve_redirects(r, request, yield_responses=False, **kwargs).next() + except StopIteration: + pass if not stream: r.content From dfd667df96f9d8102100fdf85292e6dbf4b4e22e Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Fri, 26 May 2017 21:17:13 -0400 Subject: [PATCH 3/5] who wrote this shit --- requests/models.py | 6 ++++-- requests/sessions.py | 3 +-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/requests/models.py b/requests/models.py index 740143b8..6018d27c 100644 --- a/requests/models.py +++ b/requests/models.py @@ -711,15 +711,17 @@ class Response(object): @property def is_permanent_redirect(self): - """True if this Response one of the permanent versions of redirect""" + """True if this Response one of the permanent versions of redirect.""" return ('location' in self.headers and self.status_code in (codes.moved_permanently, codes.permanent_redirect)) def next(self): + """Returns a PreparedRequest for the next request in a redirect chain, if there is one.""" if self.is_redirect: return self._next + @property def apparent_encoding(self): - """The apparent encoding, provided by the chardet library""" + """The apparent encoding, provided by the chardet library.""" return chardet.detect(self.content)['encoding'] def iter_content(self, chunk_size=1, decode_unicode=False): diff --git a/requests/sessions.py b/requests/sessions.py index 2b0b7e1a..0cde98ef 100755 --- a/requests/sessions.py +++ b/requests/sessions.py @@ -601,8 +601,7 @@ class Session(SessionRedirectMixin): return self.request('DELETE', url, **kwargs) def send(self, request, **kwargs): - """ - Send a given PreparedRequest. + """Send a given PreparedRequest. :rtype: requests.Response """ From a7239aab84b59534fb5e6eb7b83a97dcf913f8de Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Fri, 26 May 2017 21:23:55 -0400 Subject: [PATCH 4/5] feedback from @sigmavirus42 --- requests/sessions.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/requests/sessions.py b/requests/sessions.py index 0cde98ef..1028bb7f 100755 --- a/requests/sessions.py +++ b/requests/sessions.py @@ -114,7 +114,7 @@ class SessionRedirectMixin(object): return None def resolve_redirects(self, resp, req, stream=False, timeout=None, - verify=True, cert=None, proxies=None, yield_responses=True, **adapter_kwargs): + verify=True, cert=None, proxies=None, yield_requests=False, **adapter_kwargs): """Receives a Response. Returns a generator of Responses or Requests.""" hist = [] # keep track of history @@ -203,7 +203,7 @@ class SessionRedirectMixin(object): # Override the original request. req = prepared_request - if not yield_responses: + if yield_requests: yield req else: @@ -674,7 +674,7 @@ class Session(SessionRedirectMixin): # If redirects aren't being followed, store the response on the Request for Response.next(). if not allow_redirects: try: - r._next = self.resolve_redirects(r, request, yield_responses=False, **kwargs).next() + r._next = self.resolve_redirects(r, request, yield_requests=True, **kwargs).next() except StopIteration: pass From c3367d1854208c37855622659ae0a621d9352af2 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Fri, 26 May 2017 21:28:52 -0400 Subject: [PATCH 5/5] remove Request.send(session) --- requests/models.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/requests/models.py b/requests/models.py index 6018d27c..cdc17563 100644 --- a/requests/models.py +++ b/requests/models.py @@ -577,10 +577,6 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): for event in hooks: self.register_hook(event, hooks[event]) - def send(self, session): - """Sends the given PreparedRequest to the given session.""" - return session.send(self) - class Response(object): """The :class:`Response ` object, which contains a @@ -714,10 +710,10 @@ class Response(object): """True if this Response one of the permanent versions of redirect.""" return ('location' in self.headers and self.status_code in (codes.moved_permanently, codes.permanent_redirect)) + @property def next(self): """Returns a PreparedRequest for the next request in a redirect chain, if there is one.""" - if self.is_redirect: - return self._next + return self._next @property def apparent_encoding(self):