errors.go

  1// Copyright 2014 The Go Authors. All rights reserved.
  2// Use of this source code is governed by a BSD-style
  3// license that can be found in the LICENSE file.
  4
  5package http2
  6
  7import (
  8	"errors"
  9	"fmt"
 10)
 11
 12// An ErrCode is an unsigned 32-bit error code as defined in the HTTP/2 spec.
 13type ErrCode uint32
 14
 15const (
 16	ErrCodeNo                 ErrCode = 0x0
 17	ErrCodeProtocol           ErrCode = 0x1
 18	ErrCodeInternal           ErrCode = 0x2
 19	ErrCodeFlowControl        ErrCode = 0x3
 20	ErrCodeSettingsTimeout    ErrCode = 0x4
 21	ErrCodeStreamClosed       ErrCode = 0x5
 22	ErrCodeFrameSize          ErrCode = 0x6
 23	ErrCodeRefusedStream      ErrCode = 0x7
 24	ErrCodeCancel             ErrCode = 0x8
 25	ErrCodeCompression        ErrCode = 0x9
 26	ErrCodeConnect            ErrCode = 0xa
 27	ErrCodeEnhanceYourCalm    ErrCode = 0xb
 28	ErrCodeInadequateSecurity ErrCode = 0xc
 29	ErrCodeHTTP11Required     ErrCode = 0xd
 30)
 31
 32var errCodeName = map[ErrCode]string{
 33	ErrCodeNo:                 "NO_ERROR",
 34	ErrCodeProtocol:           "PROTOCOL_ERROR",
 35	ErrCodeInternal:           "INTERNAL_ERROR",
 36	ErrCodeFlowControl:        "FLOW_CONTROL_ERROR",
 37	ErrCodeSettingsTimeout:    "SETTINGS_TIMEOUT",
 38	ErrCodeStreamClosed:       "STREAM_CLOSED",
 39	ErrCodeFrameSize:          "FRAME_SIZE_ERROR",
 40	ErrCodeRefusedStream:      "REFUSED_STREAM",
 41	ErrCodeCancel:             "CANCEL",
 42	ErrCodeCompression:        "COMPRESSION_ERROR",
 43	ErrCodeConnect:            "CONNECT_ERROR",
 44	ErrCodeEnhanceYourCalm:    "ENHANCE_YOUR_CALM",
 45	ErrCodeInadequateSecurity: "INADEQUATE_SECURITY",
 46	ErrCodeHTTP11Required:     "HTTP_1_1_REQUIRED",
 47}
 48
 49func (e ErrCode) String() string {
 50	if s, ok := errCodeName[e]; ok {
 51		return s
 52	}
 53	return fmt.Sprintf("unknown error code 0x%x", uint32(e))
 54}
 55
 56func (e ErrCode) stringToken() string {
 57	if s, ok := errCodeName[e]; ok {
 58		return s
 59	}
 60	return fmt.Sprintf("ERR_UNKNOWN_%d", uint32(e))
 61}
 62
 63// ConnectionError is an error that results in the termination of the
 64// entire connection.
 65type ConnectionError ErrCode
 66
 67func (e ConnectionError) Error() string { return fmt.Sprintf("connection error: %s", ErrCode(e)) }
 68
 69// StreamError is an error that only affects one stream within an
 70// HTTP/2 connection.
 71type StreamError struct {
 72	StreamID uint32
 73	Code     ErrCode
 74	Cause    error // optional additional detail
 75}
 76
 77// errFromPeer is a sentinel error value for StreamError.Cause to
 78// indicate that the StreamError was sent from the peer over the wire
 79// and wasn't locally generated in the Transport.
 80var errFromPeer = errors.New("received from peer")
 81
 82func streamError(id uint32, code ErrCode) StreamError {
 83	return StreamError{StreamID: id, Code: code}
 84}
 85
 86func (e StreamError) Error() string {
 87	if e.Cause != nil {
 88		return fmt.Sprintf("stream error: stream ID %d; %v; %v", e.StreamID, e.Code, e.Cause)
 89	}
 90	return fmt.Sprintf("stream error: stream ID %d; %v", e.StreamID, e.Code)
 91}
 92
 93// 6.9.1 The Flow Control Window
 94// "If a sender receives a WINDOW_UPDATE that causes a flow control
 95// window to exceed this maximum it MUST terminate either the stream
 96// or the connection, as appropriate. For streams, [...]; for the
 97// connection, a GOAWAY frame with a FLOW_CONTROL_ERROR code."
 98type goAwayFlowError struct{}
 99
100func (goAwayFlowError) Error() string { return "connection exceeded flow control window size" }
101
102// connError represents an HTTP/2 ConnectionError error code, along
103// with a string (for debugging) explaining why.
104//
105// Errors of this type are only returned by the frame parser functions
106// and converted into ConnectionError(Code), after stashing away
107// the Reason into the Framer's errDetail field, accessible via
108// the (*Framer).ErrorDetail method.
109type connError struct {
110	Code   ErrCode // the ConnectionError error code
111	Reason string  // additional reason
112}
113
114func (e connError) Error() string {
115	return fmt.Sprintf("http2: connection error: %v: %v", e.Code, e.Reason)
116}
117
118type pseudoHeaderError string
119
120func (e pseudoHeaderError) Error() string {
121	return fmt.Sprintf("invalid pseudo-header %q", string(e))
122}
123
124type duplicatePseudoHeaderError string
125
126func (e duplicatePseudoHeaderError) Error() string {
127	return fmt.Sprintf("duplicate pseudo-header %q", string(e))
128}
129
130type headerFieldNameError string
131
132func (e headerFieldNameError) Error() string {
133	return fmt.Sprintf("invalid header field name %q", string(e))
134}
135
136type headerFieldValueError string
137
138func (e headerFieldValueError) Error() string {
139	return fmt.Sprintf("invalid header field value for %q", string(e))
140}
141
142var (
143	errMixPseudoHeaderTypes = errors.New("mix of request and response pseudo headers")
144	errPseudoAfterRegular   = errors.New("pseudo header field after regular")
145)