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  })