Decoding http2 frame header/data in Go

2019-08-16 06:31发布

I am trying to read from a tcp connection which contains HTTP/2 data. Below is the code for reading HEADERS frame -

framer := http2.NewFramer(conn, conn)
frame, _ := framer.ReadFrame()

fmt.Printf("fh type: %s\n", frame.Header().Type)
fmt.Printf("fh type: %d\n", frame.Header().Type)
fmt.Printf("fh flag: %d\n", frame.Header().Flags)
fmt.Printf("fh length: %d\n", frame.Header().Length)
fmt.Printf("fh streamid: %d\n", frame.Header().StreamID)
headersframe := (frame1.(*http2.HeadersFrame))
fmt.Printf("stream ended? %v\n", headersframe.StreamEnded())
fmt.Printf("block fragment: %x\n", headersframe.HeaderBlockFragment())        

I send request using curl as -

curl -v https://127.0.0.1:8000/ -k --http2

This is the output I get (after reading connection preface and SETTINGS), if I read from the conn using above code -

fh type: HEADERS
fh type: 1
fh flag: 5
fh length: 30
fh streamid: 1
stream ended? true
block fragment: 828487418a089d5c0b8170dc6c4d8b7a8825b650c3abb6f2e053032a2f2a

I understand the ouput, except the block fragment part and how to decode it into ascii string? I want to know the protocol/method/url path information.

标签: http go http2
2条回答
时光不老,我们不散
2楼-- · 2019-08-16 06:46

The "header block fragment" is encoded using HPACK.

Go has an implementation to encode and decode HPACK, so you don't have to write your own.

You can find here an example of using both the encoder and decoder Go API.

查看更多
走好不送
3楼-- · 2019-08-16 06:49

I figured it out using Go hpack library (https://godoc.org/golang.org/x/net/http2/hpack) -

decoder := hpack.NewDecoder(2048, nil)
hf, _ := decoder.DecodeFull(headersframe.HeaderBlockFragment())
for _, h := range hf {
      fmt.Printf("%s\n", h.Name + ":" + h.Value)
}

This prints -

:method:GET
:path:/
:scheme:https
:authority:127.0.0.1:5252
user-agent:curl/7.58.0
accept:*/*
查看更多
登录 后发表回答