PcapFileEx.HTTP2.IncompleteExchange (pcap_file_ex v0.5.5)

View Source

Represents 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: client and server are set, endpoint_a and endpoint_b are nil
  • When identification fails: endpoint_a and endpoint_b are set, client and server are 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

Types

Tuple of {ip_tuple, port} for backwards compatibility

t()

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

legacy_endpoint()

@type legacy_endpoint() :: {tuple(), non_neg_integer()}

Tuple of {ip_tuple, port} for backwards compatibility

reason()

@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()}

t()

@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

client_identified?(incomplete_exchange)

@spec client_identified?(t()) :: boolean()

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

endpoints(incomplete_exchange)

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

from_stream(stream, tcp_flow)

@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 state
  • tcp_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)

from_stream(stream, arg, opts)

reason_string(arg1)

@spec reason_string(reason()) :: String.t()

Get a human-readable description of the incompletion reason.

to_string(exchange)

@spec to_string(t()) :: String.t()

Get a friendly string representation of the incomplete exchange.