PcapFileEx.HTTP2.IncompleteExchange (pcap_file_ex v0.5.5)
View SourceRepresents a partial HTTP/2 exchange that couldn't complete.
The reason field indicates why the exchange is incomplete:
Protocol-level termination
{:rst_stream, error_code}- Stream was reset by peer{:goaway, last_stream_id}- Connection was shut down
PCAP truncation (capture ended mid-stream)
:truncated_no_response- Request sent, no response headers seen:truncated_incomplete_response- Response headers seen, no END_STREAM:truncated_incomplete_headers- Mid-CONTINUATION, waiting for END_HEADERS
TCP-level issues
:tcp_fin_without_end_stream- TCP closed before HTTP/2 END_STREAM
Decode errors
{:hpack_error, term()}- HPACK decompression failed{:frame_error, term()}- Malformed frame (bad padding, etc.)
Endpoint Semantics
Exactly one pair of endpoint fields will be set:
- When client/server roles are identified:
clientandserverare set,endpoint_aandendpoint_bare nil - When identification fails:
endpoint_aandendpoint_bare set,clientandserverare nil
Use client_identified?/1 to check which pair is set, and endpoints/1 to get
the pair of endpoints regardless of which fields are populated.
Summary
Functions
Returns true if client/server roles were identified for this exchange.
Returns the pair of endpoints, regardless of whether client/server was identified.
Build an incomplete exchange from a stream state.
Get a human-readable description of the incompletion reason.
Get a friendly string representation of the incomplete exchange.
Types
@type legacy_endpoint() :: {tuple(), non_neg_integer()}
Tuple of {ip_tuple, port} for backwards compatibility
@type reason() :: {:rst_stream, error_code :: non_neg_integer()} | {:goaway, last_stream_id :: non_neg_integer()} | :truncated_no_response | :truncated_incomplete_response | :truncated_incomplete_headers | :tcp_fin_without_end_stream | {:hpack_error, term()} | {:frame_error, term()}
@type t() :: %PcapFileEx.HTTP2.IncompleteExchange{ client: PcapFileEx.Endpoint.t() | nil, endpoint_a: PcapFileEx.Endpoint.t() | nil, endpoint_b: PcapFileEx.Endpoint.t() | nil, reason: reason(), request: PcapFileEx.HTTP2.Exchange.request() | nil, response: PcapFileEx.HTTP2.Exchange.response() | nil, server: PcapFileEx.Endpoint.t() | nil, stream_id: non_neg_integer(), timestamp: DateTime.t() }
Functions
Returns true if client/server roles were identified for this exchange.
Examples
if IncompleteExchange.client_identified?(exchange) do
IO.puts("Client: #{exchange.client}")
else
IO.puts("Endpoints: #{exchange.endpoint_a} <-> #{exchange.endpoint_b}")
end
@spec endpoints(t()) :: {PcapFileEx.Endpoint.t(), PcapFileEx.Endpoint.t()}
Returns the pair of endpoints, regardless of whether client/server was identified.
When client/server identified, returns {client, server}.
When not identified, returns {endpoint_a, endpoint_b}.
Examples
{client, server} = IncompleteExchange.endpoints(exchange)
@spec from_stream( PcapFileEx.HTTP2.StreamState.t(), {legacy_endpoint(), legacy_endpoint()} ) :: t()
Build an incomplete exchange from a stream state.
Determines the reason from the stream's termination_reason or infers from the stream's state.
Parameters
stream- The stream statetcp_flow- Tuple of {{ip_tuple, port}, {ip_tuple, port}} (legacy format)opts- Options::hosts_map- Map of IP strings to hostnames:client_identified- Whether client/server roles were identified (default: true)
@spec from_stream( PcapFileEx.HTTP2.StreamState.t(), {legacy_endpoint(), legacy_endpoint()}, keyword() ) :: t()
Get a human-readable description of the incompletion reason.
Get a friendly string representation of the incomplete exchange.