Home | History | Annotate | Download | only in http2
      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 // ConnectionError is an error that results in the termination of the
     57 // entire connection.
     58 type ConnectionError ErrCode
     59 
     60 func (e ConnectionError) Error() string { return fmt.Sprintf("connection error: %s", ErrCode(e)) }
     61 
     62 // StreamError is an error that only affects one stream within an
     63 // HTTP/2 connection.
     64 type StreamError struct {
     65 	StreamID uint32
     66 	Code     ErrCode
     67 	Cause    error // optional additional detail
     68 }
     69 
     70 func streamError(id uint32, code ErrCode) StreamError {
     71 	return StreamError{StreamID: id, Code: code}
     72 }
     73 
     74 func (e StreamError) Error() string {
     75 	if e.Cause != nil {
     76 		return fmt.Sprintf("stream error: stream ID %d; %v; %v", e.StreamID, e.Code, e.Cause)
     77 	}
     78 	return fmt.Sprintf("stream error: stream ID %d; %v", e.StreamID, e.Code)
     79 }
     80 
     81 // 6.9.1 The Flow Control Window
     82 // "If a sender receives a WINDOW_UPDATE that causes a flow control
     83 // window to exceed this maximum it MUST terminate either the stream
     84 // or the connection, as appropriate. For streams, [...]; for the
     85 // connection, a GOAWAY frame with a FLOW_CONTROL_ERROR code."
     86 type goAwayFlowError struct{}
     87 
     88 func (goAwayFlowError) Error() string { return "connection exceeded flow control window size" }
     89 
     90 // connError represents an HTTP/2 ConnectionError error code, along
     91 // with a string (for debugging) explaining why.
     92 //
     93 // Errors of this type are only returned by the frame parser functions
     94 // and converted into ConnectionError(Code), after stashing away
     95 // the Reason into the Framer's errDetail field, accessible via
     96 // the (*Framer).ErrorDetail method.
     97 type connError struct {
     98 	Code   ErrCode // the ConnectionError error code
     99 	Reason string  // additional reason
    100 }
    101 
    102 func (e connError) Error() string {
    103 	return fmt.Sprintf("http2: connection error: %v: %v", e.Code, e.Reason)
    104 }
    105 
    106 type pseudoHeaderError string
    107 
    108 func (e pseudoHeaderError) Error() string {
    109 	return fmt.Sprintf("invalid pseudo-header %q", string(e))
    110 }
    111 
    112 type duplicatePseudoHeaderError string
    113 
    114 func (e duplicatePseudoHeaderError) Error() string {
    115 	return fmt.Sprintf("duplicate pseudo-header %q", string(e))
    116 }
    117 
    118 type headerFieldNameError string
    119 
    120 func (e headerFieldNameError) Error() string {
    121 	return fmt.Sprintf("invalid header field name %q", string(e))
    122 }
    123 
    124 type headerFieldValueError string
    125 
    126 func (e headerFieldValueError) Error() string {
    127 	return fmt.Sprintf("invalid header field value %q", string(e))
    128 }
    129 
    130 var (
    131 	errMixPseudoHeaderTypes = errors.New("mix of request and response pseudo headers")
    132 	errPseudoAfterRegular   = errors.New("pseudo header field after regular")
    133 )
    134