PcapFileEx.HTTP2.StreamState (pcap_file_ex v0.5.5)
View SourcePer-stream state for HTTP/2 stream reconstruction.
Tracks request and response data including headers, body, and trailers. Handles CONTINUATION frame buffering for split header blocks.
Stream Lifecycle
- Created when first frame for stream ID is seen
- Receives HEADERS (possibly with CONTINUATION frames)
- May receive DATA frames
- May receive trailing HEADERS (trailers)
- Completes when both request and response have END_STREAM
- May be terminated early by RST_STREAM/GOAWAY
CONTINUATION Handling
When a HEADERS frame has END_HEADERS=false, subsequent CONTINUATION frames are buffered until END_HEADERS=true. During this time:
awaiting_continuationis truepending_header_blockaccumulates the header block fragmentspending_end_streamtracks if the initial HEADERS had END_STREAMpending_directiontracks who sent the initial HEADERS
Timestamps
created_at: When first frame for this stream was seencompleted_at: When BOTH request_complete AND response_complete became true
Summary
Functions
Append a CONTINUATION frame's payload to the pending header block.
Append data to request body.
Append data to response body.
Check if stream is complete (both request and response finished).
Complete the header block and clear continuation state.
Create a new stream state.
Get the complete request body as a binary.
Get the complete response body as a binary.
Record an error on the stream.
Set request headers (from initial HEADERS frame with :method).
Set request trailers (HEADERS with no pseudo-headers, from client).
Set response headers (from HEADERS frame with :status).
Set response trailers (HEADERS with no pseudo-headers, from server).
Start buffering a header block that spans multiple frames.
Mark stream as terminated with a reason.
Types
@type t() :: %PcapFileEx.HTTP2.StreamState{ awaiting_continuation: boolean(), completed_at: DateTime.t() | nil, created_at: DateTime.t(), error: term() | nil, informational_responses: [PcapFileEx.HTTP2.Headers.t()], pending_direction: boolean() | nil, pending_end_stream: boolean(), pending_header_block: binary(), request_body: iodata(), request_complete: boolean(), request_headers: PcapFileEx.HTTP2.Headers.t() | nil, request_trailers: PcapFileEx.HTTP2.Headers.t() | nil, response_body: iodata(), response_complete: boolean(), response_headers: PcapFileEx.HTTP2.Headers.t() | nil, response_trailers: PcapFileEx.HTTP2.Headers.t() | nil, stream_id: non_neg_integer(), terminated: boolean(), termination_reason: termination_reason() | nil }
@type termination_reason() :: {:rst_stream, non_neg_integer()} | {:goaway, non_neg_integer()} | :truncated_no_response | :truncated_incomplete_response | :truncated_incomplete_headers | :tcp_fin_without_end_stream | {:hpack_error, term()} | {:frame_error, term()}
Functions
Append a CONTINUATION frame's payload to the pending header block.
@spec append_request_data(t(), binary(), boolean(), DateTime.t()) :: t()
Append data to request body.
@spec append_response_data(t(), binary(), boolean(), DateTime.t()) :: t()
Append data to response body.
Check if stream is complete (both request and response finished).
Complete the header block and clear continuation state.
Returns the complete header block and updated stream.
@spec new(non_neg_integer(), DateTime.t()) :: t()
Create a new stream state.
Get the complete request body as a binary.
Get the complete response body as a binary.
Record an error on the stream.
@spec set_request_headers(t(), PcapFileEx.HTTP2.Headers.t(), boolean(), DateTime.t()) :: t()
Set request headers (from initial HEADERS frame with :method).
@spec set_request_trailers(t(), PcapFileEx.HTTP2.Headers.t(), DateTime.t()) :: t()
Set request trailers (HEADERS with no pseudo-headers, from client).
@spec set_response_headers(t(), PcapFileEx.HTTP2.Headers.t(), boolean(), DateTime.t()) :: t()
Set response headers (from HEADERS frame with :status).
Handles both informational (1xx) and final responses.
@spec set_response_trailers(t(), PcapFileEx.HTTP2.Headers.t(), DateTime.t()) :: t()
Set response trailers (HEADERS with no pseudo-headers, from server).
Start buffering a header block that spans multiple frames.
Called when HEADERS frame has END_HEADERS=false.
@spec terminate(t(), termination_reason()) :: t()
Mark stream as terminated with a reason.