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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions