(self, event: h2.events.Event)
| 578 | yield from super()._handle_event(event) |
| 579 | |
| 580 | def handle_h2_event(self, event: h2.events.Event) -> CommandGenerator[bool]: |
| 581 | if isinstance(event, h2.events.ResponseReceived): |
| 582 | if ( |
| 583 | self.streams.get(event.stream_id, None) |
| 584 | is not StreamState.EXPECTING_HEADERS |
| 585 | ): |
| 586 | yield from self.protocol_error(f"Received unexpected HTTP/2 response.") |
| 587 | return True |
| 588 | |
| 589 | try: |
| 590 | status_code, headers = parse_h2_response_headers(event.headers) |
| 591 | except ValueError as e: |
| 592 | yield from self.protocol_error(f"Invalid HTTP/2 response headers: {e}") |
| 593 | return True |
| 594 | |
| 595 | response = http.Response( |
| 596 | http_version=b"HTTP/2.0", |
| 597 | status_code=status_code, |
| 598 | reason=b"", |
| 599 | headers=headers, |
| 600 | content=None, |
| 601 | trailers=None, |
| 602 | timestamp_start=time.time(), |
| 603 | timestamp_end=None, |
| 604 | ) |
| 605 | self.streams[event.stream_id] = StreamState.HEADERS_RECEIVED |
| 606 | yield ReceiveHttp( |
| 607 | ResponseHeaders(event.stream_id, response, bool(event.stream_ended)) |
| 608 | ) |
| 609 | return False |
| 610 | elif isinstance(event, h2.events.InformationalResponseReceived): |
| 611 | # We violate the spec here ("A proxy MUST forward 1xx responses", RFC 7231), |
| 612 | # but that's probably fine: |
| 613 | # - 100 Continue is sent by mitmproxy to clients (irrespective of what the server does). |
| 614 | # - 101 Switching Protocols is not allowed for HTTP/2. |
| 615 | # - 102 Processing is WebDAV only and also ignorable. |
| 616 | # - 103 Early Hints is not mission-critical. |
| 617 | headers = http.Headers(event.headers) |
| 618 | status: str | int = "<unknown status>" |
| 619 | try: |
| 620 | status = int(headers[":status"]) |
| 621 | reason = status_codes.RESPONSES.get(status, "") |
| 622 | except (KeyError, ValueError): |
| 623 | reason = "" |
| 624 | yield Log(f"Swallowing HTTP/2 informational response: {status} {reason}") |
| 625 | return False |
| 626 | elif isinstance(event, h2.events.RequestReceived): |
| 627 | yield from self.protocol_error( |
| 628 | f"HTTP/2 protocol error: received request from server" |
| 629 | ) |
| 630 | return True |
| 631 | elif isinstance(event, h2.events.RemoteSettingsChanged): |
| 632 | # We have received at least one settings from now, |
| 633 | # which means we can rely on the max concurrency in remote_settings |
| 634 | self.provisional_max_concurrency = None |
| 635 | return (yield from super().handle_h2_event(event)) |
| 636 | else: |
| 637 | return (yield from super().handle_h2_event(event)) |
nothing calls this directly
no test coverage detected