Decoding http2 frame header/data in Go

2019-08-16 07:00发布

问题:

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.

回答1:

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.



回答2:

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:*/*


标签: http go http2