github.com/dannin/go@v0.0.0-20161031215817-d35dfd405eaa/src/net/http/export_test.go (about)

     1  // Copyright 2011 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  // Bridge package to expose http internals to tests in the http_test
     6  // package.
     7  
     8  package http
     9  
    10  import (
    11  	"net"
    12  	"sort"
    13  	"sync"
    14  	"time"
    15  )
    16  
    17  var (
    18  	DefaultUserAgent             = defaultUserAgent
    19  	NewLoggingConn               = newLoggingConn
    20  	ExportAppendTime             = appendTime
    21  	ExportRefererForURL          = refererForURL
    22  	ExportServerNewConn          = (*Server).newConn
    23  	ExportCloseWriteAndWait      = (*conn).closeWriteAndWait
    24  	ExportErrRequestCanceled     = errRequestCanceled
    25  	ExportErrRequestCanceledConn = errRequestCanceledConn
    26  	ExportServeFile              = serveFile
    27  	ExportHttp2ConfigureServer   = http2ConfigureServer
    28  )
    29  
    30  func init() {
    31  	// We only want to pay for this cost during testing.
    32  	// When not under test, these values are always nil
    33  	// and never assigned to.
    34  	testHookMu = new(sync.Mutex)
    35  }
    36  
    37  var (
    38  	SetEnterRoundTripHook = hookSetter(&testHookEnterRoundTrip)
    39  	SetRoundTripRetried   = hookSetter(&testHookRoundTripRetried)
    40  )
    41  
    42  func SetReadLoopBeforeNextReadHook(f func()) {
    43  	testHookMu.Lock()
    44  	defer testHookMu.Unlock()
    45  	unnilTestHook(&f)
    46  	testHookReadLoopBeforeNextRead = f
    47  }
    48  
    49  // SetPendingDialHooks sets the hooks that run before and after handling
    50  // pending dials.
    51  func SetPendingDialHooks(before, after func()) {
    52  	unnilTestHook(&before)
    53  	unnilTestHook(&after)
    54  	testHookPrePendingDial, testHookPostPendingDial = before, after
    55  }
    56  
    57  func SetTestHookServerServe(fn func(*Server, net.Listener)) { testHookServerServe = fn }
    58  
    59  func NewTestTimeoutHandler(handler Handler, ch <-chan time.Time) Handler {
    60  	return &timeoutHandler{
    61  		handler:     handler,
    62  		testTimeout: ch,
    63  		// (no body)
    64  	}
    65  }
    66  
    67  func ResetCachedEnvironment() {
    68  	httpProxyEnv.reset()
    69  	httpsProxyEnv.reset()
    70  	noProxyEnv.reset()
    71  }
    72  
    73  func (t *Transport) NumPendingRequestsForTesting() int {
    74  	t.reqMu.Lock()
    75  	defer t.reqMu.Unlock()
    76  	return len(t.reqCanceler)
    77  }
    78  
    79  func (t *Transport) IdleConnKeysForTesting() (keys []string) {
    80  	keys = make([]string, 0)
    81  	t.idleMu.Lock()
    82  	defer t.idleMu.Unlock()
    83  	for key := range t.idleConn {
    84  		keys = append(keys, key.String())
    85  	}
    86  	sort.Strings(keys)
    87  	return
    88  }
    89  
    90  func (t *Transport) IdleConnStrsForTesting() []string {
    91  	var ret []string
    92  	t.idleMu.Lock()
    93  	defer t.idleMu.Unlock()
    94  	for _, conns := range t.idleConn {
    95  		for _, pc := range conns {
    96  			ret = append(ret, pc.conn.LocalAddr().String()+"/"+pc.conn.RemoteAddr().String())
    97  		}
    98  	}
    99  	sort.Strings(ret)
   100  	return ret
   101  }
   102  
   103  func (t *Transport) IdleConnStrsForTesting_h2() []string {
   104  	var ret []string
   105  	noDialPool := t.h2transport.ConnPool.(http2noDialClientConnPool)
   106  	pool := noDialPool.http2clientConnPool
   107  
   108  	pool.mu.Lock()
   109  	defer pool.mu.Unlock()
   110  
   111  	for k, cc := range pool.conns {
   112  		for range cc {
   113  			ret = append(ret, k)
   114  		}
   115  	}
   116  
   117  	sort.Strings(ret)
   118  	return ret
   119  }
   120  
   121  func (t *Transport) IdleConnCountForTesting(cacheKey string) int {
   122  	t.idleMu.Lock()
   123  	defer t.idleMu.Unlock()
   124  	for k, conns := range t.idleConn {
   125  		if k.String() == cacheKey {
   126  			return len(conns)
   127  		}
   128  	}
   129  	return 0
   130  }
   131  
   132  func (t *Transport) IdleConnChMapSizeForTesting() int {
   133  	t.idleMu.Lock()
   134  	defer t.idleMu.Unlock()
   135  	return len(t.idleConnCh)
   136  }
   137  
   138  func (t *Transport) IsIdleForTesting() bool {
   139  	t.idleMu.Lock()
   140  	defer t.idleMu.Unlock()
   141  	return t.wantIdle
   142  }
   143  
   144  func (t *Transport) RequestIdleConnChForTesting() {
   145  	t.getIdleConnCh(connectMethod{nil, "http", "example.com"})
   146  }
   147  
   148  func (t *Transport) PutIdleTestConn() bool {
   149  	c, _ := net.Pipe()
   150  	return t.tryPutIdleConn(&persistConn{
   151  		t:        t,
   152  		conn:     c,                   // dummy
   153  		closech:  make(chan struct{}), // so it can be closed
   154  		cacheKey: connectMethodKey{"", "http", "example.com"},
   155  	}) == nil
   156  }
   157  
   158  // All test hooks must be non-nil so they can be called directly,
   159  // but the tests use nil to mean hook disabled.
   160  func unnilTestHook(f *func()) {
   161  	if *f == nil {
   162  		*f = nop
   163  	}
   164  }
   165  
   166  func hookSetter(dst *func()) func(func()) {
   167  	return func(fn func()) {
   168  		unnilTestHook(&fn)
   169  		*dst = fn
   170  	}
   171  }
   172  
   173  func ExportHttp2ConfigureTransport(t *Transport) error {
   174  	t2, err := http2configureTransport(t)
   175  	if err != nil {
   176  		return err
   177  	}
   178  	t.h2transport = t2
   179  	return nil
   180  }
   181  
   182  var Export_shouldCopyHeaderOnRedirect = shouldCopyHeaderOnRedirect