Source file
src/net/http/transport.go
1
2
3
4
5
6
7
8
9
10 package http
11
12 import (
13 "bufio"
14 "compress/gzip"
15 "container/list"
16 "context"
17 "crypto/tls"
18 "errors"
19 "fmt"
20 "internal/godebug"
21 "io"
22 "log"
23 "net"
24 "net/http/httptrace"
25 "net/http/internal/ascii"
26 "net/textproto"
27 "net/url"
28 "reflect"
29 "strings"
30 "sync"
31 "sync/atomic"
32 "time"
33
34 "golang.org/x/net/http/httpguts"
35 "golang.org/x/net/http/httpproxy"
36 )
37
38
39
40
41
42
43 var DefaultTransport RoundTripper = &Transport{
44 Proxy: ProxyFromEnvironment,
45 DialContext: defaultTransportDialContext(&net.Dialer{
46 Timeout: 30 * time.Second,
47 KeepAlive: 30 * time.Second,
48 }),
49 ForceAttemptHTTP2: true,
50 MaxIdleConns: 100,
51 IdleConnTimeout: 90 * time.Second,
52 TLSHandshakeTimeout: 10 * time.Second,
53 ExpectContinueTimeout: 1 * time.Second,
54 }
55
56
57
58 const DefaultMaxIdleConnsPerHost = 2
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 type Transport struct {
96 idleMu sync.Mutex
97 closeIdle bool
98 idleConn map[connectMethodKey][]*persistConn
99 idleConnWait map[connectMethodKey]wantConnQueue
100 idleLRU connLRU
101
102 reqMu sync.Mutex
103 reqCanceler map[cancelKey]func(error)
104
105 altMu sync.Mutex
106 altProto atomic.Value
107
108 connsPerHostMu sync.Mutex
109 connsPerHost map[connectMethodKey]int
110 connsPerHostWait map[connectMethodKey]wantConnQueue
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126 Proxy func(*Request) (*url.URL, error)
127
128
129
130
131 OnProxyConnectResponse func(ctx context.Context, proxyURL *url.URL, connectReq *Request, connectRes *Response) error
132
133
134
135
136
137
138
139
140
141 DialContext func(ctx context.Context, network, addr string) (net.Conn, error)
142
143
144
145
146
147
148
149
150
151
152
153 Dial func(network, addr string) (net.Conn, error)
154
155
156
157
158
159
160
161
162
163
164
165 DialTLSContext func(ctx context.Context, network, addr string) (net.Conn, error)
166
167
168
169
170
171
172
173 DialTLS func(network, addr string) (net.Conn, error)
174
175
176
177
178
179 TLSClientConfig *tls.Config
180
181
182
183 TLSHandshakeTimeout time.Duration
184
185
186
187
188
189
190 DisableKeepAlives bool
191
192
193
194
195
196
197
198
199
200 DisableCompression bool
201
202
203
204 MaxIdleConns int
205
206
207
208
209 MaxIdleConnsPerHost int
210
211
212
213
214
215
216 MaxConnsPerHost int
217
218
219
220
221
222 IdleConnTimeout time.Duration
223
224
225
226
227
228 ResponseHeaderTimeout time.Duration
229
230
231
232
233
234
235
236
237 ExpectContinueTimeout time.Duration
238
239
240
241
242
243
244
245
246
247
248
249 TLSNextProto map[string]func(authority string, c *tls.Conn) RoundTripper
250
251
252
253
254 ProxyConnectHeader Header
255
256
257
258
259
260
261
262
263 GetProxyConnectHeader func(ctx context.Context, proxyURL *url.URL, target string) (Header, error)
264
265
266
267
268
269
270 MaxResponseHeaderBytes int64
271
272
273
274
275 WriteBufferSize int
276
277
278
279
280 ReadBufferSize int
281
282
283
284 nextProtoOnce sync.Once
285 h2transport h2Transport
286 tlsNextProtoWasNil bool
287
288
289
290
291
292
293 ForceAttemptHTTP2 bool
294 }
295
296
297
298
299 type cancelKey struct {
300 req *Request
301 }
302
303 func (t *Transport) writeBufferSize() int {
304 if t.WriteBufferSize > 0 {
305 return t.WriteBufferSize
306 }
307 return 4 << 10
308 }
309
310 func (t *Transport) readBufferSize() int {
311 if t.ReadBufferSize > 0 {
312 return t.ReadBufferSize
313 }
314 return 4 << 10
315 }
316
317
318 func (t *Transport) Clone() *Transport {
319 t.nextProtoOnce.Do(t.onceSetNextProtoDefaults)
320 t2 := &Transport{
321 Proxy: t.Proxy,
322 OnProxyConnectResponse: t.OnProxyConnectResponse,
323 DialContext: t.DialContext,
324 Dial: t.Dial,
325 DialTLS: t.DialTLS,
326 DialTLSContext: t.DialTLSContext,
327 TLSHandshakeTimeout: t.TLSHandshakeTimeout,
328 DisableKeepAlives: t.DisableKeepAlives,
329 DisableCompression: t.DisableCompression,
330 MaxIdleConns: t.MaxIdleConns,
331 MaxIdleConnsPerHost: t.MaxIdleConnsPerHost,
332 MaxConnsPerHost: t.MaxConnsPerHost,
333 IdleConnTimeout: t.IdleConnTimeout,
334 ResponseHeaderTimeout: t.ResponseHeaderTimeout,
335 ExpectContinueTimeout: t.ExpectContinueTimeout,
336 ProxyConnectHeader: t.ProxyConnectHeader.Clone(),
337 GetProxyConnectHeader: t.GetProxyConnectHeader,
338 MaxResponseHeaderBytes: t.MaxResponseHeaderBytes,
339 ForceAttemptHTTP2: t.ForceAttemptHTTP2,
340 WriteBufferSize: t.WriteBufferSize,
341 ReadBufferSize: t.ReadBufferSize,
342 }
343 if t.TLSClientConfig != nil {
344 t2.TLSClientConfig = t.TLSClientConfig.Clone()
345 }
346 if !t.tlsNextProtoWasNil {
347 npm := map[string]func(authority string, c *tls.Conn) RoundTripper{}
348 for k, v := range t.TLSNextProto {
349 npm[k] = v
350 }
351 t2.TLSNextProto = npm
352 }
353 return t2
354 }
355
356
357
358
359
360
361
362 type h2Transport interface {
363 CloseIdleConnections()
364 }
365
366 func (t *Transport) hasCustomTLSDialer() bool {
367 return t.DialTLS != nil || t.DialTLSContext != nil
368 }
369
370 var http2client = godebug.New("http2client")
371
372
373
374 func (t *Transport) onceSetNextProtoDefaults() {
375 t.tlsNextProtoWasNil = (t.TLSNextProto == nil)
376 if http2client.Value() == "0" {
377 http2client.IncNonDefault()
378 return
379 }
380
381
382
383
384
385
386 altProto, _ := t.altProto.Load().(map[string]RoundTripper)
387 if rv := reflect.ValueOf(altProto["https"]); rv.IsValid() && rv.Type().Kind() == reflect.Struct && rv.Type().NumField() == 1 {
388 if v := rv.Field(0); v.CanInterface() {
389 if h2i, ok := v.Interface().(h2Transport); ok {
390 t.h2transport = h2i
391 return
392 }
393 }
394 }
395
396 if t.TLSNextProto != nil {
397
398
399 return
400 }
401 if !t.ForceAttemptHTTP2 && (t.TLSClientConfig != nil || t.Dial != nil || t.DialContext != nil || t.hasCustomTLSDialer()) {
402
403
404
405
406
407
408 return
409 }
410 if omitBundledHTTP2 {
411 return
412 }
413 t2, err := http2configureTransports(t)
414 if err != nil {
415 log.Printf("Error enabling Transport HTTP/2 support: %v", err)
416 return
417 }
418 t.h2transport = t2
419
420
421
422
423
424
425
426 if limit1 := t.MaxResponseHeaderBytes; limit1 != 0 && t2.MaxHeaderListSize == 0 {
427 const h2max = 1<<32 - 1
428 if limit1 >= h2max {
429 t2.MaxHeaderListSize = h2max
430 } else {
431 t2.MaxHeaderListSize = uint32(limit1)
432 }
433 }
434 }
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452 func ProxyFromEnvironment(req *Request) (*url.URL, error) {
453 return envProxyFunc()(req.URL)
454 }
455
456
457
458 func ProxyURL(fixedURL *url.URL) func(*Request) (*url.URL, error) {
459 return func(*Request) (*url.URL, error) {
460 return fixedURL, nil
461 }
462 }
463
464
465
466
467 type transportRequest struct {
468 *Request
469 extra Header
470 trace *httptrace.ClientTrace
471 cancelKey cancelKey
472
473 mu sync.Mutex
474 err error
475 }
476
477 func (tr *transportRequest) extraHeaders() Header {
478 if tr.extra == nil {
479 tr.extra = make(Header)
480 }
481 return tr.extra
482 }
483
484 func (tr *transportRequest) setError(err error) {
485 tr.mu.Lock()
486 if tr.err == nil {
487 tr.err = err
488 }
489 tr.mu.Unlock()
490 }
491
492
493
494 func (t *Transport) useRegisteredProtocol(req *Request) bool {
495 if req.URL.Scheme == "https" && req.requiresHTTP1() {
496
497
498
499
500 return false
501 }
502 return true
503 }
504
505
506
507
508 func (t *Transport) alternateRoundTripper(req *Request) RoundTripper {
509 if !t.useRegisteredProtocol(req) {
510 return nil
511 }
512 altProto, _ := t.altProto.Load().(map[string]RoundTripper)
513 return altProto[req.URL.Scheme]
514 }
515
516 func validateHeaders(hdrs Header) string {
517 for k, vv := range hdrs {
518 if !httpguts.ValidHeaderFieldName(k) {
519 return fmt.Sprintf("field name %q", k)
520 }
521 for _, v := range vv {
522 if !httpguts.ValidHeaderFieldValue(v) {
523
524
525 return fmt.Sprintf("field value for %q", k)
526 }
527 }
528 }
529 return ""
530 }
531
532
533 func (t *Transport) roundTrip(req *Request) (*Response, error) {
534 t.nextProtoOnce.Do(t.onceSetNextProtoDefaults)
535 ctx := req.Context()
536 trace := httptrace.ContextClientTrace(ctx)
537
538 if req.URL == nil {
539 req.closeBody()
540 return nil, errors.New("http: nil Request.URL")
541 }
542 if req.Header == nil {
543 req.closeBody()
544 return nil, errors.New("http: nil Request.Header")
545 }
546 scheme := req.URL.Scheme
547 isHTTP := scheme == "http" || scheme == "https"
548 if isHTTP {
549
550 if err := validateHeaders(req.Header); err != "" {
551 req.closeBody()
552 return nil, fmt.Errorf("net/http: invalid header %s", err)
553 }
554
555
556 if err := validateHeaders(req.Trailer); err != "" {
557 req.closeBody()
558 return nil, fmt.Errorf("net/http: invalid trailer %s", err)
559 }
560 }
561
562 origReq := req
563 cancelKey := cancelKey{origReq}
564 req = setupRewindBody(req)
565
566 if altRT := t.alternateRoundTripper(req); altRT != nil {
567 if resp, err := altRT.RoundTrip(req); err != ErrSkipAltProtocol {
568 return resp, err
569 }
570 var err error
571 req, err = rewindBody(req)
572 if err != nil {
573 return nil, err
574 }
575 }
576 if !isHTTP {
577 req.closeBody()
578 return nil, badStringError("unsupported protocol scheme", scheme)
579 }
580 if req.Method != "" && !validMethod(req.Method) {
581 req.closeBody()
582 return nil, fmt.Errorf("net/http: invalid method %q", req.Method)
583 }
584 if req.URL.Host == "" {
585 req.closeBody()
586 return nil, errors.New("http: no Host in request URL")
587 }
588
589 for {
590 select {
591 case <-ctx.Done():
592 req.closeBody()
593 return nil, ctx.Err()
594 default:
595 }
596
597
598 treq := &transportRequest{Request: req, trace: trace, cancelKey: cancelKey}
599 cm, err := t.connectMethodForRequest(treq)
600 if err != nil {
601 req.closeBody()
602 return nil, err
603 }
604
605
606
607
608
609 pconn, err := t.getConn(treq, cm)
610 if err != nil {
611 t.setReqCanceler(cancelKey, nil)
612 req.closeBody()
613 return nil, err
614 }
615
616 var resp *Response
617 if pconn.alt != nil {
618
619 t.setReqCanceler(cancelKey, nil)
620 resp, err = pconn.alt.RoundTrip(req)
621 } else {
622 resp, err = pconn.roundTrip(treq)
623 }
624 if err == nil {
625 resp.Request = origReq
626 return resp, nil
627 }
628
629
630 if http2isNoCachedConnError(err) {
631 if t.removeIdleConn(pconn) {
632 t.decConnsPerHost(pconn.cacheKey)
633 }
634 } else if !pconn.shouldRetryRequest(req, err) {
635
636
637 if e, ok := err.(nothingWrittenError); ok {
638 err = e.error
639 }
640 if e, ok := err.(transportReadFromServerError); ok {
641 err = e.err
642 }
643 if b, ok := req.Body.(*readTrackingBody); ok && !b.didClose {
644
645
646
647 req.closeBody()
648 }
649 return nil, err
650 }
651 testHookRoundTripRetried()
652
653
654 req, err = rewindBody(req)
655 if err != nil {
656 return nil, err
657 }
658 }
659 }
660
661 var errCannotRewind = errors.New("net/http: cannot rewind body after connection loss")
662
663 type readTrackingBody struct {
664 io.ReadCloser
665 didRead bool
666 didClose bool
667 }
668
669 func (r *readTrackingBody) Read(data []byte) (int, error) {
670 r.didRead = true
671 return r.ReadCloser.Read(data)
672 }
673
674 func (r *readTrackingBody) Close() error {
675 r.didClose = true
676 return r.ReadCloser.Close()
677 }
678
679
680
681
682
683 func setupRewindBody(req *Request) *Request {
684 if req.Body == nil || req.Body == NoBody {
685 return req
686 }
687 newReq := *req
688 newReq.Body = &readTrackingBody{ReadCloser: req.Body}
689 return &newReq
690 }
691
692
693
694
695
696 func rewindBody(req *Request) (rewound *Request, err error) {
697 if req.Body == nil || req.Body == NoBody || (!req.Body.(*readTrackingBody).didRead && !req.Body.(*readTrackingBody).didClose) {
698 return req, nil
699 }
700 if !req.Body.(*readTrackingBody).didClose {
701 req.closeBody()
702 }
703 if req.GetBody == nil {
704 return nil, errCannotRewind
705 }
706 body, err := req.GetBody()
707 if err != nil {
708 return nil, err
709 }
710 newReq := *req
711 newReq.Body = &readTrackingBody{ReadCloser: body}
712 return &newReq, nil
713 }
714
715
716
717
718 func (pc *persistConn) shouldRetryRequest(req *Request, err error) bool {
719 if http2isNoCachedConnError(err) {
720
721
722
723
724
725
726 return true
727 }
728 if err == errMissingHost {
729
730 return false
731 }
732 if !pc.isReused() {
733
734
735
736
737
738
739
740 return false
741 }
742 if _, ok := err.(nothingWrittenError); ok {
743
744
745 return req.outgoingLength() == 0 || req.GetBody != nil
746 }
747 if !req.isReplayable() {
748
749 return false
750 }
751 if _, ok := err.(transportReadFromServerError); ok {
752
753
754 return true
755 }
756 if err == errServerClosedIdle {
757
758
759
760 return true
761 }
762 return false
763 }
764
765
766 var ErrSkipAltProtocol = errors.New("net/http: skip alternate protocol")
767
768
769
770
771
772
773
774
775
776
777
778 func (t *Transport) RegisterProtocol(scheme string, rt RoundTripper) {
779 t.altMu.Lock()
780 defer t.altMu.Unlock()
781 oldMap, _ := t.altProto.Load().(map[string]RoundTripper)
782 if _, exists := oldMap[scheme]; exists {
783 panic("protocol " + scheme + " already registered")
784 }
785 newMap := make(map[string]RoundTripper)
786 for k, v := range oldMap {
787 newMap[k] = v
788 }
789 newMap[scheme] = rt
790 t.altProto.Store(newMap)
791 }
792
793
794
795
796
797 func (t *Transport) CloseIdleConnections() {
798 t.nextProtoOnce.Do(t.onceSetNextProtoDefaults)
799 t.idleMu.Lock()
800 m := t.idleConn
801 t.idleConn = nil
802 t.closeIdle = true
803 t.idleLRU = connLRU{}
804 t.idleMu.Unlock()
805 for _, conns := range m {
806 for _, pconn := range conns {
807 pconn.close(errCloseIdleConns)
808 }
809 }
810 if t2 := t.h2transport; t2 != nil {
811 t2.CloseIdleConnections()
812 }
813 }
814
815
816
817
818
819
820
821 func (t *Transport) CancelRequest(req *Request) {
822 t.cancelRequest(cancelKey{req}, errRequestCanceled)
823 }
824
825
826
827 func (t *Transport) cancelRequest(key cancelKey, err error) bool {
828
829
830 t.reqMu.Lock()
831 defer t.reqMu.Unlock()
832 cancel := t.reqCanceler[key]
833 delete(t.reqCanceler, key)
834 if cancel != nil {
835 cancel(err)
836 }
837
838 return cancel != nil
839 }
840
841
842
843
844
845 var (
846 envProxyOnce sync.Once
847 envProxyFuncValue func(*url.URL) (*url.URL, error)
848 )
849
850
851
852 func envProxyFunc() func(*url.URL) (*url.URL, error) {
853 envProxyOnce.Do(func() {
854 envProxyFuncValue = httpproxy.FromEnvironment().ProxyFunc()
855 })
856 return envProxyFuncValue
857 }
858
859
860 func resetProxyConfig() {
861 envProxyOnce = sync.Once{}
862 envProxyFuncValue = nil
863 }
864
865 func (t *Transport) connectMethodForRequest(treq *transportRequest) (cm connectMethod, err error) {
866 cm.targetScheme = treq.URL.Scheme
867 cm.targetAddr = canonicalAddr(treq.URL)
868 if t.Proxy != nil {
869 cm.proxyURL, err = t.Proxy(treq.Request)
870 }
871 cm.onlyH1 = treq.requiresHTTP1()
872 return cm, err
873 }
874
875
876
877 func (cm *connectMethod) proxyAuth() string {
878 if cm.proxyURL == nil {
879 return ""
880 }
881 if u := cm.proxyURL.User; u != nil {
882 username := u.Username()
883 password, _ := u.Password()
884 return "Basic " + basicAuth(username, password)
885 }
886 return ""
887 }
888
889
890 var (
891 errKeepAlivesDisabled = errors.New("http: putIdleConn: keep alives disabled")
892 errConnBroken = errors.New("http: putIdleConn: connection is in bad state")
893 errCloseIdle = errors.New("http: putIdleConn: CloseIdleConnections was called")
894 errTooManyIdle = errors.New("http: putIdleConn: too many idle connections")
895 errTooManyIdleHost = errors.New("http: putIdleConn: too many idle connections for host")
896 errCloseIdleConns = errors.New("http: CloseIdleConnections called")
897 errReadLoopExiting = errors.New("http: persistConn.readLoop exiting")
898 errIdleConnTimeout = errors.New("http: idle connection timeout")
899
900
901
902
903
904 errServerClosedIdle = errors.New("http: server closed idle connection")
905 )
906
907
908
909
910
911
912
913
914
915 type transportReadFromServerError struct {
916 err error
917 }
918
919 func (e transportReadFromServerError) Unwrap() error { return e.err }
920
921 func (e transportReadFromServerError) Error() string {
922 return fmt.Sprintf("net/http: Transport failed to read from server: %v", e.err)
923 }
924
925 func (t *Transport) putOrCloseIdleConn(pconn *persistConn) {
926 if err := t.tryPutIdleConn(pconn); err != nil {
927 pconn.close(err)
928 }
929 }
930
931 func (t *Transport) maxIdleConnsPerHost() int {
932 if v := t.MaxIdleConnsPerHost; v != 0 {
933 return v
934 }
935 return DefaultMaxIdleConnsPerHost
936 }
937
938
939
940
941
942
943 func (t *Transport) tryPutIdleConn(pconn *persistConn) error {
944 if t.DisableKeepAlives || t.MaxIdleConnsPerHost < 0 {
945 return errKeepAlivesDisabled
946 }
947 if pconn.isBroken() {
948 return errConnBroken
949 }
950 pconn.markReused()
951
952 t.idleMu.Lock()
953 defer t.idleMu.Unlock()
954
955
956
957
958 if pconn.alt != nil && t.idleLRU.m[pconn] != nil {
959 return nil
960 }
961
962
963
964
965
966 key := pconn.cacheKey
967 if q, ok := t.idleConnWait[key]; ok {
968 done := false
969 if pconn.alt == nil {
970
971
972 for q.len() > 0 {
973 w := q.popFront()
974 if w.tryDeliver(pconn, nil, time.Time{}) {
975 done = true
976 break
977 }
978 }
979 } else {
980
981
982
983
984 for q.len() > 0 {
985 w := q.popFront()
986 w.tryDeliver(pconn, nil, time.Time{})
987 }
988 }
989 if q.len() == 0 {
990 delete(t.idleConnWait, key)
991 } else {
992 t.idleConnWait[key] = q
993 }
994 if done {
995 return nil
996 }
997 }
998
999 if t.closeIdle {
1000 return errCloseIdle
1001 }
1002 if t.idleConn == nil {
1003 t.idleConn = make(map[connectMethodKey][]*persistConn)
1004 }
1005 idles := t.idleConn[key]
1006 if len(idles) >= t.maxIdleConnsPerHost() {
1007 return errTooManyIdleHost
1008 }
1009 for _, exist := range idles {
1010 if exist == pconn {
1011 log.Fatalf("dup idle pconn %p in freelist", pconn)
1012 }
1013 }
1014 t.idleConn[key] = append(idles, pconn)
1015 t.idleLRU.add(pconn)
1016 if t.MaxIdleConns != 0 && t.idleLRU.len() > t.MaxIdleConns {
1017 oldest := t.idleLRU.removeOldest()
1018 oldest.close(errTooManyIdle)
1019 t.removeIdleConnLocked(oldest)
1020 }
1021
1022
1023
1024
1025 if t.IdleConnTimeout > 0 && pconn.alt == nil {
1026 if pconn.idleTimer != nil {
1027 pconn.idleTimer.Reset(t.IdleConnTimeout)
1028 } else {
1029 pconn.idleTimer = time.AfterFunc(t.IdleConnTimeout, pconn.closeConnIfStillIdle)
1030 }
1031 }
1032 pconn.idleAt = time.Now()
1033 return nil
1034 }
1035
1036
1037
1038
1039 func (t *Transport) queueForIdleConn(w *wantConn) (delivered bool) {
1040 if t.DisableKeepAlives {
1041 return false
1042 }
1043
1044 t.idleMu.Lock()
1045 defer t.idleMu.Unlock()
1046
1047
1048
1049 t.closeIdle = false
1050
1051 if w == nil {
1052
1053 return false
1054 }
1055
1056
1057
1058
1059 var oldTime time.Time
1060 if t.IdleConnTimeout > 0 {
1061 oldTime = time.Now().Add(-t.IdleConnTimeout)
1062 }
1063
1064
1065 if list, ok := t.idleConn[w.key]; ok {
1066 stop := false
1067 delivered := false
1068 for len(list) > 0 && !stop {
1069 pconn := list[len(list)-1]
1070
1071
1072
1073
1074 tooOld := !oldTime.IsZero() && pconn.idleAt.Round(0).Before(oldTime)
1075 if tooOld {
1076
1077
1078
1079 go pconn.closeConnIfStillIdle()
1080 }
1081 if pconn.isBroken() || tooOld {
1082
1083
1084
1085
1086
1087 list = list[:len(list)-1]
1088 continue
1089 }
1090 delivered = w.tryDeliver(pconn, nil, pconn.idleAt)
1091 if delivered {
1092 if pconn.alt != nil {
1093
1094
1095 } else {
1096
1097
1098 t.idleLRU.remove(pconn)
1099 list = list[:len(list)-1]
1100 }
1101 }
1102 stop = true
1103 }
1104 if len(list) > 0 {
1105 t.idleConn[w.key] = list
1106 } else {
1107 delete(t.idleConn, w.key)
1108 }
1109 if stop {
1110 return delivered
1111 }
1112 }
1113
1114
1115 if t.idleConnWait == nil {
1116 t.idleConnWait = make(map[connectMethodKey]wantConnQueue)
1117 }
1118 q := t.idleConnWait[w.key]
1119 q.cleanFront()
1120 q.pushBack(w)
1121 t.idleConnWait[w.key] = q
1122 return false
1123 }
1124
1125
1126 func (t *Transport) removeIdleConn(pconn *persistConn) bool {
1127 t.idleMu.Lock()
1128 defer t.idleMu.Unlock()
1129 return t.removeIdleConnLocked(pconn)
1130 }
1131
1132
1133 func (t *Transport) removeIdleConnLocked(pconn *persistConn) bool {
1134 if pconn.idleTimer != nil {
1135 pconn.idleTimer.Stop()
1136 }
1137 t.idleLRU.remove(pconn)
1138 key := pconn.cacheKey
1139 pconns := t.idleConn[key]
1140 var removed bool
1141 switch len(pconns) {
1142 case 0:
1143
1144 case 1:
1145 if pconns[0] == pconn {
1146 delete(t.idleConn, key)
1147 removed = true
1148 }
1149 default:
1150 for i, v := range pconns {
1151 if v != pconn {
1152 continue
1153 }
1154
1155
1156 copy(pconns[i:], pconns[i+1:])
1157 t.idleConn[key] = pconns[:len(pconns)-1]
1158 removed = true
1159 break
1160 }
1161 }
1162 return removed
1163 }
1164
1165 func (t *Transport) setReqCanceler(key cancelKey, fn func(error)) {
1166 t.reqMu.Lock()
1167 defer t.reqMu.Unlock()
1168 if t.reqCanceler == nil {
1169 t.reqCanceler = make(map[cancelKey]func(error))
1170 }
1171 if fn != nil {
1172 t.reqCanceler[key] = fn
1173 } else {
1174 delete(t.reqCanceler, key)
1175 }
1176 }
1177
1178
1179
1180
1181
1182 func (t *Transport) replaceReqCanceler(key cancelKey, fn func(error)) bool {
1183 t.reqMu.Lock()
1184 defer t.reqMu.Unlock()
1185 _, ok := t.reqCanceler[key]
1186 if !ok {
1187 return false
1188 }
1189 if fn != nil {
1190 t.reqCanceler[key] = fn
1191 } else {
1192 delete(t.reqCanceler, key)
1193 }
1194 return true
1195 }
1196
1197 var zeroDialer net.Dialer
1198
1199 func (t *Transport) dial(ctx context.Context, network, addr string) (net.Conn, error) {
1200 if t.DialContext != nil {
1201 c, err := t.DialContext(ctx, network, addr)
1202 if c == nil && err == nil {
1203 err = errors.New("net/http: Transport.DialContext hook returned (nil, nil)")
1204 }
1205 return c, err
1206 }
1207 if t.Dial != nil {
1208 c, err := t.Dial(network, addr)
1209 if c == nil && err == nil {
1210 err = errors.New("net/http: Transport.Dial hook returned (nil, nil)")
1211 }
1212 return c, err
1213 }
1214 return zeroDialer.DialContext(ctx, network, addr)
1215 }
1216
1217
1218
1219
1220
1221
1222
1223 type wantConn struct {
1224 cm connectMethod
1225 key connectMethodKey
1226
1227
1228
1229
1230 beforeDial func()
1231 afterDial func()
1232
1233 mu sync.Mutex
1234 ctx context.Context
1235 done bool
1236 result chan connOrError
1237 }
1238
1239 type connOrError struct {
1240 pc *persistConn
1241 err error
1242 idleAt time.Time
1243 }
1244
1245
1246 func (w *wantConn) waiting() bool {
1247 w.mu.Lock()
1248 defer w.mu.Unlock()
1249
1250 return !w.done
1251 }
1252
1253
1254 func (w *wantConn) getCtxForDial() context.Context {
1255 w.mu.Lock()
1256 defer w.mu.Unlock()
1257
1258 return w.ctx
1259 }
1260
1261
1262 func (w *wantConn) tryDeliver(pc *persistConn, err error, idleAt time.Time) bool {
1263 w.mu.Lock()
1264 defer w.mu.Unlock()
1265
1266 if w.done {
1267 return false
1268 }
1269 if (pc == nil) == (err == nil) {
1270 panic("net/http: internal error: misuse of tryDeliver")
1271 }
1272 w.ctx = nil
1273 w.done = true
1274
1275 w.result <- connOrError{pc: pc, err: err, idleAt: idleAt}
1276 close(w.result)
1277
1278 return true
1279 }
1280
1281
1282
1283 func (w *wantConn) cancel(t *Transport, err error) {
1284 w.mu.Lock()
1285 var pc *persistConn
1286 if w.done {
1287 if r, ok := <-w.result; ok {
1288 pc = r.pc
1289 }
1290 } else {
1291 close(w.result)
1292 }
1293 w.ctx = nil
1294 w.done = true
1295 w.mu.Unlock()
1296
1297 if pc != nil {
1298 t.putOrCloseIdleConn(pc)
1299 }
1300 }
1301
1302
1303 type wantConnQueue struct {
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314 head []*wantConn
1315 headPos int
1316 tail []*wantConn
1317 }
1318
1319
1320 func (q *wantConnQueue) len() int {
1321 return len(q.head) - q.headPos + len(q.tail)
1322 }
1323
1324
1325 func (q *wantConnQueue) pushBack(w *wantConn) {
1326 q.tail = append(q.tail, w)
1327 }
1328
1329
1330 func (q *wantConnQueue) popFront() *wantConn {
1331 if q.headPos >= len(q.head) {
1332 if len(q.tail) == 0 {
1333 return nil
1334 }
1335
1336 q.head, q.headPos, q.tail = q.tail, 0, q.head[:0]
1337 }
1338 w := q.head[q.headPos]
1339 q.head[q.headPos] = nil
1340 q.headPos++
1341 return w
1342 }
1343
1344
1345 func (q *wantConnQueue) peekFront() *wantConn {
1346 if q.headPos < len(q.head) {
1347 return q.head[q.headPos]
1348 }
1349 if len(q.tail) > 0 {
1350 return q.tail[0]
1351 }
1352 return nil
1353 }
1354
1355
1356
1357 func (q *wantConnQueue) cleanFront() (cleaned bool) {
1358 for {
1359 w := q.peekFront()
1360 if w == nil || w.waiting() {
1361 return cleaned
1362 }
1363 q.popFront()
1364 cleaned = true
1365 }
1366 }
1367
1368 func (t *Transport) customDialTLS(ctx context.Context, network, addr string) (conn net.Conn, err error) {
1369 if t.DialTLSContext != nil {
1370 conn, err = t.DialTLSContext(ctx, network, addr)
1371 } else {
1372 conn, err = t.DialTLS(network, addr)
1373 }
1374 if conn == nil && err == nil {
1375 err = errors.New("net/http: Transport.DialTLS or DialTLSContext returned (nil, nil)")
1376 }
1377 return
1378 }
1379
1380
1381
1382
1383
1384 func (t *Transport) getConn(treq *transportRequest, cm connectMethod) (_ *persistConn, err error) {
1385 req := treq.Request
1386 trace := treq.trace
1387 ctx := req.Context()
1388 if trace != nil && trace.GetConn != nil {
1389 trace.GetConn(cm.addr())
1390 }
1391
1392 w := &wantConn{
1393 cm: cm,
1394 key: cm.key(),
1395 ctx: ctx,
1396 result: make(chan connOrError, 1),
1397 beforeDial: testHookPrePendingDial,
1398 afterDial: testHookPostPendingDial,
1399 }
1400 defer func() {
1401 if err != nil {
1402 w.cancel(t, err)
1403 }
1404 }()
1405
1406 var cancelc chan error
1407
1408
1409 if delivered := t.queueForIdleConn(w); delivered {
1410
1411
1412
1413 t.setReqCanceler(treq.cancelKey, func(error) {})
1414 } else {
1415 cancelc = make(chan error, 1)
1416 t.setReqCanceler(treq.cancelKey, func(err error) { cancelc <- err })
1417
1418
1419 t.queueForDial(w)
1420 }
1421
1422
1423 select {
1424 case r := <-w.result:
1425
1426
1427 if r.pc != nil && r.pc.alt == nil && trace != nil && trace.GotConn != nil {
1428 info := httptrace.GotConnInfo{
1429 Conn: r.pc.conn,
1430 Reused: r.pc.isReused(),
1431 }
1432 if !r.idleAt.IsZero() {
1433 info.WasIdle = true
1434 info.IdleTime = time.Since(r.idleAt)
1435 }
1436 trace.GotConn(info)
1437 }
1438 if r.err != nil {
1439
1440
1441
1442 select {
1443 case <-req.Cancel:
1444 return nil, errRequestCanceledConn
1445 case <-req.Context().Done():
1446 return nil, req.Context().Err()
1447 case err := <-cancelc:
1448 if err == errRequestCanceled {
1449 err = errRequestCanceledConn
1450 }
1451 return nil, err
1452 default:
1453
1454 }
1455 }
1456 return r.pc, r.err
1457 case <-req.Cancel:
1458 return nil, errRequestCanceledConn
1459 case <-req.Context().Done():
1460 return nil, req.Context().Err()
1461 case err := <-cancelc:
1462 if err == errRequestCanceled {
1463 err = errRequestCanceledConn
1464 }
1465 return nil, err
1466 }
1467 }
1468
1469
1470
1471 func (t *Transport) queueForDial(w *wantConn) {
1472 w.beforeDial()
1473 if t.MaxConnsPerHost <= 0 {
1474 go t.dialConnFor(w)
1475 return
1476 }
1477
1478 t.connsPerHostMu.Lock()
1479 defer t.connsPerHostMu.Unlock()
1480
1481 if n := t.connsPerHost[w.key]; n < t.MaxConnsPerHost {
1482 if t.connsPerHost == nil {
1483 t.connsPerHost = make(map[connectMethodKey]int)
1484 }
1485 t.connsPerHost[w.key] = n + 1
1486 go t.dialConnFor(w)
1487 return
1488 }
1489
1490 if t.connsPerHostWait == nil {
1491 t.connsPerHostWait = make(map[connectMethodKey]wantConnQueue)
1492 }
1493 q := t.connsPerHostWait[w.key]
1494 q.cleanFront()
1495 q.pushBack(w)
1496 t.connsPerHostWait[w.key] = q
1497 }
1498
1499
1500
1501
1502 func (t *Transport) dialConnFor(w *wantConn) {
1503 defer w.afterDial()
1504 ctx := w.getCtxForDial()
1505 if ctx == nil {
1506 t.decConnsPerHost(w.key)
1507 return
1508 }
1509
1510 pc, err := t.dialConn(ctx, w.cm)
1511 delivered := w.tryDeliver(pc, err, time.Time{})
1512 if err == nil && (!delivered || pc.alt != nil) {
1513
1514
1515
1516 t.putOrCloseIdleConn(pc)
1517 }
1518 if err != nil {
1519 t.decConnsPerHost(w.key)
1520 }
1521 }
1522
1523
1524
1525 func (t *Transport) decConnsPerHost(key connectMethodKey) {
1526 if t.MaxConnsPerHost <= 0 {
1527 return
1528 }
1529
1530 t.connsPerHostMu.Lock()
1531 defer t.connsPerHostMu.Unlock()
1532 n := t.connsPerHost[key]
1533 if n == 0 {
1534
1535
1536 panic("net/http: internal error: connCount underflow")
1537 }
1538
1539
1540
1541
1542
1543 if q := t.connsPerHostWait[key]; q.len() > 0 {
1544 done := false
1545 for q.len() > 0 {
1546 w := q.popFront()
1547 if w.waiting() {
1548 go t.dialConnFor(w)
1549 done = true
1550 break
1551 }
1552 }
1553 if q.len() == 0 {
1554 delete(t.connsPerHostWait, key)
1555 } else {
1556
1557
1558 t.connsPerHostWait[key] = q
1559 }
1560 if done {
1561 return
1562 }
1563 }
1564
1565
1566 if n--; n == 0 {
1567 delete(t.connsPerHost, key)
1568 } else {
1569 t.connsPerHost[key] = n
1570 }
1571 }
1572
1573
1574
1575
1576 func (pconn *persistConn) addTLS(ctx context.Context, name string, trace *httptrace.ClientTrace) error {
1577
1578 cfg := cloneTLSConfig(pconn.t.TLSClientConfig)
1579 if cfg.ServerName == "" {
1580 cfg.ServerName = name
1581 }
1582 if pconn.cacheKey.onlyH1 {
1583 cfg.NextProtos = nil
1584 }
1585 plainConn := pconn.conn
1586 tlsConn := tls.Client(plainConn, cfg)
1587 errc := make(chan error, 2)
1588 var timer *time.Timer
1589 if d := pconn.t.TLSHandshakeTimeout; d != 0 {
1590 timer = time.AfterFunc(d, func() {
1591 errc <- tlsHandshakeTimeoutError{}
1592 })
1593 }
1594 go func() {
1595 if trace != nil && trace.TLSHandshakeStart != nil {
1596 trace.TLSHandshakeStart()
1597 }
1598 err := tlsConn.HandshakeContext(ctx)
1599 if timer != nil {
1600 timer.Stop()
1601 }
1602 errc <- err
1603 }()
1604 if err := <-errc; err != nil {
1605 plainConn.Close()
1606 if err == (tlsHandshakeTimeoutError{}) {
1607
1608
1609 <-errc
1610 }
1611 if trace != nil && trace.TLSHandshakeDone != nil {
1612 trace.TLSHandshakeDone(tls.ConnectionState{}, err)
1613 }
1614 return err
1615 }
1616 cs := tlsConn.ConnectionState()
1617 if trace != nil && trace.TLSHandshakeDone != nil {
1618 trace.TLSHandshakeDone(cs, nil)
1619 }
1620 pconn.tlsState = &cs
1621 pconn.conn = tlsConn
1622 return nil
1623 }
1624
1625 type erringRoundTripper interface {
1626 RoundTripErr() error
1627 }
1628
1629 func (t *Transport) dialConn(ctx context.Context, cm connectMethod) (pconn *persistConn, err error) {
1630 pconn = &persistConn{
1631 t: t,
1632 cacheKey: cm.key(),
1633 reqch: make(chan requestAndChan, 1),
1634 writech: make(chan writeRequest, 1),
1635 closech: make(chan struct{}),
1636 writeErrCh: make(chan error, 1),
1637 writeLoopDone: make(chan struct{}),
1638 }
1639 trace := httptrace.ContextClientTrace(ctx)
1640 wrapErr := func(err error) error {
1641 if cm.proxyURL != nil {
1642
1643 return &net.OpError{Op: "proxyconnect", Net: "tcp", Err: err}
1644 }
1645 return err
1646 }
1647 if cm.scheme() == "https" && t.hasCustomTLSDialer() {
1648 var err error
1649 pconn.conn, err = t.customDialTLS(ctx, "tcp", cm.addr())
1650 if err != nil {
1651 return nil, wrapErr(err)
1652 }
1653 if tc, ok := pconn.conn.(*tls.Conn); ok {
1654
1655
1656 if trace != nil && trace.TLSHandshakeStart != nil {
1657 trace.TLSHandshakeStart()
1658 }
1659 if err := tc.HandshakeContext(ctx); err != nil {
1660 go pconn.conn.Close()
1661 if trace != nil && trace.TLSHandshakeDone != nil {
1662 trace.TLSHandshakeDone(tls.ConnectionState{}, err)
1663 }
1664 return nil, err
1665 }
1666 cs := tc.ConnectionState()
1667 if trace != nil && trace.TLSHandshakeDone != nil {
1668 trace.TLSHandshakeDone(cs, nil)
1669 }
1670 pconn.tlsState = &cs
1671 }
1672 } else {
1673 conn, err := t.dial(ctx, "tcp", cm.addr())
1674 if err != nil {
1675 return nil, wrapErr(err)
1676 }
1677 pconn.conn = conn
1678 if cm.scheme() == "https" {
1679 var firstTLSHost string
1680 if firstTLSHost, _, err = net.SplitHostPort(cm.addr()); err != nil {
1681 return nil, wrapErr(err)
1682 }
1683 if err = pconn.addTLS(ctx, firstTLSHost, trace); err != nil {
1684 return nil, wrapErr(err)
1685 }
1686 }
1687 }
1688
1689
1690 switch {
1691 case cm.proxyURL == nil:
1692
1693 case cm.proxyURL.Scheme == "socks5" || cm.proxyURL.Scheme == "socks5h":
1694 conn := pconn.conn
1695 d := socksNewDialer("tcp", conn.RemoteAddr().String())
1696 if u := cm.proxyURL.User; u != nil {
1697 auth := &socksUsernamePassword{
1698 Username: u.Username(),
1699 }
1700 auth.Password, _ = u.Password()
1701 d.AuthMethods = []socksAuthMethod{
1702 socksAuthMethodNotRequired,
1703 socksAuthMethodUsernamePassword,
1704 }
1705 d.Authenticate = auth.Authenticate
1706 }
1707 if _, err := d.DialWithConn(ctx, conn, "tcp", cm.targetAddr); err != nil {
1708 conn.Close()
1709 return nil, err
1710 }
1711 case cm.targetScheme == "http":
1712 pconn.isProxy = true
1713 if pa := cm.proxyAuth(); pa != "" {
1714 pconn.mutateHeaderFunc = func(h Header) {
1715 h.Set("Proxy-Authorization", pa)
1716 }
1717 }
1718 case cm.targetScheme == "https":
1719 conn := pconn.conn
1720 var hdr Header
1721 if t.GetProxyConnectHeader != nil {
1722 var err error
1723 hdr, err = t.GetProxyConnectHeader(ctx, cm.proxyURL, cm.targetAddr)
1724 if err != nil {
1725 conn.Close()
1726 return nil, err
1727 }
1728 } else {
1729 hdr = t.ProxyConnectHeader
1730 }
1731 if hdr == nil {
1732 hdr = make(Header)
1733 }
1734 if pa := cm.proxyAuth(); pa != "" {
1735 hdr = hdr.Clone()
1736 hdr.Set("Proxy-Authorization", pa)
1737 }
1738 connectReq := &Request{
1739 Method: "CONNECT",
1740 URL: &url.URL{Opaque: cm.targetAddr},
1741 Host: cm.targetAddr,
1742 Header: hdr,
1743 }
1744
1745
1746
1747
1748
1749
1750 connectCtx := ctx
1751 if ctx.Done() == nil {
1752 newCtx, cancel := context.WithTimeout(ctx, 1*time.Minute)
1753 defer cancel()
1754 connectCtx = newCtx
1755 }
1756
1757 didReadResponse := make(chan struct{})
1758 var (
1759 resp *Response
1760 err error
1761 )
1762
1763 go func() {
1764 defer close(didReadResponse)
1765 err = connectReq.Write(conn)
1766 if err != nil {
1767 return
1768 }
1769
1770
1771 br := bufio.NewReader(conn)
1772 resp, err = ReadResponse(br, connectReq)
1773 }()
1774 select {
1775 case <-connectCtx.Done():
1776 conn.Close()
1777 <-didReadResponse
1778 return nil, connectCtx.Err()
1779 case <-didReadResponse:
1780
1781 }
1782 if err != nil {
1783 conn.Close()
1784 return nil, err
1785 }
1786
1787 if t.OnProxyConnectResponse != nil {
1788 err = t.OnProxyConnectResponse(ctx, cm.proxyURL, connectReq, resp)
1789 if err != nil {
1790 conn.Close()
1791 return nil, err
1792 }
1793 }
1794
1795 if resp.StatusCode != 200 {
1796 _, text, ok := strings.Cut(resp.Status, " ")
1797 conn.Close()
1798 if !ok {
1799 return nil, errors.New("unknown status code")
1800 }
1801 return nil, errors.New(text)
1802 }
1803 }
1804
1805 if cm.proxyURL != nil && cm.targetScheme == "https" {
1806 if err := pconn.addTLS(ctx, cm.tlsHost(), trace); err != nil {
1807 return nil, err
1808 }
1809 }
1810
1811 if s := pconn.tlsState; s != nil && s.NegotiatedProtocolIsMutual && s.NegotiatedProtocol != "" {
1812 if next, ok := t.TLSNextProto[s.NegotiatedProtocol]; ok {
1813 alt := next(cm.targetAddr, pconn.conn.(*tls.Conn))
1814 if e, ok := alt.(erringRoundTripper); ok {
1815
1816 return nil, e.RoundTripErr()
1817 }
1818 return &persistConn{t: t, cacheKey: pconn.cacheKey, alt: alt}, nil
1819 }
1820 }
1821
1822 pconn.br = bufio.NewReaderSize(pconn, t.readBufferSize())
1823 pconn.bw = bufio.NewWriterSize(persistConnWriter{pconn}, t.writeBufferSize())
1824
1825 go pconn.readLoop()
1826 go pconn.writeLoop()
1827 return pconn, nil
1828 }
1829
1830
1831
1832
1833
1834
1835
1836 type persistConnWriter struct {
1837 pc *persistConn
1838 }
1839
1840 func (w persistConnWriter) Write(p []byte) (n int, err error) {
1841 n, err = w.pc.conn.Write(p)
1842 w.pc.nwrite += int64(n)
1843 return
1844 }
1845
1846
1847
1848
1849 func (w persistConnWriter) ReadFrom(r io.Reader) (n int64, err error) {
1850 n, err = io.Copy(w.pc.conn, r)
1851 w.pc.nwrite += n
1852 return
1853 }
1854
1855 var _ io.ReaderFrom = (*persistConnWriter)(nil)
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873 type connectMethod struct {
1874 _ incomparable
1875 proxyURL *url.URL
1876 targetScheme string
1877
1878
1879
1880 targetAddr string
1881 onlyH1 bool
1882 }
1883
1884 func (cm *connectMethod) key() connectMethodKey {
1885 proxyStr := ""
1886 targetAddr := cm.targetAddr
1887 if cm.proxyURL != nil {
1888 proxyStr = cm.proxyURL.String()
1889 if (cm.proxyURL.Scheme == "http" || cm.proxyURL.Scheme == "https") && cm.targetScheme == "http" {
1890 targetAddr = ""
1891 }
1892 }
1893 return connectMethodKey{
1894 proxy: proxyStr,
1895 scheme: cm.targetScheme,
1896 addr: targetAddr,
1897 onlyH1: cm.onlyH1,
1898 }
1899 }
1900
1901
1902 func (cm *connectMethod) scheme() string {
1903 if cm.proxyURL != nil {
1904 return cm.proxyURL.Scheme
1905 }
1906 return cm.targetScheme
1907 }
1908
1909
1910 func (cm *connectMethod) addr() string {
1911 if cm.proxyURL != nil {
1912 return canonicalAddr(cm.proxyURL)
1913 }
1914 return cm.targetAddr
1915 }
1916
1917
1918
1919 func (cm *connectMethod) tlsHost() string {
1920 h := cm.targetAddr
1921 if hasPort(h) {
1922 h = h[:strings.LastIndex(h, ":")]
1923 }
1924 return h
1925 }
1926
1927
1928
1929
1930 type connectMethodKey struct {
1931 proxy, scheme, addr string
1932 onlyH1 bool
1933 }
1934
1935 func (k connectMethodKey) String() string {
1936
1937 var h1 string
1938 if k.onlyH1 {
1939 h1 = ",h1"
1940 }
1941 return fmt.Sprintf("%s|%s%s|%s", k.proxy, k.scheme, h1, k.addr)
1942 }
1943
1944
1945
1946 type persistConn struct {
1947
1948
1949
1950 alt RoundTripper
1951
1952 t *Transport
1953 cacheKey connectMethodKey
1954 conn net.Conn
1955 tlsState *tls.ConnectionState
1956 br *bufio.Reader
1957 bw *bufio.Writer
1958 nwrite int64
1959 reqch chan requestAndChan
1960 writech chan writeRequest
1961 closech chan struct{}
1962 isProxy bool
1963 sawEOF bool
1964 readLimit int64
1965
1966
1967
1968
1969 writeErrCh chan error
1970
1971 writeLoopDone chan struct{}
1972
1973
1974 idleAt time.Time
1975 idleTimer *time.Timer
1976
1977 mu sync.Mutex
1978 numExpectedResponses int
1979 closed error
1980 canceledErr error
1981 broken bool
1982 reused bool
1983
1984
1985
1986 mutateHeaderFunc func(Header)
1987 }
1988
1989 func (pc *persistConn) maxHeaderResponseSize() int64 {
1990 if v := pc.t.MaxResponseHeaderBytes; v != 0 {
1991 return v
1992 }
1993 return 10 << 20
1994 }
1995
1996 func (pc *persistConn) Read(p []byte) (n int, err error) {
1997 if pc.readLimit <= 0 {
1998 return 0, fmt.Errorf("read limit of %d bytes exhausted", pc.maxHeaderResponseSize())
1999 }
2000 if int64(len(p)) > pc.readLimit {
2001 p = p[:pc.readLimit]
2002 }
2003 n, err = pc.conn.Read(p)
2004 if err == io.EOF {
2005 pc.sawEOF = true
2006 }
2007 pc.readLimit -= int64(n)
2008 return
2009 }
2010
2011
2012 func (pc *persistConn) isBroken() bool {
2013 pc.mu.Lock()
2014 b := pc.closed != nil
2015 pc.mu.Unlock()
2016 return b
2017 }
2018
2019
2020
2021 func (pc *persistConn) canceled() error {
2022 pc.mu.Lock()
2023 defer pc.mu.Unlock()
2024 return pc.canceledErr
2025 }
2026
2027
2028 func (pc *persistConn) isReused() bool {
2029 pc.mu.Lock()
2030 r := pc.reused
2031 pc.mu.Unlock()
2032 return r
2033 }
2034
2035 func (pc *persistConn) cancelRequest(err error) {
2036 pc.mu.Lock()
2037 defer pc.mu.Unlock()
2038 pc.canceledErr = err
2039 pc.closeLocked(errRequestCanceled)
2040 }
2041
2042
2043
2044
2045 func (pc *persistConn) closeConnIfStillIdle() {
2046 t := pc.t
2047 t.idleMu.Lock()
2048 defer t.idleMu.Unlock()
2049 if _, ok := t.idleLRU.m[pc]; !ok {
2050
2051 return
2052 }
2053 t.removeIdleConnLocked(pc)
2054 pc.close(errIdleConnTimeout)
2055 }
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065 func (pc *persistConn) mapRoundTripError(req *transportRequest, startBytesWritten int64, err error) error {
2066 if err == nil {
2067 return nil
2068 }
2069
2070
2071
2072
2073
2074
2075
2076
2077 <-pc.writeLoopDone
2078
2079
2080
2081
2082 if cerr := pc.canceled(); cerr != nil {
2083 return cerr
2084 }
2085
2086
2087 req.mu.Lock()
2088 reqErr := req.err
2089 req.mu.Unlock()
2090 if reqErr != nil {
2091 return reqErr
2092 }
2093
2094 if err == errServerClosedIdle {
2095
2096 return err
2097 }
2098
2099 if _, ok := err.(transportReadFromServerError); ok {
2100 if pc.nwrite == startBytesWritten {
2101 return nothingWrittenError{err}
2102 }
2103
2104 return err
2105 }
2106 if pc.isBroken() {
2107 if pc.nwrite == startBytesWritten {
2108 return nothingWrittenError{err}
2109 }
2110 return fmt.Errorf("net/http: HTTP/1.x transport connection broken: %w", err)
2111 }
2112 return err
2113 }
2114
2115
2116
2117
2118 var errCallerOwnsConn = errors.New("read loop ending; caller owns writable underlying conn")
2119
2120 func (pc *persistConn) readLoop() {
2121 closeErr := errReadLoopExiting
2122 defer func() {
2123 pc.close(closeErr)
2124 pc.t.removeIdleConn(pc)
2125 }()
2126
2127 tryPutIdleConn := func(trace *httptrace.ClientTrace) bool {
2128 if err := pc.t.tryPutIdleConn(pc); err != nil {
2129 closeErr = err
2130 if trace != nil && trace.PutIdleConn != nil && err != errKeepAlivesDisabled {
2131 trace.PutIdleConn(err)
2132 }
2133 return false
2134 }
2135 if trace != nil && trace.PutIdleConn != nil {
2136 trace.PutIdleConn(nil)
2137 }
2138 return true
2139 }
2140
2141
2142
2143
2144 eofc := make(chan struct{})
2145 defer close(eofc)
2146
2147
2148 testHookMu.Lock()
2149 testHookReadLoopBeforeNextRead := testHookReadLoopBeforeNextRead
2150 testHookMu.Unlock()
2151
2152 alive := true
2153 for alive {
2154 pc.readLimit = pc.maxHeaderResponseSize()
2155 _, err := pc.br.Peek(1)
2156
2157 pc.mu.Lock()
2158 if pc.numExpectedResponses == 0 {
2159 pc.readLoopPeekFailLocked(err)
2160 pc.mu.Unlock()
2161 return
2162 }
2163 pc.mu.Unlock()
2164
2165 rc := <-pc.reqch
2166 trace := httptrace.ContextClientTrace(rc.req.Context())
2167
2168 var resp *Response
2169 if err == nil {
2170 resp, err = pc.readResponse(rc, trace)
2171 } else {
2172 err = transportReadFromServerError{err}
2173 closeErr = err
2174 }
2175
2176 if err != nil {
2177 if pc.readLimit <= 0 {
2178 err = fmt.Errorf("net/http: server response headers exceeded %d bytes; aborted", pc.maxHeaderResponseSize())
2179 }
2180
2181 select {
2182 case rc.ch <- responseAndError{err: err}:
2183 case <-rc.callerGone:
2184 return
2185 }
2186 return
2187 }
2188 pc.readLimit = maxInt64
2189
2190 pc.mu.Lock()
2191 pc.numExpectedResponses--
2192 pc.mu.Unlock()
2193
2194 bodyWritable := resp.bodyIsWritable()
2195 hasBody := rc.req.Method != "HEAD" && resp.ContentLength != 0
2196
2197 if resp.Close || rc.req.Close || resp.StatusCode <= 199 || bodyWritable {
2198
2199
2200
2201 alive = false
2202 }
2203
2204 if !hasBody || bodyWritable {
2205 replaced := pc.t.replaceReqCanceler(rc.cancelKey, nil)
2206
2207
2208
2209
2210
2211
2212 alive = alive &&
2213 !pc.sawEOF &&
2214 pc.wroteRequest() &&
2215 replaced && tryPutIdleConn(trace)
2216
2217 if bodyWritable {
2218 closeErr = errCallerOwnsConn
2219 }
2220
2221 select {
2222 case rc.ch <- responseAndError{res: resp}:
2223 case <-rc.callerGone:
2224 return
2225 }
2226
2227
2228
2229
2230 testHookReadLoopBeforeNextRead()
2231 continue
2232 }
2233
2234 waitForBodyRead := make(chan bool, 2)
2235 body := &bodyEOFSignal{
2236 body: resp.Body,
2237 earlyCloseFn: func() error {
2238 waitForBodyRead <- false
2239 <-eofc
2240 return nil
2241
2242 },
2243 fn: func(err error) error {
2244 isEOF := err == io.EOF
2245 waitForBodyRead <- isEOF
2246 if isEOF {
2247 <-eofc
2248 } else if err != nil {
2249 if cerr := pc.canceled(); cerr != nil {
2250 return cerr
2251 }
2252 }
2253 return err
2254 },
2255 }
2256
2257 resp.Body = body
2258 if rc.addedGzip && ascii.EqualFold(resp.Header.Get("Content-Encoding"), "gzip") {
2259 resp.Body = &gzipReader{body: body}
2260 resp.Header.Del("Content-Encoding")
2261 resp.Header.Del("Content-Length")
2262 resp.ContentLength = -1
2263 resp.Uncompressed = true
2264 }
2265
2266 select {
2267 case rc.ch <- responseAndError{res: resp}:
2268 case <-rc.callerGone:
2269 return
2270 }
2271
2272
2273
2274
2275 select {
2276 case bodyEOF := <-waitForBodyRead:
2277 replaced := pc.t.replaceReqCanceler(rc.cancelKey, nil)
2278 alive = alive &&
2279 bodyEOF &&
2280 !pc.sawEOF &&
2281 pc.wroteRequest() &&
2282 replaced && tryPutIdleConn(trace)
2283 if bodyEOF {
2284 eofc <- struct{}{}
2285 }
2286 case <-rc.req.Cancel:
2287 alive = false
2288 pc.t.cancelRequest(rc.cancelKey, errRequestCanceled)
2289 case <-rc.req.Context().Done():
2290 alive = false
2291 pc.t.cancelRequest(rc.cancelKey, rc.req.Context().Err())
2292 case <-pc.closech:
2293 alive = false
2294 pc.t.setReqCanceler(rc.cancelKey, nil)
2295 }
2296
2297 testHookReadLoopBeforeNextRead()
2298 }
2299 }
2300
2301 func (pc *persistConn) readLoopPeekFailLocked(peekErr error) {
2302 if pc.closed != nil {
2303 return
2304 }
2305 if n := pc.br.Buffered(); n > 0 {
2306 buf, _ := pc.br.Peek(n)
2307 if is408Message(buf) {
2308 pc.closeLocked(errServerClosedIdle)
2309 return
2310 } else {
2311 log.Printf("Unsolicited response received on idle HTTP channel starting with %q; err=%v", buf, peekErr)
2312 }
2313 }
2314 if peekErr == io.EOF {
2315
2316 pc.closeLocked(errServerClosedIdle)
2317 } else {
2318 pc.closeLocked(fmt.Errorf("readLoopPeekFailLocked: %w", peekErr))
2319 }
2320 }
2321
2322
2323
2324
2325 func is408Message(buf []byte) bool {
2326 if len(buf) < len("HTTP/1.x 408") {
2327 return false
2328 }
2329 if string(buf[:7]) != "HTTP/1." {
2330 return false
2331 }
2332 return string(buf[8:12]) == " 408"
2333 }
2334
2335
2336
2337
2338 func (pc *persistConn) readResponse(rc requestAndChan, trace *httptrace.ClientTrace) (resp *Response, err error) {
2339 if trace != nil && trace.GotFirstResponseByte != nil {
2340 if peek, err := pc.br.Peek(1); err == nil && len(peek) == 1 {
2341 trace.GotFirstResponseByte()
2342 }
2343 }
2344 num1xx := 0
2345 const max1xxResponses = 5
2346
2347 continueCh := rc.continueCh
2348 for {
2349 resp, err = ReadResponse(pc.br, rc.req)
2350 if err != nil {
2351 return
2352 }
2353 resCode := resp.StatusCode
2354 if continueCh != nil {
2355 if resCode == 100 {
2356 if trace != nil && trace.Got100Continue != nil {
2357 trace.Got100Continue()
2358 }
2359 continueCh <- struct{}{}
2360 continueCh = nil
2361 } else if resCode >= 200 {
2362 close(continueCh)
2363 continueCh = nil
2364 }
2365 }
2366 is1xx := 100 <= resCode && resCode <= 199
2367
2368 is1xxNonTerminal := is1xx && resCode != StatusSwitchingProtocols
2369 if is1xxNonTerminal {
2370 num1xx++
2371 if num1xx > max1xxResponses {
2372 return nil, errors.New("net/http: too many 1xx informational responses")
2373 }
2374 pc.readLimit = pc.maxHeaderResponseSize()
2375 if trace != nil && trace.Got1xxResponse != nil {
2376 if err := trace.Got1xxResponse(resCode, textproto.MIMEHeader(resp.Header)); err != nil {
2377 return nil, err
2378 }
2379 }
2380 continue
2381 }
2382 break
2383 }
2384 if resp.isProtocolSwitch() {
2385 resp.Body = newReadWriteCloserBody(pc.br, pc.conn)
2386 }
2387
2388 resp.TLS = pc.tlsState
2389 return
2390 }
2391
2392
2393
2394
2395 func (pc *persistConn) waitForContinue(continueCh <-chan struct{}) func() bool {
2396 if continueCh == nil {
2397 return nil
2398 }
2399 return func() bool {
2400 timer := time.NewTimer(pc.t.ExpectContinueTimeout)
2401 defer timer.Stop()
2402
2403 select {
2404 case _, ok := <-continueCh:
2405 return ok
2406 case <-timer.C:
2407 return true
2408 case <-pc.closech:
2409 return false
2410 }
2411 }
2412 }
2413
2414 func newReadWriteCloserBody(br *bufio.Reader, rwc io.ReadWriteCloser) io.ReadWriteCloser {
2415 body := &readWriteCloserBody{ReadWriteCloser: rwc}
2416 if br.Buffered() != 0 {
2417 body.br = br
2418 }
2419 return body
2420 }
2421
2422
2423
2424
2425
2426
2427 type readWriteCloserBody struct {
2428 _ incomparable
2429 br *bufio.Reader
2430 io.ReadWriteCloser
2431 }
2432
2433 func (b *readWriteCloserBody) Read(p []byte) (n int, err error) {
2434 if b.br != nil {
2435 if n := b.br.Buffered(); len(p) > n {
2436 p = p[:n]
2437 }
2438 n, err = b.br.Read(p)
2439 if b.br.Buffered() == 0 {
2440 b.br = nil
2441 }
2442 return n, err
2443 }
2444 return b.ReadWriteCloser.Read(p)
2445 }
2446
2447
2448 type nothingWrittenError struct {
2449 error
2450 }
2451
2452 func (nwe nothingWrittenError) Unwrap() error {
2453 return nwe.error
2454 }
2455
2456 func (pc *persistConn) writeLoop() {
2457 defer close(pc.writeLoopDone)
2458 for {
2459 select {
2460 case wr := <-pc.writech:
2461 startBytesWritten := pc.nwrite
2462 err := wr.req.Request.write(pc.bw, pc.isProxy, wr.req.extra, pc.waitForContinue(wr.continueCh))
2463 if bre, ok := err.(requestBodyReadError); ok {
2464 err = bre.error
2465
2466
2467
2468
2469
2470
2471
2472 wr.req.setError(err)
2473 }
2474 if err == nil {
2475 err = pc.bw.Flush()
2476 }
2477 if err != nil {
2478 if pc.nwrite == startBytesWritten {
2479 err = nothingWrittenError{err}
2480 }
2481 }
2482 pc.writeErrCh <- err
2483 wr.ch <- err
2484 if err != nil {
2485 pc.close(err)
2486 return
2487 }
2488 case <-pc.closech:
2489 return
2490 }
2491 }
2492 }
2493
2494
2495
2496
2497
2498
2499
2500 var maxWriteWaitBeforeConnReuse = 50 * time.Millisecond
2501
2502
2503
2504 func (pc *persistConn) wroteRequest() bool {
2505 select {
2506 case err := <-pc.writeErrCh:
2507
2508
2509 return err == nil
2510 default:
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521 t := time.NewTimer(maxWriteWaitBeforeConnReuse)
2522 defer t.Stop()
2523 select {
2524 case err := <-pc.writeErrCh:
2525 return err == nil
2526 case <-t.C:
2527 return false
2528 }
2529 }
2530 }
2531
2532
2533
2534 type responseAndError struct {
2535 _ incomparable
2536 res *Response
2537 err error
2538 }
2539
2540 type requestAndChan struct {
2541 _ incomparable
2542 req *Request
2543 cancelKey cancelKey
2544 ch chan responseAndError
2545
2546
2547
2548
2549 addedGzip bool
2550
2551
2552
2553
2554
2555 continueCh chan<- struct{}
2556
2557 callerGone <-chan struct{}
2558 }
2559
2560
2561
2562
2563
2564 type writeRequest struct {
2565 req *transportRequest
2566 ch chan<- error
2567
2568
2569
2570
2571 continueCh <-chan struct{}
2572 }
2573
2574
2575
2576 type timeoutError struct {
2577 err string
2578 }
2579
2580 func (e *timeoutError) Error() string { return e.err }
2581 func (e *timeoutError) Timeout() bool { return true }
2582 func (e *timeoutError) Temporary() bool { return true }
2583 func (e *timeoutError) Is(err error) bool { return err == context.DeadlineExceeded }
2584
2585 var errTimeout error = &timeoutError{"net/http: timeout awaiting response headers"}
2586
2587
2588
2589 var errRequestCanceled = http2errRequestCanceled
2590 var errRequestCanceledConn = errors.New("net/http: request canceled while waiting for connection")
2591
2592 func nop() {}
2593
2594
2595 var (
2596 testHookEnterRoundTrip = nop
2597 testHookWaitResLoop = nop
2598 testHookRoundTripRetried = nop
2599 testHookPrePendingDial = nop
2600 testHookPostPendingDial = nop
2601
2602 testHookMu sync.Locker = fakeLocker{}
2603 testHookReadLoopBeforeNextRead = nop
2604 )
2605
2606 func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err error) {
2607 testHookEnterRoundTrip()
2608 if !pc.t.replaceReqCanceler(req.cancelKey, pc.cancelRequest) {
2609 pc.t.putOrCloseIdleConn(pc)
2610 return nil, errRequestCanceled
2611 }
2612 pc.mu.Lock()
2613 pc.numExpectedResponses++
2614 headerFn := pc.mutateHeaderFunc
2615 pc.mu.Unlock()
2616
2617 if headerFn != nil {
2618 headerFn(req.extraHeaders())
2619 }
2620
2621
2622
2623
2624
2625 requestedGzip := false
2626 if !pc.t.DisableCompression &&
2627 req.Header.Get("Accept-Encoding") == "" &&
2628 req.Header.Get("Range") == "" &&
2629 req.Method != "HEAD" {
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642 requestedGzip = true
2643 req.extraHeaders().Set("Accept-Encoding", "gzip")
2644 }
2645
2646 var continueCh chan struct{}
2647 if req.ProtoAtLeast(1, 1) && req.Body != nil && req.expectsContinue() {
2648 continueCh = make(chan struct{}, 1)
2649 }
2650
2651 if pc.t.DisableKeepAlives &&
2652 !req.wantsClose() &&
2653 !isProtocolSwitchHeader(req.Header) {
2654 req.extraHeaders().Set("Connection", "close")
2655 }
2656
2657 gone := make(chan struct{})
2658 defer close(gone)
2659
2660 defer func() {
2661 if err != nil {
2662 pc.t.setReqCanceler(req.cancelKey, nil)
2663 }
2664 }()
2665
2666 const debugRoundTrip = false
2667
2668
2669
2670
2671 startBytesWritten := pc.nwrite
2672 writeErrCh := make(chan error, 1)
2673 pc.writech <- writeRequest{req, writeErrCh, continueCh}
2674
2675 resc := make(chan responseAndError)
2676 pc.reqch <- requestAndChan{
2677 req: req.Request,
2678 cancelKey: req.cancelKey,
2679 ch: resc,
2680 addedGzip: requestedGzip,
2681 continueCh: continueCh,
2682 callerGone: gone,
2683 }
2684
2685 var respHeaderTimer <-chan time.Time
2686 cancelChan := req.Request.Cancel
2687 ctxDoneChan := req.Context().Done()
2688 pcClosed := pc.closech
2689 canceled := false
2690 for {
2691 testHookWaitResLoop()
2692 select {
2693 case err := <-writeErrCh:
2694 if debugRoundTrip {
2695 req.logf("writeErrCh resv: %T/%#v", err, err)
2696 }
2697 if err != nil {
2698 pc.close(fmt.Errorf("write error: %w", err))
2699 return nil, pc.mapRoundTripError(req, startBytesWritten, err)
2700 }
2701 if d := pc.t.ResponseHeaderTimeout; d > 0 {
2702 if debugRoundTrip {
2703 req.logf("starting timer for %v", d)
2704 }
2705 timer := time.NewTimer(d)
2706 defer timer.Stop()
2707 respHeaderTimer = timer.C
2708 }
2709 case <-pcClosed:
2710 pcClosed = nil
2711 if canceled || pc.t.replaceReqCanceler(req.cancelKey, nil) {
2712 if debugRoundTrip {
2713 req.logf("closech recv: %T %#v", pc.closed, pc.closed)
2714 }
2715 return nil, pc.mapRoundTripError(req, startBytesWritten, pc.closed)
2716 }
2717 case <-respHeaderTimer:
2718 if debugRoundTrip {
2719 req.logf("timeout waiting for response headers.")
2720 }
2721 pc.close(errTimeout)
2722 return nil, errTimeout
2723 case re := <-resc:
2724 if (re.res == nil) == (re.err == nil) {
2725 panic(fmt.Sprintf("internal error: exactly one of res or err should be set; nil=%v", re.res == nil))
2726 }
2727 if debugRoundTrip {
2728 req.logf("resc recv: %p, %T/%#v", re.res, re.err, re.err)
2729 }
2730 if re.err != nil {
2731 return nil, pc.mapRoundTripError(req, startBytesWritten, re.err)
2732 }
2733 return re.res, nil
2734 case <-cancelChan:
2735 canceled = pc.t.cancelRequest(req.cancelKey, errRequestCanceled)
2736 cancelChan = nil
2737 case <-ctxDoneChan:
2738 canceled = pc.t.cancelRequest(req.cancelKey, req.Context().Err())
2739 cancelChan = nil
2740 ctxDoneChan = nil
2741 }
2742 }
2743 }
2744
2745
2746
2747 type tLogKey struct{}
2748
2749 func (tr *transportRequest) logf(format string, args ...any) {
2750 if logf, ok := tr.Request.Context().Value(tLogKey{}).(func(string, ...any)); ok {
2751 logf(time.Now().Format(time.RFC3339Nano)+": "+format, args...)
2752 }
2753 }
2754
2755
2756
2757 func (pc *persistConn) markReused() {
2758 pc.mu.Lock()
2759 pc.reused = true
2760 pc.mu.Unlock()
2761 }
2762
2763
2764
2765
2766
2767
2768 func (pc *persistConn) close(err error) {
2769 pc.mu.Lock()
2770 defer pc.mu.Unlock()
2771 pc.closeLocked(err)
2772 }
2773
2774 func (pc *persistConn) closeLocked(err error) {
2775 if err == nil {
2776 panic("nil error")
2777 }
2778 pc.broken = true
2779 if pc.closed == nil {
2780 pc.closed = err
2781 pc.t.decConnsPerHost(pc.cacheKey)
2782
2783
2784 if pc.alt == nil {
2785 if err != errCallerOwnsConn {
2786 pc.conn.Close()
2787 }
2788 close(pc.closech)
2789 }
2790 }
2791 pc.mutateHeaderFunc = nil
2792 }
2793
2794 var portMap = map[string]string{
2795 "http": "80",
2796 "https": "443",
2797 "socks5": "1080",
2798 "socks5h": "1080",
2799 }
2800
2801 func idnaASCIIFromURL(url *url.URL) string {
2802 addr := url.Hostname()
2803 if v, err := idnaASCII(addr); err == nil {
2804 addr = v
2805 }
2806 return addr
2807 }
2808
2809
2810 func canonicalAddr(url *url.URL) string {
2811 port := url.Port()
2812 if port == "" {
2813 port = portMap[url.Scheme]
2814 }
2815 return net.JoinHostPort(idnaASCIIFromURL(url), port)
2816 }
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829 type bodyEOFSignal struct {
2830 body io.ReadCloser
2831 mu sync.Mutex
2832 closed bool
2833 rerr error
2834 fn func(error) error
2835 earlyCloseFn func() error
2836 }
2837
2838 var errReadOnClosedResBody = errors.New("http: read on closed response body")
2839
2840 func (es *bodyEOFSignal) Read(p []byte) (n int, err error) {
2841 es.mu.Lock()
2842 closed, rerr := es.closed, es.rerr
2843 es.mu.Unlock()
2844 if closed {
2845 return 0, errReadOnClosedResBody
2846 }
2847 if rerr != nil {
2848 return 0, rerr
2849 }
2850
2851 n, err = es.body.Read(p)
2852 if err != nil {
2853 es.mu.Lock()
2854 defer es.mu.Unlock()
2855 if es.rerr == nil {
2856 es.rerr = err
2857 }
2858 err = es.condfn(err)
2859 }
2860 return
2861 }
2862
2863 func (es *bodyEOFSignal) Close() error {
2864 es.mu.Lock()
2865 defer es.mu.Unlock()
2866 if es.closed {
2867 return nil
2868 }
2869 es.closed = true
2870 if es.earlyCloseFn != nil && es.rerr != io.EOF {
2871 return es.earlyCloseFn()
2872 }
2873 err := es.body.Close()
2874 return es.condfn(err)
2875 }
2876
2877
2878 func (es *bodyEOFSignal) condfn(err error) error {
2879 if es.fn == nil {
2880 return err
2881 }
2882 err = es.fn(err)
2883 es.fn = nil
2884 return err
2885 }
2886
2887
2888
2889 type gzipReader struct {
2890 _ incomparable
2891 body *bodyEOFSignal
2892 zr *gzip.Reader
2893 zerr error
2894 }
2895
2896 func (gz *gzipReader) Read(p []byte) (n int, err error) {
2897 if gz.zr == nil {
2898 if gz.zerr == nil {
2899 gz.zr, gz.zerr = gzip.NewReader(gz.body)
2900 }
2901 if gz.zerr != nil {
2902 return 0, gz.zerr
2903 }
2904 }
2905
2906 gz.body.mu.Lock()
2907 if gz.body.closed {
2908 err = errReadOnClosedResBody
2909 }
2910 gz.body.mu.Unlock()
2911
2912 if err != nil {
2913 return 0, err
2914 }
2915 return gz.zr.Read(p)
2916 }
2917
2918 func (gz *gzipReader) Close() error {
2919 return gz.body.Close()
2920 }
2921
2922 type tlsHandshakeTimeoutError struct{}
2923
2924 func (tlsHandshakeTimeoutError) Timeout() bool { return true }
2925 func (tlsHandshakeTimeoutError) Temporary() bool { return true }
2926 func (tlsHandshakeTimeoutError) Error() string { return "net/http: TLS handshake timeout" }
2927
2928
2929
2930
2931 type fakeLocker struct{}
2932
2933 func (fakeLocker) Lock() {}
2934 func (fakeLocker) Unlock() {}
2935
2936
2937
2938
2939 func cloneTLSConfig(cfg *tls.Config) *tls.Config {
2940 if cfg == nil {
2941 return &tls.Config{}
2942 }
2943 return cfg.Clone()
2944 }
2945
2946 type connLRU struct {
2947 ll *list.List
2948 m map[*persistConn]*list.Element
2949 }
2950
2951
2952 func (cl *connLRU) add(pc *persistConn) {
2953 if cl.ll == nil {
2954 cl.ll = list.New()
2955 cl.m = make(map[*persistConn]*list.Element)
2956 }
2957 ele := cl.ll.PushFront(pc)
2958 if _, ok := cl.m[pc]; ok {
2959 panic("persistConn was already in LRU")
2960 }
2961 cl.m[pc] = ele
2962 }
2963
2964 func (cl *connLRU) removeOldest() *persistConn {
2965 ele := cl.ll.Back()
2966 pc := ele.Value.(*persistConn)
2967 cl.ll.Remove(ele)
2968 delete(cl.m, pc)
2969 return pc
2970 }
2971
2972
2973 func (cl *connLRU) remove(pc *persistConn) {
2974 if ele, ok := cl.m[pc]; ok {
2975 cl.ll.Remove(ele)
2976 delete(cl.m, pc)
2977 }
2978 }
2979
2980
2981 func (cl *connLRU) len() int {
2982 return len(cl.m)
2983 }
2984
View as plain text