github.com/sbinet/go@v0.0.0-20160827155028-54d7de7dd62b/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) IdleConnCountForTesting(cacheKey string) int {
   104  	t.idleMu.Lock()
   105  	defer t.idleMu.Unlock()
   106  	for k, conns := range t.idleConn {
   107  		if k.String() == cacheKey {
   108  			return len(conns)
   109  		}
   110  	}
   111  	return 0
   112  }
   113  
   114  func (t *Transport) IdleConnChMapSizeForTesting() int {
   115  	t.idleMu.Lock()
   116  	defer t.idleMu.Unlock()
   117  	return len(t.idleConnCh)
   118  }
   119  
   120  func (t *Transport) IsIdleForTesting() bool {
   121  	t.idleMu.Lock()
   122  	defer t.idleMu.Unlock()
   123  	return t.wantIdle
   124  }
   125  
   126  func (t *Transport) RequestIdleConnChForTesting() {
   127  	t.getIdleConnCh(connectMethod{nil, "http", "example.com"})
   128  }
   129  
   130  func (t *Transport) PutIdleTestConn() bool {
   131  	c, _ := net.Pipe()
   132  	return t.tryPutIdleConn(&persistConn{
   133  		t:        t,
   134  		conn:     c,                   // dummy
   135  		closech:  make(chan struct{}), // so it can be closed
   136  		cacheKey: connectMethodKey{"", "http", "example.com"},
   137  	}) == nil
   138  }
   139  
   140  // All test hooks must be non-nil so they can be called directly,
   141  // but the tests use nil to mean hook disabled.
   142  func unnilTestHook(f *func()) {
   143  	if *f == nil {
   144  		*f = nop
   145  	}
   146  }
   147  
   148  func hookSetter(dst *func()) func(func()) {
   149  	return func(fn func()) {
   150  		unnilTestHook(&fn)
   151  		*dst = fn
   152  	}
   153  }
   154  
   155  func ExportHttp2ConfigureTransport(t *Transport) error {
   156  	t2, err := http2configureTransport(t)
   157  	if err != nil {
   158  		return err
   159  	}
   160  	t.h2transport = t2
   161  	return nil
   162  }