Source file src/net/http/internal/http2/export_test.go

     1  // Copyright 2026 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  	"context"
     9  	"fmt"
    10  	"net"
    11  	"net/textproto"
    12  	"sync"
    13  	"testing"
    14  	"time"
    15  
    16  	"net/http/internal/httpcommon"
    17  
    18  	"golang.org/x/net/http2/hpack"
    19  )
    20  
    21  func init() {
    22  	inTests = true
    23  }
    24  
    25  const (
    26  	DefaultMaxReadFrameSize     = defaultMaxReadFrameSize
    27  	DefaultMaxStreams           = defaultMaxStreams
    28  	InflowMinRefresh            = inflowMinRefresh
    29  	InitialHeaderTableSize      = initialHeaderTableSize
    30  	InitialMaxConcurrentStreams = initialMaxConcurrentStreams
    31  	InitialWindowSize           = initialWindowSize
    32  	MaxFrameSize                = maxFrameSize
    33  	MaxQueuedControlFrames      = maxQueuedControlFrames
    34  	MinMaxFrameSize             = minMaxFrameSize
    35  )
    36  
    37  type (
    38  	ServerConn  = serverConn
    39  	Stream      = stream
    40  	StreamState = streamState
    41  
    42  	PseudoHeaderError     = pseudoHeaderError
    43  	HeaderFieldNameError  = headerFieldNameError
    44  	HeaderFieldValueError = headerFieldValueError
    45  )
    46  
    47  const (
    48  	StateIdle             = stateIdle
    49  	StateOpen             = stateOpen
    50  	StateHalfClosedLocal  = stateHalfClosedLocal
    51  	StateHalfClosedRemote = stateHalfClosedRemote
    52  	StateClosed           = stateClosed
    53  )
    54  
    55  var (
    56  	ErrClientConnForceClosed       = errClientConnForceClosed
    57  	ErrClientConnNotEstablished    = errClientConnNotEstablished
    58  	ErrClientConnUnusable          = errClientConnUnusable
    59  	ErrExtendedConnectNotSupported = errExtendedConnectNotSupported
    60  	ErrReqBodyTooLong              = errReqBodyTooLong
    61  	ErrRequestHeaderListSize       = errRequestHeaderListSize
    62  	ErrResponseHeaderListSize      = errResponseHeaderListSize
    63  )
    64  
    65  func (s *Server) TestServeConn(c net.Conn, opts *ServeConnOpts, newf func(*serverConn)) {
    66  	s.serveConn(c, opts, newf)
    67  }
    68  
    69  func (sc *serverConn) TestFlowControlConsumed() (consumed int32) {
    70  	conf := configFromServer(sc.hs, sc.srv)
    71  	donec := make(chan struct{})
    72  	sc.sendServeMsg(func(sc *serverConn) {
    73  		defer close(donec)
    74  		initial := int32(conf.MaxReceiveBufferPerConnection)
    75  		avail := sc.inflow.avail + sc.inflow.unsent
    76  		consumed = initial - avail
    77  	})
    78  	<-donec
    79  	return consumed
    80  }
    81  
    82  func (sc *serverConn) TestStreamExists(id uint32) bool {
    83  	ch := make(chan bool, 1)
    84  	sc.serveMsgCh <- func(int) {
    85  		ch <- (sc.streams[id] != nil)
    86  	}
    87  	return <-ch
    88  }
    89  
    90  func (sc *serverConn) TestStreamState(id uint32) streamState {
    91  	ch := make(chan streamState, 1)
    92  	sc.serveMsgCh <- func(int) {
    93  		state, _ := sc.state(id)
    94  		ch <- state
    95  	}
    96  	return <-ch
    97  }
    98  
    99  func (sc *serverConn) StartGracefulShutdown() { sc.startGracefulShutdown() }
   100  
   101  func (sc *serverConn) TestHPACKEncoder() *hpack.Encoder {
   102  	return sc.hpackEncoder
   103  }
   104  
   105  func (sc *serverConn) TestFramerMaxHeaderStringLen() int {
   106  	return sc.framer.maxHeaderStringLen()
   107  }
   108  
   109  func (t *Transport) DialClientConn(ctx context.Context, addr string, singleUse bool) (*ClientConn, error) {
   110  	return t.dialClientConn(ctx, addr, singleUse)
   111  }
   112  
   113  func (t *Transport) TestNewClientConn(c net.Conn, singleUse bool, internalStateHook func()) (*ClientConn, error) {
   114  	return t.newClientConn(c, singleUse, internalStateHook)
   115  }
   116  
   117  func (t *Transport) TestSetNewClientConnHook(f func(*ClientConn)) {
   118  	t.transportTestHooks = &transportTestHooks{
   119  		newclientconn: f,
   120  	}
   121  }
   122  
   123  func (cc *ClientConn) TestNetConn() net.Conn     { return cc.tconn }
   124  func (cc *ClientConn) TestSetNetConn(c net.Conn) { cc.tconn = c }
   125  
   126  func (cc *ClientConn) TestRoundTrip(req *ClientRequest, f func(stremaID uint32)) (*ClientResponse, error) {
   127  	return cc.roundTrip(req, func(cs *clientStream) {
   128  		f(cs.ID)
   129  	})
   130  }
   131  
   132  func (cc *ClientConn) TestHPACKEncoder() *hpack.Encoder {
   133  	return cc.henc
   134  }
   135  
   136  func (cc *ClientConn) TestPeerMaxHeaderTableSize() uint32 {
   137  	cc.mu.Lock()
   138  	defer cc.mu.Unlock()
   139  	return cc.peerMaxHeaderTableSize
   140  }
   141  
   142  func (cc *ClientConn) TestInflowWindow(streamID uint32) (int32, error) {
   143  	cc.mu.Lock()
   144  	defer cc.mu.Unlock()
   145  	if streamID == 0 {
   146  		return cc.inflow.avail + cc.inflow.unsent, nil
   147  	}
   148  	cs := cc.streams[streamID]
   149  	if cs == nil {
   150  		return -1, fmt.Errorf("no stream with id %v", streamID)
   151  	}
   152  	return cs.inflow.avail + cs.inflow.unsent, nil
   153  }
   154  
   155  func (fr *Framer) TestSetDebugReadLoggerf(f func(string, ...any)) {
   156  	fr.logReads = true
   157  	fr.debugReadLoggerf = f
   158  }
   159  
   160  func (fr *Framer) TestSetDebugWriteLoggerf(f func(string, ...any)) {
   161  	fr.logWrites = true
   162  	fr.debugWriteLoggerf = f
   163  }
   164  
   165  func SummarizeFrame(f Frame) string {
   166  	return summarizeFrame(f)
   167  }
   168  
   169  func init() {
   170  	testHookOnPanicMu = new(sync.Mutex)
   171  }
   172  
   173  func SetTestHookOnPanic(t testing.TB, f func(sc *serverConn, panicVal interface{}) (rePanic bool)) {
   174  	testHookOnPanicMu.Lock()
   175  	defer testHookOnPanicMu.Unlock()
   176  	old := testHookOnPanic
   177  	testHookOnPanic = f
   178  	t.Cleanup(func() {
   179  		testHookOnPanicMu.Lock()
   180  		defer testHookOnPanicMu.Unlock()
   181  		testHookOnPanic = old
   182  	})
   183  }
   184  
   185  func SetTestHookGot1xx(t testing.TB, f func(int, textproto.MIMEHeader) error) {
   186  	SetForTest(t, &got1xxFuncForTests, f)
   187  }
   188  
   189  func SetDisableExtendedConnectProtocol(t testing.TB, v bool) {
   190  	SetForTest(t, &disableExtendedConnectProtocol, v)
   191  }
   192  
   193  func LogFrameReads() bool  { return logFrameReads }
   194  func LogFrameWrites() bool { return logFrameWrites }
   195  
   196  const GoAwayTimeout = 25 * time.Millisecond
   197  
   198  func init() {
   199  	goAwayTimeout = GoAwayTimeout
   200  }
   201  
   202  func EncodeHeaderRaw(t testing.TB, headers ...string) []byte {
   203  	return encodeHeaderRaw(t, headers...)
   204  }
   205  
   206  func NewPriorityWriteSchedulerRFC7540(cfg *PriorityWriteSchedulerConfig) WriteScheduler {
   207  	return newPriorityWriteSchedulerRFC7540(cfg)
   208  }
   209  
   210  func NewPriorityWriteSchedulerRFC9218() WriteScheduler {
   211  	return newPriorityWriteSchedulerRFC9218()
   212  }
   213  
   214  func NewRoundRobinWriteScheduler() WriteScheduler {
   215  	return newRoundRobinWriteScheduler()
   216  }
   217  
   218  func DisableGoroutineTracking(t testing.TB) {
   219  	disableDebugGoroutines.Store(true)
   220  	t.Cleanup(func() {
   221  		disableDebugGoroutines.Store(false)
   222  	})
   223  }
   224  
   225  func InvalidHTTP1LookingFrameHeader() FrameHeader {
   226  	return invalidHTTP1LookingFrameHeader()
   227  }
   228  
   229  func NewNoDialClientConnPool() ClientConnPool {
   230  	return noDialClientConnPool{new(clientConnPool)}
   231  }
   232  
   233  func EncodeRequestHeaders(req *ClientRequest, addGzipHeader bool, peerMaxHeaderListSize uint64, headerf func(name, value string)) (httpcommon.EncodeHeadersResult, error) {
   234  	return encodeRequestHeaders(req, addGzipHeader, peerMaxHeaderListSize, headerf)
   235  }
   236  

View as plain text