-
Notifications
You must be signed in to change notification settings - Fork 12
/
http2.go
84 lines (73 loc) · 2.05 KB
/
http2.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// Copyright 2020 The searKing Author. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package http2
import (
"io"
"golang.org/x/net/http2"
"golang.org/x/net/http2/hpack"
)
const (
// http://http2.github.io/http2-spec/#SettingValues
initialHeaderTableSize = 4096
)
// MatchHTTP2Header matches all headerFields if len(filterNames) == 0
func MatchHTTP2Header(w io.Writer, r io.Reader, filterNames map[string]struct{}, matches func(headerFields map[string]hpack.HeaderField) (matched bool)) (matched bool) {
// filter http2 only
if !HasClientPreface(r) {
return false
}
readAll := len(filterNames) > 0
done := false
framer := http2.NewFramer(w, r)
var filteredHeaderFields map[string]hpack.HeaderField
readMetaHeaders := hpack.NewDecoder(initialHeaderTableSize, func(f hpack.HeaderField) {
if _, has := filterNames[f.Name]; has || readAll {
filteredHeaderFields[f.Name] = f
}
})
frame, err := framer.ReadFrame()
if err != nil {
return false
}
sf, ok := frame.(*http2.SettingsFrame)
if !ok {
return false
}
if err := handleSettings(framer, sf); err != nil {
return false
}
for {
frame, err := framer.ReadFrame()
if err != nil {
return false
}
switch frame := frame.(type) {
case *http2.SettingsFrame:
if err := handleSettings(framer, sf); err != nil {
return false
}
case *http2.ContinuationFrame:
if _, err := readMetaHeaders.Write(frame.HeaderBlockFragment()); err != nil {
return false
}
done = frame.HeadersEnded()
case *http2.HeadersFrame:
if _, err := readMetaHeaders.Write(frame.HeaderBlockFragment()); err != nil {
return false
}
done = frame.HeadersEnded()
}
if done || (!readAll && len(filteredHeaderFields) == len(filterNames)) {
return matches(filteredHeaderFields)
}
}
}
func handleSettings(framer *http2.Framer, frame *http2.SettingsFrame) error {
// Sender acknowledged the SETTINGS frame. No need to write
// SETTINGS again.
if frame.IsAck() {
return nil
}
return framer.WriteSettings()
}