github.com/gocuntian/go@v0.0.0-20160610041250-fee02d270bf8/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 }