Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

_HTTPConnection: check location on _should_follow_redirect() and retain safe request when following redirects #2409

Merged
merged 5 commits into from
Jun 28, 2018

Conversation

garenchan
Copy link
Contributor

@garenchan garenchan commented Jun 1, 2018

  1. http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.3
    According to the spec, the temporary URI may not be specified when the request method was HEAD.
    while check _should_follow_redirect(), doesn't verify whether location is specified.

    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))

  2. AsyncHTTPClient always use GET method on following redirects

    if self.code in (302, 303):
    new_request.method = "GET"

    but while use CURL with HEAD method, CURL will also use HEAD method on following redirects:

# curl -v -L --head http://172.18.231.164:9999/test
* Hostname was NOT found in DNS cache
*   Trying 172.18.231.164...
* Connected to 172.18.231.164 (172.18.231.164) port 9999 (#0)
> HEAD /test HTTP/1.1
> User-Agent: curl/7.35.0
> Host: 172.18.231.164:9999
> Accept: */*
> 
< HTTP/1.1 302 Found
HTTP/1.1 302 Found
< Location: /dest
Location: /dest
* Server TornadoServer/5.0.2 is not blacklisted
< Server: TornadoServer/5.0.2
Server: TornadoServer/5.0.2
< Content-Length: 0
Content-Length: 0
< Content-Type: text/html; charset=UTF-8
Content-Type: text/html; charset=UTF-8
< Date: Fri, 01 Jun 2018 11:21:35 GMT
Date: Fri, 01 Jun 2018 11:21:35 GMT

< 
* Connection #0 to host 172.18.231.164 left intact
* Issue another request to this URL: 'http://172.18.231.164:9999/dest'
* Found bundle for host 172.18.231.164: 0xba18f0
* Re-using existing connection! (#0) with host 172.18.231.164
* Connected to 172.18.231.164 (172.18.231.164) port 9999 (#0)
> HEAD /dest HTTP/1.1
> User-Agent: curl/7.35.0
> Host: 172.18.231.164:9999
> Accept: */*
> 
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Content-Length: 10
Content-Length: 10
* Server TornadoServer/5.0.2 is not blacklisted
< Server: TornadoServer/5.0.2
Server: TornadoServer/5.0.2
< Etag: "9c0e5ce7f4b8696ea9ab7095b94bb717d09718a9"
Etag: "9c0e5ce7f4b8696ea9ab7095b94bb717d09718a9"
< Content-Type: text/html; charset=UTF-8
Content-Type: text/html; charset=UTF-8
< Date: Fri, 01 Jun 2018 11:21:35 GMT
Date: Fri, 01 Jun 2018 11:21:35 GMT

< 
* Connection #0 to host 172.18.231.164 left intact

self.code in (301, 302, 303, 307, 308)):
return False
# http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4
# According to the spec, the temporary URI may not be specified when the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're misreading the spec. The Location header SHOULD be given no matter what the request method was. The only difference with HEAD is whether there should be a body for clients that don't follow redirects automatically (there's nothing special about HEAD with 302 in this respect; that's how HEAD always works).

Also, RFC2616 is obsolete. The current definition of the 302 response code is https://tools.ietf.org/html/rfc7231#section-6.4.3.

# TODO: Unless the request method was HEAD, give a warning or raise an
# exception when the temporary URI is not specified?
redirect_location = self.headers.get("Location")
return (redirect_location is not None)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The actual code change is fine, but I think I'd add it in to the same return expression above (and self.headers.get('Location') is not None) instead of making this method have two separate return statements.

@garenchan
Copy link
Contributor Author

Sorry, I really misunderstood the spec because of my poor English!
When following 301/302/303 redirects, should we retain the original request method if it is GET, HEAD or OPTIONS?

@garenchan garenchan closed this Jun 3, 2018
@garenchan garenchan reopened this Jun 3, 2018
@garenchan garenchan changed the title _HTTPConnection: verify whether location is specified while check _should_follow_redirect() _HTTPConnection: check location on _should_follow_redirect() and retain safe request when following redirects Jun 3, 2018
@@ -209,6 +209,7 @@ def _on_timeout(self, key, info=None):

class _HTTPConnection(httputil.HTTPMessageDelegate):
_SUPPORTED_METHODS = set(["GET", "HEAD", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"])
_SAFE_NETHODS = set(["GET", "HEAD", "OPTIONS"])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor typo: N should be M in "NETHODS"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your reminding. I‘m too careless.

@bdarnell
Copy link
Member

Thanks!

@bdarnell bdarnell merged commit 859a038 into tornadoweb:master Jun 28, 2018
@garenchan garenchan deleted the bugfix branch June 28, 2018 01:22
bdarnell added a commit to bdarnell/tornado that referenced this pull request Jul 11, 2018
…and retain safe request when following redirects (tornadoweb#2409)"

This reverts commit 859a038.

This commit was merged after the release of 5.1b1 with insufficient
consideration and testing. I'll bring this back in the 6.0 cycle with
a test
bdarnell added a commit to bdarnell/tornado that referenced this pull request Jul 11, 2018
…irect() and retain safe request when following redirects (tornadoweb#2409)""

This reverts commit dda77f2.
bdarnell added a commit to bdarnell/tornado that referenced this pull request Jan 1, 2019
…irect() and retain safe request when following redirects (tornadoweb#2409)""

This reverts commit dda77f2.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants