github.com/timstclair/heapster@v0.20.0-alpha1/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/http.go (about) 1 /* 2 Copyright 2014 The Kubernetes Authors All rights reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package util 18 19 import ( 20 "crypto/tls" 21 "fmt" 22 "io" 23 "net" 24 "net/http" 25 "net/url" 26 "strings" 27 ) 28 29 // IsProbableEOF returns true if the given error resembles a connection termination 30 // scenario that would justify assuming that the watch is empty. 31 // These errors are what the Go http stack returns back to us which are general 32 // connection closure errors (strongly correlated) and callers that need to 33 // differentiate probable errors in connection behavior between normal "this is 34 // disconnected" should use the method. 35 func IsProbableEOF(err error) bool { 36 if uerr, ok := err.(*url.Error); ok { 37 err = uerr.Err 38 } 39 switch { 40 case err == io.EOF: 41 return true 42 case err.Error() == "http: can't write HTTP request on broken connection": 43 return true 44 case strings.Contains(err.Error(), "connection reset by peer"): 45 return true 46 case strings.Contains(strings.ToLower(err.Error()), "use of closed network connection"): 47 return true 48 } 49 return false 50 } 51 52 var defaultTransport = http.DefaultTransport.(*http.Transport) 53 54 // SetTransportDefaults applies the defaults from http.DefaultTransport 55 // for the Proxy, Dial, and TLSHandshakeTimeout fields if unset 56 func SetTransportDefaults(t *http.Transport) *http.Transport { 57 if t.Proxy == nil { 58 t.Proxy = defaultTransport.Proxy 59 } 60 if t.Dial == nil { 61 t.Dial = defaultTransport.Dial 62 } 63 if t.TLSHandshakeTimeout == 0 { 64 t.TLSHandshakeTimeout = defaultTransport.TLSHandshakeTimeout 65 } 66 return t 67 } 68 69 type RoundTripperWrapper interface { 70 http.RoundTripper 71 WrappedRoundTripper() http.RoundTripper 72 } 73 74 type DialFunc func(net, addr string) (net.Conn, error) 75 76 func Dialer(transport http.RoundTripper) (DialFunc, error) { 77 if transport == nil { 78 return nil, nil 79 } 80 81 switch transport := transport.(type) { 82 case *http.Transport: 83 return transport.Dial, nil 84 case RoundTripperWrapper: 85 return Dialer(transport.WrappedRoundTripper()) 86 default: 87 return nil, fmt.Errorf("unknown transport type: %v", transport) 88 } 89 } 90 91 func TLSClientConfig(transport http.RoundTripper) (*tls.Config, error) { 92 if transport == nil { 93 return nil, nil 94 } 95 96 switch transport := transport.(type) { 97 case *http.Transport: 98 return transport.TLSClientConfig, nil 99 case RoundTripperWrapper: 100 return TLSClientConfig(transport.WrappedRoundTripper()) 101 default: 102 return nil, fmt.Errorf("unknown transport type: %v", transport) 103 } 104 }