MCPcopy
hub / github.com/tornadoweb/tornado / finish

Method finish

tornado/simple_httpclient.py:622–721  ·  view source on GitHub ↗
(self)

Source from the content-addressed store, hash-verified

620 return False
621
622 def finish(self) -> None:
623 assert self.code is not None
624 data = b"".join(self.chunks)
625 self._remove_timeout()
626 original_request = getattr(self.request, "original_request", self.request)
627 if self._should_follow_redirect():
628 assert isinstance(self.request, _RequestProxy)
629 assert self.headers is not None
630 new_request = copy.copy(self.request.request)
631 new_request.url = urllib.parse.urljoin(
632 self.request.url, self.headers["Location"]
633 )
634 new_request.headers = self.request.headers.copy()
635 parsed_orig_url = urllib.parse.urlsplit(original_request.url)
636 parsed_new_url = urllib.parse.urlsplit(new_request.url)
637 if (
638 parsed_orig_url.scheme != parsed_new_url.scheme
639 or parsed_orig_url.netloc != parsed_new_url.netloc
640 ):
641 # Cross-origin redirect: strip auth headers.
642 # Note that while there is no formal specification of headers that should be
643 # stripped here, libcurl strips the Authorization and Cookie headers, so we
644 # do the same.
645 # Reference:
646 # https://github.com/curl/curl/blob/01d8191b25a05e8fa91553a6c0d48acb99907d26/lib/http.c#L1827-L1828
647 #
648 # Note that checking for cross-origin redirects is a crude heuristic. It is both
649 # too weak (e.g. cookies that have a path attribute may need to be stripped even on
650 # same-origin redirects) and too strong (e.g. cookies may be kept on cross-host
651 # redirects within the same domain). However, we cannot know the full details of
652 # the cookie policy at this layer, so we use the same heuristic as libcurl.
653 # Applications that need more control over behavior on redirects can set
654 # follow_redirects=False and handle 3xx responses themselves.
655 new_request.auth_username = None
656 new_request.auth_password = None
657 if "@" in parsed_new_url.netloc:
658 if parsed_new_url.port is not None:
659 new_netloc = f"{parsed_new_url.hostname}:{parsed_new_url.port}"
660 else:
661 assert parsed_new_url.hostname is not None
662 new_netloc = parsed_new_url.hostname
663 parsed_new_url = parsed_new_url._replace(netloc=new_netloc)
664 new_request.url = urllib.parse.urlunsplit(parsed_new_url)
665 for h in ["Authorization", "Cookie"]:
666 try:
667 del new_request.headers[h]
668 except KeyError:
669 pass
670 assert self.request.max_redirects is not None
671 new_request.max_redirects = self.request.max_redirects - 1
672 del new_request.headers["Host"]
673 # https://tools.ietf.org/html/rfc7231#section-6.4
674 #
675 # The original HTTP spec said that after a 301 or 302
676 # redirect, the request method should be preserved.
677 # However, browsers implemented this by changing the
678 # method to GET, and the behavior stuck. 303 redirects
679 # always specified this POST-to-GET behavior, arguably

Callers 1

_write_bodyMethod · 0.45

Calls 11

_remove_timeoutMethod · 0.95
_releaseMethod · 0.95
_on_end_requestMethod · 0.95
_run_callbackMethod · 0.95
HTTPResponseClass · 0.90
joinMethod · 0.80
copyMethod · 0.80
resultMethod · 0.80
timeMethod · 0.80
fetchMethod · 0.45

Tested by

no test coverage detected