@@ -3,6 +3,7 @@ package network
3
3
import (
4
4
"context"
5
5
"errors"
6
+ "fmt"
6
7
"io"
7
8
"net"
8
9
"time"
@@ -11,6 +12,49 @@ import (
11
12
// ErrReset is returned when reading or writing on a reset stream.
12
13
var ErrReset = errors .New ("stream reset" )
13
14
15
+ type StreamErrorCode uint32
16
+
17
+ type StreamError struct {
18
+ ErrorCode StreamErrorCode
19
+ Remote bool
20
+ TransportError error
21
+ }
22
+
23
+ func (s * StreamError ) Error () string {
24
+ side := "local"
25
+ if s .Remote {
26
+ side = "remote"
27
+ }
28
+ if s .TransportError != nil {
29
+ return fmt .Sprintf ("stream reset (%s): code: 0x%x: transport error: %s" , side , s .ErrorCode , s .TransportError )
30
+ }
31
+ return fmt .Sprintf ("stream reset (%s): code: 0x%x" , side , s .ErrorCode )
32
+ }
33
+
34
+ func (s * StreamError ) Is (target error ) bool {
35
+ if tse , ok := target .(* StreamError ); ok {
36
+ return tse .ErrorCode == s .ErrorCode && tse .Remote == s .Remote
37
+ }
38
+ return false
39
+ }
40
+
41
+ func (s * StreamError ) Unwrap () []error {
42
+ return []error {ErrReset , s .TransportError }
43
+ }
44
+
45
+ const (
46
+ StreamNoError StreamErrorCode = 0
47
+ StreamProtocolNegotiationFailed StreamErrorCode = 0x1001
48
+ StreamResourceLimitExceeded StreamErrorCode = 0x1002
49
+ StreamRateLimited StreamErrorCode = 0x1003
50
+ StreamProtocolViolation StreamErrorCode = 0x1004
51
+ StreamSupplanted StreamErrorCode = 0x1005
52
+ StreamGarbageCollected StreamErrorCode = 0x1006
53
+ StreamShutdown StreamErrorCode = 0x1007
54
+ StreamGated StreamErrorCode = 0x1008
55
+ StreamCodeOutOfRange StreamErrorCode = 0x1009
56
+ )
57
+
14
58
// MuxedStream is a bidirectional io pipe within a connection.
15
59
type MuxedStream interface {
16
60
io.Reader
@@ -56,6 +100,11 @@ type MuxedStream interface {
56
100
// side to hang up and go away.
57
101
Reset () error
58
102
103
+ // ResetWithError aborts both ends of the stream with `errCode`. `errCode` is sent
104
+ // to the peer on a best effort basis. For transports that do not support sending
105
+ // error codes to remote peer, the behavior is identical to calling Reset
106
+ ResetWithError (errCode StreamErrorCode ) error
107
+
59
108
SetDeadline (time.Time ) error
60
109
SetReadDeadline (time.Time ) error
61
110
SetWriteDeadline (time.Time ) error
@@ -75,6 +124,10 @@ type MuxedConn interface {
75
124
// Close closes the stream muxer and the the underlying net.Conn.
76
125
io.Closer
77
126
127
+ // CloseWithError closes the connection with errCode. The errCode is sent
128
+ // to the peer.
129
+ CloseWithError (errCode ConnErrorCode ) error
130
+
78
131
// IsClosed returns whether a connection is fully closed, so it can
79
132
// be garbage collected.
80
133
IsClosed () bool
0 commit comments