Skip to content

HTTP2 server_settings frame is ignored #473

@David-Klemenc

Description

@David-Klemenc

Creating a HTTP connection always return the same (server) settings (ignoring the frame sent from the server):

Mint.HTTP2.connect(:http, "localhost", 5001)

{:ok,
 %Mint.HTTP2{
   transport: Mint.Core.Transport.TCP,
   socket: #Port<0.30>,
   mode: :active,
   hostname: "localhost",
   port: 5001,
   scheme: "http",
   authority: "localhost:5001",
   state: :handshaking,
   buffer: "",
   window_size: 65535,
   encode_table: %HPAX.Table{
     protocol_max_table_size: 4096,
     max_table_size: 4096,
     huffman_encoding: :never,
     entries: [],
     size: 0,
     length: 0,
     pending_minimum_resize: nil
   },
   decode_table: %HPAX.Table{
     protocol_max_table_size: 4096,
     max_table_size: 4096,
     huffman_encoding: :never,
     entries: [],
     size: 0,
     length: 0,
     pending_minimum_resize: nil
   },
   ping_queue: {[], []},
   client_settings_queue: {[[]], []},
   next_stream_id: 3,
   streams: %{},
   open_client_stream_count: 0,
   open_server_stream_count: 0,
   ref_to_stream_id: %{},
   server_settings: %{
     max_concurrent_streams: 100,
     max_frame_size: 16384,
     max_header_list_size: :infinity,
     initial_window_size: 65535,
     enable_push: true,
     enable_connect_protocol: false
   },
   client_settings: %{
     max_concurrent_streams: 100,
     max_frame_size: 16384,
     max_header_list_size: :infinity,
     initial_window_size: 65535,
     enable_push: true
   },
   headers_being_processed: nil,
   proxy_headers: [],
   private: %{},
   log: false
 }}

testing the same connection with nghttp returns:

nghttp -nv http://localhost:5001 
[  0.042] Connected
[  0.043] send SETTINGS frame <length=18, flags=0x00, stream_id=0>
          (niv=3)
          [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
          [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
          [SETTINGS_NO_RFC7540_PRIORITIES(0x09):1]
[  0.043] send HEADERS frame <length=49, flags=0x05, stream_id=1>
          ; END_STREAM | END_HEADERS
          (padlen=0)
          ; Open new stream
          :method: GET
          :path: /
          :scheme: http
          :authority: localhost:5001
          priority: u=3
          accept: */*
          accept-encoding: gzip, deflate
          user-agent: nghttp2/1.67.1
[  0.093] recv SETTINGS frame <length=6, flags=0x00, stream_id=0>
          (niv=1)
          [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):255]
[  0.093] recv SETTINGS frame <length=0, flags=0x01, stream_id=0>
          ; ACK
          (niv=0)
[  0.093] send SETTINGS frame <length=0, flags=0x01, stream_id=0>
          ; ACK
          (niv=0)
[  0.124] recv (stream_id=1) :status: 200
[  0.124] recv (stream_id=1) date: Tue, 18 Nov 2025 09:24:23 GMT
[  0.124] recv (stream_id=1) content-length: 1965
[  0.124] recv (stream_id=1) cache-control: max-age=0, private, must-revalidate
[  0.124] recv (stream_id=1) x-request-id: GHkPlXvgXDwp6WIAAAaF
[  0.124] recv HEADERS frame <length=113, flags=0x04, stream_id=1>
          ; END_HEADERS
          (padlen=0)
          ; First response header
[  0.124] recv DATA frame <length=1965, flags=0x01, stream_id=1>
          ; END_STREAM
[  0.125] send GOAWAY frame <length=8, flags=0x00, stream_id=0>
          (last_stream_id=0, error_code=NO_ERROR(0x00), opaque_data(0)=[])

Finch does not show the correct max_concurrent_streams for the server which are:
SETTINGS_MAX_CONCURRENT_STREAMS(0x03):255

I setup the server with bandit - here is the config that sets max_concurrent_streams option:

{
  Bandit,
  http_2_options: [default_local_settings: [max_concurrent_streams: 255]],
  scheme: :http,
  plug: BanditRouter,
  port: 5001,
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions