github.com/panjjo/go@v0.0.0-20161104043856-d62b31386338/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  	ExportScanETag               = scanETag
    28  	ExportHttp2ConfigureServer   = http2ConfigureServer
    29  )
    30  
    31  func init() {
    32  	// We only want to pay for this cost during testing.
    33  	// When not under test, these values are always nil
    34  	// and never assigned to.
    35  	testHookMu = new(sync.Mutex)
    36  }
    37  
    38  var (
    39  	SetEnterRoundTripHook = hookSetter(&testHookEnterRoundTrip)
    40  	SetRoundTripRetried   = hookSetter(&testHookRoundTripRetried)
    41  )
    42  
    43  func SetReadLoopBeforeNextReadHook(f func()) {
    44  	testHookMu.Lock()
    45  	defer testHookMu.Unlock()
    46  	unnilTestHook(&f)
    47  	testHookReadLoopBeforeNextRead = f
    48  }
    49  
    50  // SetPendingDialHooks sets the hooks that run before and after handling
    51  // pending dials.
    52  func SetPendingDialHooks(before, after func()) {
    53  	unnilTestHook(&before)
    54  	unnilTestHook(&after)
    55  	testHookPrePendingDial, testHookPostPendingDial = before, after
    56  }
    57  
    58  func SetTestHookServerServe(fn func(*Server, net.Listener)) { testHookServerServe = fn }
    59  
    60  func NewTestTimeoutHandler(handler Handler, ch <-chan time.Time) Handler {
    61  	return &timeoutHandler{
    62  		handler:     handler,
    63  		testTimeout: ch,
    64  		// (no body)
    65  	}
    66  }
    67  
    68  func ResetCachedEnvironment() {
    69  	httpProxyEnv.reset()
    70  	httpsProxyEnv.reset()
    71  	noProxyEnv.reset()
    72  }
    73  
    74  func (t *Transport) NumPendingRequestsForTesting() int {
    75  	t.reqMu.Lock()
    76  	defer t.reqMu.Unlock()
    77  	return len(t.reqCanceler)
    78  }
    79  
    80  func (t *Transport) IdleConnKeysForTesting() (keys []string) {
    81  	keys = make([]string, 0)
    82  	t.idleMu.Lock()
    83  	defer t.idleMu.Unlock()
    84  	for key := range t.idleConn {
    85  		keys = append(keys, key.String())
    86  	}
    87  	sort.Strings(keys)
    88  	return
    89  }
    90  
    91  func (t *Transport) IdleConnKeyCountForTesting() int {
    92  	t.idleMu.Lock()
    93  	defer t.idleMu.Unlock()
    94  	return len(t.idleConn)
    95  }
    96  
    97  func (t *Transport) IdleConnStrsForTesting() []string {
    98  	var ret []string
    99  	t.idleMu.Lock()
   100  	defer t.idleMu.Unlock()
   101  	for _, conns := range t.idleConn {
   102  		for _, pc := range conns {
   103  			ret = append(ret, pc.conn.LocalAddr().String()+"/"+pc.conn.RemoteAddr().String())
   104  		}
   105  	}
   106  	sort.Strings(ret)
   107  	return ret
   108  }
   109  
   110  func (t *Transport) IdleConnStrsForTesting_h2() []string {
   111  	var ret []string
   112  	noDialPool := t.h2transport.ConnPool.(http2noDialClientConnPool)
   113  	pool := noDialPool.http2clientConnPool
   114  
   115  	pool.mu.Lock()
   116  	defer pool.mu.Unlock()
   117  
   118  	for k, cc := range pool.conns {
   119  		for range cc {
   120  			ret = append(ret, k)
   121  		}
   122  	}
   123  
   124  	sort.Strings(ret)
   125  	return ret
   126  }
   127  
   128  func (t *Transport) IdleConnCountForTesting(cacheKey string) int {
   129  	t.idleMu.Lock()
   130  	defer t.idleMu.Unlock()
   131  	for k, conns := range t.idleConn {
   132  		if k.String() == cacheKey {
   133  			return len(conns)
   134  		}
   135  	}
   136  	return 0
   137  }
   138  
   139  func (t *Transport) IdleConnChMapSizeForTesting() int {
   140  	t.idleMu.Lock()
   141  	defer t.idleMu.Unlock()
   142  	return len(t.idleConnCh)
   143  }
   144  
   145  func (t *Transport) IsIdleForTesting() bool {
   146  	t.idleMu.Lock()
   147  	defer t.idleMu.Unlock()
   148  	return t.wantIdle
   149  }
   150  
   151  func (t *Transport) RequestIdleConnChForTesting() {
   152  	t.getIdleConnCh(connectMethod{nil, "http", "example.com"})
   153  }
   154  
   155  func (t *Transport) PutIdleTestConn() bool {
   156  	c, _ := net.Pipe()
   157  	return t.tryPutIdleConn(&persistConn{
   158  		t:        t,
   159  		conn:     c,                   // dummy
   160  		closech:  make(chan struct{}), // so it can be closed
   161  		cacheKey: connectMethodKey{"", "http", "example.com"},
   162  	}) == nil
   163  }
   164  
   165  // All test hooks must be non-nil so they can be called directly,
   166  // but the tests use nil to mean hook disabled.
   167  func unnilTestHook(f *func()) {
   168  	if *f == nil {
   169  		*f = nop
   170  	}
   171  }
   172  
   173  func hookSetter(dst *func()) func(func()) {
   174  	return func(fn func()) {
   175  		unnilTestHook(&fn)
   176  		*dst = fn
   177  	}
   178  }
   179  
   180  func ExportHttp2ConfigureTransport(t *Transport) error {
   181  	t2, err := http2configureTransport(t)
   182  	if err != nil {
   183  		return err
   184  	}
   185  	t.h2transport = t2
   186  	return nil
   187  }
   188  
   189  var Export_shouldCopyHeaderOnRedirect = shouldCopyHeaderOnRedirect
   190  
   191  func (s *Server) ExportAllConnsIdle() bool {
   192  	s.mu.Lock()
   193  	defer s.mu.Unlock()
   194  	for c := range s.activeConn {
   195  		st, ok := c.curState.Load().(ConnState)
   196  		if !ok || st != StateIdle {
   197  			return false
   198  		}
   199  	}
   200  	return true
   201  }