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.
5 // Bridge package to expose http internals to tests in the http_test
22 DefaultUserAgent
= defaultUserAgent
23 NewLoggingConn
= newLoggingConn
24 ExportAppendTime
= appendTime
25 ExportRefererForURL
= refererForURL
26 ExportServerNewConn
= (*Server
).newConn
27 ExportCloseWriteAndWait
= (*conn
).closeWriteAndWait
28 ExportErrRequestCanceled
= errRequestCanceled
29 ExportErrRequestCanceledConn
= errRequestCanceledConn
30 ExportErrServerClosedIdle
= errServerClosedIdle
31 ExportServeFile
= serveFile
32 ExportScanETag
= scanETag
33 ExportHttp2ConfigureServer
= http2ConfigureServer
34 Export_shouldCopyHeaderOnRedirect
= shouldCopyHeaderOnRedirect
35 Export_writeStatusLine
= writeStatusLine
38 const MaxWriteWaitBeforeConnReuse
= maxWriteWaitBeforeConnReuse
41 // We only want to pay for this cost during testing.
42 // When not under test, these values are always nil
43 // and never assigned to.
44 testHookMu
= new(sync
.Mutex
)
46 testHookClientDoResult
= func(res
*Response
, err error
) {
48 if _
, ok
:= err
.(*url
.Error
); !ok
{
49 panic(fmt
.Sprintf("unexpected Client.Do error of type %T; want *url.Error", err
))
53 panic("Client.Do returned nil, nil")
56 panic("Client.Do returned nil res.Body and no error")
63 SetEnterRoundTripHook
= hookSetter(&testHookEnterRoundTrip
)
64 SetRoundTripRetried
= hookSetter(&testHookRoundTripRetried
)
67 func SetReadLoopBeforeNextReadHook(f
func()) {
69 defer testHookMu
.Unlock()
71 testHookReadLoopBeforeNextRead
= f
74 // SetPendingDialHooks sets the hooks that run before and after handling
76 func SetPendingDialHooks(before
, after
func()) {
77 unnilTestHook(&before
)
79 testHookPrePendingDial
, testHookPostPendingDial
= before
, after
82 func SetTestHookServerServe(fn
func(*Server
, net
.Listener
)) { testHookServerServe
= fn
}
84 func NewTestTimeoutHandler(handler Handler
, ch
<-chan time
.Time
) Handler
{
85 ctx
, cancel
:= context
.WithCancel(context
.Background())
90 return &timeoutHandler
{
97 func ResetCachedEnvironment() {
101 func (t
*Transport
) NumPendingRequestsForTesting() int {
103 defer t
.reqMu
.Unlock()
104 return len(t
.reqCanceler
)
107 func (t
*Transport
) IdleConnKeysForTesting() (keys
[]string) {
108 keys
= make([]string, 0)
110 defer t
.idleMu
.Unlock()
111 for key
:= range t
.idleConn
{
112 keys
= append(keys
, key
.String())
118 func (t
*Transport
) IdleConnKeyCountForTesting() int {
120 defer t
.idleMu
.Unlock()
121 return len(t
.idleConn
)
124 func (t
*Transport
) IdleConnStrsForTesting() []string {
127 defer t
.idleMu
.Unlock()
128 for _
, conns
:= range t
.idleConn
{
129 for _
, pc
:= range conns
{
130 ret
= append(ret
, pc
.conn
.LocalAddr().String()+"/"+pc
.conn
.RemoteAddr().String())
137 func (t
*Transport
) IdleConnStrsForTesting_h2() []string {
139 noDialPool
:= t
.h2transport
.(*http2Transport
).ConnPool
.(http2noDialClientConnPool
)
140 pool
:= noDialPool
.http2clientConnPool
143 defer pool
.mu
.Unlock()
145 for k
, cc
:= range pool
.conns
{
155 func (t
*Transport
) IdleConnCountForTesting(scheme
, addr
string) int {
157 defer t
.idleMu
.Unlock()
158 key
:= connectMethodKey
{"", scheme
, addr
}
159 cacheKey
:= key
.String()
160 for k
, conns
:= range t
.idleConn
{
161 if k
.String() == cacheKey
{
168 func (t
*Transport
) IdleConnChMapSizeForTesting() int {
170 defer t
.idleMu
.Unlock()
171 return len(t
.idleConnCh
)
174 func (t
*Transport
) IsIdleForTesting() bool {
176 defer t
.idleMu
.Unlock()
180 func (t
*Transport
) RequestIdleConnChForTesting() {
181 t
.getIdleConnCh(connectMethod
{nil, "http", "example.com"})
184 func (t
*Transport
) PutIdleTestConn(scheme
, addr
string) bool {
186 key
:= connectMethodKey
{"", scheme
, addr
}
188 case <-t
.incHostConnCount(key
):
192 return t
.tryPutIdleConn(&persistConn
{
195 closech
: make(chan struct{}), // so it can be closed
200 // All test hooks must be non-nil so they can be called directly,
201 // but the tests use nil to mean hook disabled.
202 func unnilTestHook(f
*func()) {
208 func hookSetter(dst
*func()) func(func()) {
209 return func(fn
func()) {
215 func ExportHttp2ConfigureTransport(t
*Transport
) error
{
216 t2
, err
:= http2configureTransport(t
)
224 func (s
*Server
) ExportAllConnsIdle() bool {
227 for c
:= range s
.activeConn
{
228 st
, unixSec
:= c
.getState()
229 if unixSec
== 0 || st
!= StateIdle
{
236 func (r
*Request
) WithT(t
*testing
.T
) *Request
{
237 return r
.WithContext(context
.WithValue(r
.Context(), tLogKey
{}, t
.Logf
))
240 func ExportSetH2GoawayTimeout(d time
.Duration
) (restore
func()) {
241 old
:= http2goAwayTimeout
242 http2goAwayTimeout
= d
243 return func() { http2goAwayTimeout
= old
}