Files
golang.net/http2/h2i
Russ Cox 5f55cee0dc all: go fmt ./...
Make all our package sources use Go 1.17 gofmt format
(adding //go:build lines).

Not strictly necessary but will avoid spurious changes
as files are edited.

Part of //go:build change (#41184).
See https://golang.org/design/draft-gobuild

Change-Id: I5b2b7d93424e828a3c5f76ae3f30ab825aca388e
Reviewed-on: https://go-review.googlesource.com/c/net/+/294371
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2021-02-20 03:31:24 +00:00
..
2021-02-20 03:31:24 +00:00

h2i

h2i is an interactive HTTP/2 ("h2") console debugger. Miss the good ol' days of telnetting to your HTTP/1.n servers? We're bringing you back.

Features:

  • send raw HTTP/2 frames
  • PING
  • SETTINGS
  • HEADERS
  • etc
  • type in HTTP/1.n and have it auto-HPACK/frame-ify it for HTTP/2
  • pretty print all received HTTP/2 frames from the peer (including HPACK decoding)
  • tab completion of commands, options

Not yet features, but soon:

  • unnecessary CONTINUATION frames on short boundaries, to test peer implementations
  • request bodies (DATA frames)
  • send invalid frames for testing server implementations (supported by underlying Framer)

Later:

  • act like a server

Installation

$ go get golang.org/x/net/http2/h2i
$ h2i <host>

Demo

$ h2i
Usage: h2i <hostname>
  
  -insecure
        Whether to skip TLS cert validation
  -nextproto string
        Comma-separated list of NPN/ALPN protocol names to negotiate. (default "h2,h2-14")

$ h2i google.com
Connecting to google.com:443 ...
Connected to 74.125.224.41:443
Negotiated protocol "h2-14"
[FrameHeader SETTINGS len=18]
  [MAX_CONCURRENT_STREAMS = 100]
  [INITIAL_WINDOW_SIZE = 1048576]
  [MAX_FRAME_SIZE = 16384]
[FrameHeader WINDOW_UPDATE len=4]
  Window-Increment = 983041
  
h2i> PING h2iSayHI
[FrameHeader PING flags=ACK len=8]
  Data = "h2iSayHI"
h2i> headers
(as HTTP/1.1)> GET / HTTP/1.1
(as HTTP/1.1)> Host: ip.appspot.com
(as HTTP/1.1)> User-Agent: h2i/brad-n-blake
(as HTTP/1.1)>  
Opening Stream-ID 1:
 :authority = ip.appspot.com
 :method = GET
 :path = /
 :scheme = https
 user-agent = h2i/brad-n-blake
[FrameHeader HEADERS flags=END_HEADERS stream=1 len=77]
  :status = "200"
  alternate-protocol = "443:quic,p=1"
  content-length = "15"
  content-type = "text/html"
  date = "Fri, 01 May 2015 23:06:56 GMT"
  server = "Google Frontend"
[FrameHeader DATA flags=END_STREAM stream=1 len=15]
  "173.164.155.78\n"
[FrameHeader PING len=8]
  Data = "\x00\x00\x00\x00\x00\x00\x00\x00"
h2i> ping  
[FrameHeader PING flags=ACK len=8]  
  Data = "h2i_ping"  
h2i> ping  
[FrameHeader PING flags=ACK len=8]
  Data = "h2i_ping"
h2i> ping
[FrameHeader GOAWAY len=22]
  Last-Stream-ID = 1; Error-Code = PROTOCOL_ERROR (1)

ReadFrame: EOF

Status

Quick few hour hack. So much yet to do. Feel free to file issues for bugs or wishlist items, but @bmizerany and I aren't yet accepting pull requests until things settle down.