1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Bridge package to expose http internals to tests in the http_test
// package.
package http
import (
"net"
"sync"
"time"
)
var (
DefaultUserAgent = defaultUserAgent
NewLoggingConn = newLoggingConn
ExportAppendTime = appendTime
ExportRefererForURL = refererForURL
ExportServerNewConn = (*Server).newConn
ExportCloseWriteAndWait = (*conn).closeWriteAndWait
ExportErrRequestCanceled = errRequestCanceled
ExportErrRequestCanceledConn = errRequestCanceledConn
ExportServeFile = serveFile
ExportHttp2ConfigureTransport = http2ConfigureTransport
ExportHttp2ConfigureServer = http2ConfigureServer
)
func init() {
// We only want to pay for this cost during testing.
// When not under test, these values are always nil
// and never assigned to.
testHookMu = new(sync.Mutex)
}
var (
SetEnterRoundTripHook = hookSetter(&testHookEnterRoundTrip)
SetTestHookWaitResLoop = hookSetter(&testHookWaitResLoop)
SetRoundTripRetried = hookSetter(&testHookRoundTripRetried)
)
func SetReadLoopBeforeNextReadHook(f func()) {
testHookMu.Lock()
defer testHookMu.Unlock()
unnilTestHook(&f)
testHookReadLoopBeforeNextRead = f
}
// SetPendingDialHooks sets the hooks that run before and after handling
// pending dials.
func SetPendingDialHooks(before, after func()) {
unnilTestHook(&before)
unnilTestHook(&after)
testHookPrePendingDial, testHookPostPendingDial = before, after
}
func SetTestHookServerServe(fn func(*Server, net.Listener)) { testHookServerServe = fn }
func NewTestTimeoutHandler(handler Handler, ch <-chan time.Time) Handler {
return &timeoutHandler{
handler: handler,
testTimeout: ch,
// (no body)
}
}
func ResetCachedEnvironment() {
httpProxyEnv.reset()
httpsProxyEnv.reset()
noProxyEnv.reset()
}
func (t *Transport) NumPendingRequestsForTesting() int {
t.reqMu.Lock()
defer t.reqMu.Unlock()
return len(t.reqCanceler)
}
func (t *Transport) IdleConnKeysForTesting() (keys []string) {
keys = make([]string, 0)
t.idleMu.Lock()
defer t.idleMu.Unlock()
if t.idleConn == nil {
return
}
for key := range t.idleConn {
keys = append(keys, key.String())
}
return
}
func (t *Transport) IdleConnCountForTesting(cacheKey string) int {
t.idleMu.Lock()
defer t.idleMu.Unlock()
if t.idleConn == nil {
return 0
}
for k, conns := range t.idleConn {
if k.String() == cacheKey {
return len(conns)
}
}
return 0
}
func (t *Transport) IdleConnChMapSizeForTesting() int {
t.idleMu.Lock()
defer t.idleMu.Unlock()
return len(t.idleConnCh)
}
func (t *Transport) IsIdleForTesting() bool {
t.idleMu.Lock()
defer t.idleMu.Unlock()
return t.wantIdle
}
func (t *Transport) RequestIdleConnChForTesting() {
t.getIdleConnCh(connectMethod{nil, "http", "example.com"})
}
func (t *Transport) PutIdleTestConn() bool {
c, _ := net.Pipe()
return t.tryPutIdleConn(&persistConn{
t: t,
conn: c, // dummy
closech: make(chan struct{}), // so it can be closed
cacheKey: connectMethodKey{"", "http", "example.com"},
}) == nil
}
// All test hooks must be non-nil so they can be called directly,
// but the tests use nil to mean hook disabled.
func unnilTestHook(f *func()) {
if *f == nil {
*f = nop
}
}
func hookSetter(dst *func()) func(func()) {
return func(fn func()) {
unnilTestHook(&fn)
*dst = fn
}
}
|