Search code examples
chttp2nghttp2

Cannot see the Http-Settings Header in the nghttp2 example


I am currently trying to learn nghttp2 and was trying to execute the client code which is provided at the bottom of this page:

https://nghttp2.org/documentation/tutorial-client.html

I executed the above C code doing the following:

./libevent-client URL

My Server is Windows IIS 10.0 and i want to see the http2-settings frame in the output of the header. As of now it is showing the following output:

Connected
Request headers:
:method: GET
:scheme: https
:authority: MY URL
:path: /

Response headers from stream ID=1:
:status: 200
content-type: text/html
last-modified: Mon, 01 Jul 2019 17:57:17 GMT
accept-ranges: bytes
etag: "c7c5406c3630d51:0"
server: Microsoft-IIS/10.0
date: Mon, 08 Jul 2019 16:02:27 GMT
content-length:51
All headers received

<html><head>Hello</head><html>

I need to know what should i need in the code to see whether the http-settings are getting passed on with the request. I know that following function does the work of sending the SETTINGS frames with the request:

static void send_client_connection_header(http2_session_data *session_data) {
  nghttp2_settings_entry iv[1] = {
      {NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 100}};
  int rv;

  /* client 24 bytes magic string will be sent by nghttp2 library */
  rv = nghttp2_submit_settings(session_data->session, NGHTTP2_FLAG_NONE, iv,
                               ARRLEN(iv));
  if (rv != 0) {
    errx(1, "Could not submit SETTINGS: %s", nghttp2_strerror(rv));
  }
}

I also don't know what is the tag we use for HTTP-Settings in http2 protocol just like for method we have ":method", for scheme ":scheme" etc. I couldn't find it even in the RFC.


Solution

  • The HTTP/2 settings frame is not an HTTP Header - it is a separate message sent at the beginning of connections. Therefore it is not possible to display it like as if it was an HTTP Header.

    HTTP/2 contains many such non-visible control frames:

    • SETTINGS frame to define how the connection is used
    • WINDOW_UPDATE frame to implement flow control
    • PRIORITY frame to reprioritise streams (and therefore responses).

    ...etc.

    Typically browsers and servers do not show these Control messages to the user or even in developer tools. Chrome allows you to see them using the chrome://net-export URL, or you can use a network sniffing tool like Wireshark to see them.

    One of the easiest ways however, and a very good way to learn HTTP/2 by examining the raw frames, is to use the nghttpd tool (which is part of the nghttp2 suite) to create an HTTP/2 server that can log any messages sent to it when run in verbose mode, like this:

    nghttpd -v 443 server.key server.crt
    

    I discuss how to do this in more depth in my book, which you can preview online for free for 5 mins a day at: https://livebook.manning.com/#!/book/http2-in-action/chapter-4/176

    One thing I should say is that when connecting over non-encrypted HTTP/1.1 (as opposed to HTTPS) and then upgrading to HTTP/2 then the Settings are sent in an HTTP Header (called HTTP2-Settings) but this is a special case, and when this is sent the message is an HTTP/1.1 message. Additionally browsers only support HTTP/2 over HTTPS (for good reasons) and I see you are using HTTPS too. So I would ignore this and only mentioning it for completeness sake.