1
2
3
4
5 package http2
6
7 import (
8 "errors"
9 "fmt"
10 "reflect"
11 )
12
13
14 type ErrCode uint32
15
16 const (
17 ErrCodeNo ErrCode = 0x0
18 ErrCodeProtocol ErrCode = 0x1
19 ErrCodeInternal ErrCode = 0x2
20 ErrCodeFlowControl ErrCode = 0x3
21 ErrCodeSettingsTimeout ErrCode = 0x4
22 ErrCodeStreamClosed ErrCode = 0x5
23 ErrCodeFrameSize ErrCode = 0x6
24 ErrCodeRefusedStream ErrCode = 0x7
25 ErrCodeCancel ErrCode = 0x8
26 ErrCodeCompression ErrCode = 0x9
27 ErrCodeConnect ErrCode = 0xa
28 ErrCodeEnhanceYourCalm ErrCode = 0xb
29 ErrCodeInadequateSecurity ErrCode = 0xc
30 ErrCodeHTTP11Required ErrCode = 0xd
31 )
32
33 var errCodeName = map[ErrCode]string{
34 ErrCodeNo: "NO_ERROR",
35 ErrCodeProtocol: "PROTOCOL_ERROR",
36 ErrCodeInternal: "INTERNAL_ERROR",
37 ErrCodeFlowControl: "FLOW_CONTROL_ERROR",
38 ErrCodeSettingsTimeout: "SETTINGS_TIMEOUT",
39 ErrCodeStreamClosed: "STREAM_CLOSED",
40 ErrCodeFrameSize: "FRAME_SIZE_ERROR",
41 ErrCodeRefusedStream: "REFUSED_STREAM",
42 ErrCodeCancel: "CANCEL",
43 ErrCodeCompression: "COMPRESSION_ERROR",
44 ErrCodeConnect: "CONNECT_ERROR",
45 ErrCodeEnhanceYourCalm: "ENHANCE_YOUR_CALM",
46 ErrCodeInadequateSecurity: "INADEQUATE_SECURITY",
47 ErrCodeHTTP11Required: "HTTP_1_1_REQUIRED",
48 }
49
50 func (e ErrCode) String() string {
51 if s, ok := errCodeName[e]; ok {
52 return s
53 }
54 return fmt.Sprintf("unknown error code 0x%x", uint32(e))
55 }
56
57 func (e ErrCode) stringToken() string {
58 if s, ok := errCodeName[e]; ok {
59 return s
60 }
61 return fmt.Sprintf("ERR_UNKNOWN_%d", uint32(e))
62 }
63
64
65
66 type ConnectionError ErrCode
67
68 func (e ConnectionError) Error() string { return fmt.Sprintf("connection error: %s", ErrCode(e)) }
69
70
71
72 type StreamError struct {
73 StreamID uint32
74 Code ErrCode
75 Cause error
76 }
77
78
79
80
81 var errFromPeer = errors.New("received from peer")
82
83 func streamError(id uint32, code ErrCode) StreamError {
84 return StreamError{StreamID: id, Code: code}
85 }
86
87 func (e StreamError) Error() string {
88 if e.Cause != nil {
89 return fmt.Sprintf("stream error: stream ID %d; %v; %v", e.StreamID, e.Code, e.Cause)
90 }
91 return fmt.Sprintf("stream error: stream ID %d; %v", e.StreamID, e.Code)
92 }
93
94
95 func (e StreamError) As(target any) bool {
96 dst := reflect.ValueOf(target).Elem()
97 dstType := dst.Type()
98 if dstType.Kind() != reflect.Struct {
99 return false
100 }
101 src := reflect.ValueOf(e)
102 srcType := src.Type()
103 numField := srcType.NumField()
104 if dstType.NumField() != numField {
105 return false
106 }
107 for i := 0; i < numField; i++ {
108 sf := srcType.Field(i)
109 df := dstType.Field(i)
110 if sf.Name != df.Name || !sf.Type.ConvertibleTo(df.Type) {
111 return false
112 }
113 }
114 for i := 0; i < numField; i++ {
115 df := dst.Field(i)
116 df.Set(src.Field(i).Convert(df.Type()))
117 }
118 return true
119 }
120
121
122
123
124
125
126 type goAwayFlowError struct{}
127
128 func (goAwayFlowError) Error() string { return "connection exceeded flow control window size" }
129
130
131
132
133
134
135
136
137 type connError struct {
138 Code ErrCode
139 Reason string
140 }
141
142 func (e connError) Error() string {
143 return fmt.Sprintf("http2: connection error: %v: %v", e.Code, e.Reason)
144 }
145
146 type pseudoHeaderError string
147
148 func (e pseudoHeaderError) Error() string {
149 return fmt.Sprintf("invalid pseudo-header %q", string(e))
150 }
151
152 type duplicatePseudoHeaderError string
153
154 func (e duplicatePseudoHeaderError) Error() string {
155 return fmt.Sprintf("duplicate pseudo-header %q", string(e))
156 }
157
158 type headerFieldNameError string
159
160 func (e headerFieldNameError) Error() string {
161 return fmt.Sprintf("invalid header field name %q", string(e))
162 }
163
164 type headerFieldValueError string
165
166 func (e headerFieldValueError) Error() string {
167 return fmt.Sprintf("invalid header field value for %q", string(e))
168 }
169
170 var (
171 errMixPseudoHeaderTypes = errors.New("mix of request and response pseudo headers")
172 errPseudoAfterRegular = errors.New("pseudo header field after regular")
173 )
174
View as plain text