MCPcopy Create free account
hub / github.com/mitmproxy/mitmproxy / handle_h2_event

Method handle_h2_event

mitmproxy/proxy/layers/http/_http2.py:580–637  ·  view source on GitHub ↗
(self, event: h2.events.Event)

Source from the content-addressed store, hash-verified

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

Callers

nothing calls this directly

Calls 7

ReceiveHttpClass · 0.85
ResponseHeadersClass · 0.85
protocol_errorMethod · 0.80
LogClass · 0.50
getMethod · 0.45
handle_h2_eventMethod · 0.45

Tested by

no test coverage detected