github.com/searKing/golang/go@v1.2.117/net/mux/internal/http2/http2.go (about)

     1  // Copyright 2020 The searKing Author. 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  	"io"
     9  
    10  	"golang.org/x/net/http2"
    11  	"golang.org/x/net/http2/hpack"
    12  )
    13  
    14  const (
    15  	// http://http2.github.io/http2-spec/#SettingValues
    16  	initialHeaderTableSize = 4096
    17  )
    18  
    19  // MatchHTTP2Header matches all headerFields if len(filterNames) == 0
    20  func MatchHTTP2Header(w io.Writer, r io.Reader, filterNames map[string]struct{}, matches func(headerFields map[string]hpack.HeaderField) (matched bool)) (matched bool) {
    21  	// filter http2 only
    22  	if !HasClientPreface(r) {
    23  		return false
    24  	}
    25  
    26  	readAll := len(filterNames) > 0
    27  	done := false
    28  	framer := http2.NewFramer(w, r)
    29  	var filteredHeaderFields map[string]hpack.HeaderField
    30  	readMetaHeaders := hpack.NewDecoder(initialHeaderTableSize, func(f hpack.HeaderField) {
    31  		if _, has := filterNames[f.Name]; has || readAll {
    32  			filteredHeaderFields[f.Name] = f
    33  		}
    34  	})
    35  
    36  	frame, err := framer.ReadFrame()
    37  	if err != nil {
    38  		return false
    39  	}
    40  
    41  	sf, ok := frame.(*http2.SettingsFrame)
    42  	if !ok {
    43  		return false
    44  	}
    45  	if err := handleSettings(framer, sf); err != nil {
    46  		return false
    47  	}
    48  
    49  	for {
    50  		frame, err := framer.ReadFrame()
    51  		if err != nil {
    52  			return false
    53  		}
    54  
    55  		switch frame := frame.(type) {
    56  		case *http2.SettingsFrame:
    57  			if err := handleSettings(framer, sf); err != nil {
    58  				return false
    59  			}
    60  		case *http2.ContinuationFrame:
    61  			if _, err := readMetaHeaders.Write(frame.HeaderBlockFragment()); err != nil {
    62  				return false
    63  			}
    64  			done = frame.HeadersEnded()
    65  		case *http2.HeadersFrame:
    66  			if _, err := readMetaHeaders.Write(frame.HeaderBlockFragment()); err != nil {
    67  				return false
    68  			}
    69  			done = frame.HeadersEnded()
    70  		}
    71  
    72  		if done || (!readAll && len(filteredHeaderFields) == len(filterNames)) {
    73  			return matches(filteredHeaderFields)
    74  		}
    75  	}
    76  }
    77  func handleSettings(framer *http2.Framer, frame *http2.SettingsFrame) error {
    78  	// Sender acknowledged the SETTINGS frame. No need to write
    79  	// SETTINGS again.
    80  	if frame.IsAck() {
    81  		return nil
    82  	}
    83  	return framer.WriteSettings()
    84  }