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:

    ...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.