errors.go raw

   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  
   5  package http2
   6  
   7  import (
   8  	"errors"
   9  	"fmt"
  10  )
  11  
  12  // An ErrCode is an unsigned 32-bit error code as defined in the HTTP/2 spec.
  13  type ErrCode uint32
  14  
  15  const (
  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  
  32  var 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  
  49  func (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  
  56  func (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.
  65  type ConnectionError ErrCode
  66  
  67  func (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.
  71  type 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.
  80  var errFromPeer = errors.New("received from peer")
  81  
  82  func streamError(id uint32, code ErrCode) StreamError {
  83  	return StreamError{StreamID: id, Code: code}
  84  }
  85  
  86  func (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."
  98  type goAwayFlowError struct{}
  99  
 100  func (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.
 109  type connError struct {
 110  	Code   ErrCode // the ConnectionError error code
 111  	Reason string  // additional reason
 112  }
 113  
 114  func (e connError) Error() string {
 115  	return fmt.Sprintf("http2: connection error: %v: %v", e.Code, e.Reason)
 116  }
 117  
 118  type pseudoHeaderError string
 119  
 120  func (e pseudoHeaderError) Error() string {
 121  	return fmt.Sprintf("invalid pseudo-header %q", string(e))
 122  }
 123  
 124  type duplicatePseudoHeaderError string
 125  
 126  func (e duplicatePseudoHeaderError) Error() string {
 127  	return fmt.Sprintf("duplicate pseudo-header %q", string(e))
 128  }
 129  
 130  type headerFieldNameError string
 131  
 132  func (e headerFieldNameError) Error() string {
 133  	return fmt.Sprintf("invalid header field name %q", string(e))
 134  }
 135  
 136  type headerFieldValueError string
 137  
 138  func (e headerFieldValueError) Error() string {
 139  	return fmt.Sprintf("invalid header field value for %q", string(e))
 140  }
 141  
 142  var (
 143  	errMixPseudoHeaderTypes = errors.New("mix of request and response pseudo headers")
 144  	errPseudoAfterRegular   = errors.New("pseudo header field after regular")
 145  )
 146