class _HTTPConnection(httputil.HTTPMessageDelegate):
_SUPPORTED_METHODS = set(["GET", "HEAD", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"])
+ _SAFE_METHODS = set(["GET", "HEAD", "OPTIONS"])
def __init__(self, client, request, release_callback,
final_callback, max_buffer_size, tcp_client,
def _should_follow_redirect(self):
return (self.request.follow_redirects and
self.request.max_redirects > 0 and
- self.code in (301, 302, 303, 307, 308))
+ self.code in (301, 302, 303, 307, 308) and
+ self.headers.get("Location") is not None)
def finish(self):
data = b''.join(self.chunks)
# treat 302 the same as 303, and many servers use 302 for
# compatibility with pre-HTTP/1.1 user agents which don't
# understand the 303 status.
- if self.code in (302, 303):
- new_request.method = "GET"
+ if self.code in (301, 302, 303):
+ if self.request.method not in self._SAFE_METHODS:
+ new_request.method = "GET"
new_request.body = None
for h in ["Content-Length", "Content-Type",
"Content-Encoding", "Transfer-Encoding"]: