github.com/FenixAra/go@v0.0.0-20170127160404-96ea0918e670/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 }