(self)
| 622 | return False |
| 623 | |
| 624 | def finish(self) -> None: |
| 625 | assert self.code is not None |
| 626 | data = b"".join(self.chunks) |
| 627 | self._remove_timeout() |
| 628 | original_request = getattr(self.request, "original_request", self.request) |
| 629 | if self._should_follow_redirect(): |
| 630 | assert isinstance(self.request, _RequestProxy) |
| 631 | assert self.headers is not None |
| 632 | new_request = copy.copy(self.request.request) |
| 633 | new_request.url = urllib.parse.urljoin( |
| 634 | self.request.url, self.headers["Location"] |
| 635 | ) |
| 636 | assert self.request.max_redirects is not None |
| 637 | new_request.max_redirects = self.request.max_redirects - 1 |
| 638 | del new_request.headers["Host"] |
| 639 | # https://tools.ietf.org/html/rfc7231#section-6.4 |
| 640 | # |
| 641 | # The original HTTP spec said that after a 301 or 302 |
| 642 | # redirect, the request method should be preserved. |
| 643 | # However, browsers implemented this by changing the |
| 644 | # method to GET, and the behavior stuck. 303 redirects |
| 645 | # always specified this POST-to-GET behavior, arguably |
| 646 | # for *all* methods, but libcurl < 7.70 only does this |
| 647 | # for POST, while libcurl >= 7.70 does it for other methods. |
| 648 | if (self.code == 303 and self.request.method != "HEAD") or ( |
| 649 | self.code in (301, 302) and self.request.method == "POST" |
| 650 | ): |
| 651 | new_request.method = "GET" |
| 652 | new_request.body = None # type: ignore |
| 653 | for h in [ |
| 654 | "Content-Length", |
| 655 | "Content-Type", |
| 656 | "Content-Encoding", |
| 657 | "Transfer-Encoding", |
| 658 | ]: |
| 659 | try: |
| 660 | del self.request.headers[h] |
| 661 | except KeyError: |
| 662 | pass |
| 663 | new_request.original_request = original_request # type: ignore |
| 664 | final_callback = self.final_callback |
| 665 | self.final_callback = None # type: ignore |
| 666 | self._release() |
| 667 | assert self.client is not None |
| 668 | fut = self.client.fetch(new_request, raise_error=False) |
| 669 | fut.add_done_callback(lambda f: final_callback(f.result())) |
| 670 | self._on_end_request() |
| 671 | return |
| 672 | if self.request.streaming_callback: |
| 673 | buffer = BytesIO() |
| 674 | else: |
| 675 | buffer = BytesIO(data) # TODO: don't require one big string? |
| 676 | response = HTTPResponse( |
| 677 | original_request, |
| 678 | self.code, |
| 679 | reason=getattr(self, "reason", None), |
| 680 | headers=self.headers, |
| 681 | request_time=self.io_loop.time() - self.start_time, |
no test coverage detected