code.cloudfoundry.org/cli@v7.1.0+incompatible/cf/net/http_client_test.go (about) 1 package net_test 2 3 import ( 4 "crypto/x509" 5 "net" 6 "net/http" 7 "net/url" 8 "syscall" 9 10 "code.cloudfoundry.org/cli/cf/errors" 11 . "code.cloudfoundry.org/cli/cf/net" 12 "code.cloudfoundry.org/cli/cf/trace/tracefakes" 13 . "github.com/onsi/ginkgo" 14 . "github.com/onsi/gomega" 15 "golang.org/x/net/websocket" 16 ) 17 18 var _ = Describe("HTTP Client", func() { 19 var ( 20 client HTTPClientInterface 21 dumper RequestDumper 22 fakePrinter *tracefakes.FakePrinter 23 ) 24 25 BeforeEach(func() { 26 fakePrinter = new(tracefakes.FakePrinter) 27 dumper = NewRequestDumper(fakePrinter) 28 client = NewHTTPClient(&http.Transport{}, dumper) 29 }) 30 31 Describe("ExecuteCheckRedirect", func() { 32 It("transfers original headers", func() { 33 originalReq, err := http.NewRequest("GET", "http://local.com/foo", nil) 34 Expect(err).NotTo(HaveOccurred()) 35 originalReq.Header.Set("Authorization", "my-auth-token") 36 originalReq.Header.Set("Accept", "application/json") 37 38 redirectReq, err := http.NewRequest("GET", "http://local.com/bar", nil) 39 Expect(err).NotTo(HaveOccurred()) 40 41 via := []*http.Request{originalReq} 42 43 err = client.ExecuteCheckRedirect(redirectReq, via) 44 45 Expect(err).NotTo(HaveOccurred()) 46 Expect(redirectReq.Header.Get("Authorization")).To(Equal("my-auth-token")) 47 Expect(redirectReq.Header.Get("Accept")).To(Equal("application/json")) 48 }) 49 50 It("does not transfer 'Authorization' headers during a redirect to different Host", func() { 51 originalReq, err := http.NewRequest("GET", "http://www.local.com/foo", nil) 52 Expect(err).NotTo(HaveOccurred()) 53 originalReq.Header.Set("Authorization", "my-auth-token") 54 originalReq.Header.Set("Accept", "application/json") 55 56 redirectReq, err := http.NewRequest("GET", "http://www.remote.com/bar", nil) 57 Expect(err).NotTo(HaveOccurred()) 58 59 via := []*http.Request{originalReq} 60 61 err = client.ExecuteCheckRedirect(redirectReq, via) 62 63 Expect(err).NotTo(HaveOccurred()) 64 Expect(redirectReq.Header.Get("Authorization")).To(Equal("")) 65 Expect(redirectReq.Header.Get("Accept")).To(Equal("application/json")) 66 }) 67 68 It("does not transfer POST-specific headers", func() { 69 originalReq, err := http.NewRequest("POST", "http://local.com/foo", nil) 70 Expect(err).NotTo(HaveOccurred()) 71 originalReq.Header.Set("Content-Type", "application/json") 72 originalReq.Header.Set("Content-Length", "100") 73 74 redirectReq, err := http.NewRequest("GET", "http://local.com/bar", nil) 75 Expect(err).NotTo(HaveOccurred()) 76 77 via := []*http.Request{originalReq} 78 79 err = client.ExecuteCheckRedirect(redirectReq, via) 80 81 Expect(err).NotTo(HaveOccurred()) 82 Expect(redirectReq.Header.Get("Content-Type")).To(Equal("")) 83 Expect(redirectReq.Header.Get("Content-Length")).To(Equal("")) 84 }) 85 86 It("fails after one redirect", func() { 87 firstReq, err := http.NewRequest("GET", "http://local.com/foo", nil) 88 Expect(err).NotTo(HaveOccurred()) 89 90 secondReq, err := http.NewRequest("GET", "http://local.com/manchu", nil) 91 Expect(err).NotTo(HaveOccurred()) 92 93 redirectReq, err := http.NewRequest("GET", "http://local.com/bar", nil) 94 redirectReq.Header["Referer"] = []string{"http://local.com"} 95 Expect(err).NotTo(HaveOccurred()) 96 97 via := []*http.Request{firstReq, secondReq} 98 99 err = client.ExecuteCheckRedirect(redirectReq, via) 100 101 Expect(err).To(HaveOccurred()) 102 }) 103 }) 104 105 Describe("WrapNetworkErrors", func() { 106 It("replaces http unknown authority errors with InvalidSSLCert errors", func() { 107 err, ok := WrapNetworkErrors("example.com", &url.Error{Err: x509.UnknownAuthorityError{}}).(*errors.InvalidSSLCert) 108 Expect(ok).To(BeTrue()) 109 Expect(err).To(HaveOccurred()) 110 }) 111 112 It("replaces http hostname errors with InvalidSSLCert errors", func() { 113 err, ok := WrapNetworkErrors("example.com", &url.Error{Err: x509.HostnameError{}}).(*errors.InvalidSSLCert) 114 Expect(ok).To(BeTrue()) 115 Expect(err).To(HaveOccurred()) 116 }) 117 118 It("replaces http certificate invalid errors with InvalidSSLCert errors", func() { 119 err, ok := WrapNetworkErrors("example.com", &url.Error{Err: x509.CertificateInvalidError{}}).(*errors.InvalidSSLCert) 120 Expect(ok).To(BeTrue()) 121 Expect(err).To(HaveOccurred()) 122 }) 123 124 It("replaces websocket unknown authority errors with InvalidSSLCert errors", func() { 125 err, ok := WrapNetworkErrors("example.com", &websocket.DialError{Err: x509.UnknownAuthorityError{}}).(*errors.InvalidSSLCert) 126 Expect(ok).To(BeTrue()) 127 Expect(err).To(HaveOccurred()) 128 }) 129 130 It("replaces websocket hostname with InvalidSSLCert errors", func() { 131 err, ok := WrapNetworkErrors("example.com", &websocket.DialError{Err: x509.HostnameError{}}).(*errors.InvalidSSLCert) 132 Expect(ok).To(BeTrue()) 133 Expect(err).To(HaveOccurred()) 134 }) 135 136 It("replaces http websocket certificate invalid errors with InvalidSSLCert errors", func() { 137 err, ok := WrapNetworkErrors("example.com", &websocket.DialError{Err: x509.CertificateInvalidError{}}).(*errors.InvalidSSLCert) 138 Expect(ok).To(BeTrue()) 139 Expect(err).To(HaveOccurred()) 140 }) 141 142 It("provides a nice message for connection errors", func() { 143 underlyingErr := syscall.Errno(61) 144 err := WrapNetworkErrors("example.com", &url.Error{Err: &net.OpError{Err: underlyingErr}}) 145 Expect(err.Error()).To(ContainSubstring("Error performing request")) 146 }) 147 148 It("wraps other errors in a generic error type", func() { 149 err := WrapNetworkErrors("example.com", errors.New("whatever")) 150 Expect(err).To(HaveOccurred()) 151 152 _, ok := err.(*errors.InvalidSSLCert) 153 Expect(ok).To(BeFalse()) 154 }) 155 156 It("returns an error with a tip when it is a tcp dial error", func() { 157 err := WrapNetworkErrors("example.com", &url.Error{Err: &net.OpError{Op: "dial", Net: "tcp", Err: errors.New("tcp-dial-error")}}) 158 Expect(err).To(HaveOccurred()) 159 Expect(err.Error()).To(ContainSubstring("TIP: If you are behind a firewall and require an HTTP proxy, verify the https_proxy environment variable is correctly set. Else, check your network connection.")) 160 }) 161 162 It("does not return an error with a tip when it is not a network error", func() { 163 err := WrapNetworkErrors("example.com", errors.New("an-error")) 164 Expect(err).To(HaveOccurred()) 165 Expect(err.Error()).To(Not(ContainSubstring("TIP: If you are behind a firewall and require an HTTP proxy, verify the https_proxy environment variable is correctly set. Else, check your network connection."))) 166 }) 167 }) 168 })