func (c *Consumer) tryWebsocketConnection(path, token string) (*websocket.Conn, *httpError) { header := http.Header{"Origin": []string{"http://localhost"}, "Authorization": []string{token}} URL := c.trafficControllerUrl + path c.debugPrinter.Print("WEBSOCKET REQUEST:", "GET "+path+" HTTP/1.1\n"+ "Host: "+c.trafficControllerUrl+"\n"+ "Upgrade: websocket\nConnection: Upgrade\nSec-WebSocket-Version: 13\nSec-WebSocket-Key: [HIDDEN]\n"+ headersString(header)) ws, resp, err := c.dialer.Dial(URL, header) if resp != nil { c.debugPrinter.Print("WEBSOCKET RESPONSE:", resp.Proto+" "+resp.Status+"\n"+ headersString(resp.Header)) } httpErr := &httpError{} if resp != nil { if resp.StatusCode == http.StatusUnauthorized { bodyData, _ := ioutil.ReadAll(resp.Body) err = noaa_errors.NewUnauthorizedError(string(bodyData)) } httpErr.statusCode = resp.StatusCode } if err != nil { errMsg := "Error dialing trafficcontroller server: %s.\n" + "Please ask your Cloud Foundry Operator to check the platform configuration (trafficcontroller is %s)." httpErr.error = fmt.Errorf(errMsg, err.Error(), c.trafficControllerUrl) return nil, httpErr } return ws, nil }
func (c *Consumer) establishWebsocketConnection(path string, authToken string) (*websocket.Conn, error) { header := http.Header{"Origin": []string{"http://localhost"}, "Authorization": []string{authToken}} url := c.trafficControllerUrl + path c.debugPrinter.Print("WEBSOCKET REQUEST:", "GET "+path+" HTTP/1.1\n"+ "Host: "+c.trafficControllerUrl+"\n"+ "Upgrade: websocket\nConnection: Upgrade\nSec-WebSocket-Version: 13\nSec-WebSocket-Key: [HIDDEN]\n"+ headersString(header)) ws, resp, err := c.dialer.Dial(url, header) if resp != nil { c.debugPrinter.Print("WEBSOCKET RESPONSE:", resp.Proto+" "+resp.Status+"\n"+ headersString(resp.Header)) } if resp != nil && resp.StatusCode == http.StatusUnauthorized { bodyData, _ := ioutil.ReadAll(resp.Body) err = noaa_errors.NewUnauthorizedError(string(bodyData)) return ws, err } callback := c.onConnectCallback() if err == nil && callback != nil { callback() } if err != nil { return nil, errors.New(fmt.Sprintf("Error dialing traffic controller server: %s.\nPlease ask your Cloud Foundry Operator to check the platform configuration (traffic controller is %s).", err.Error(), c.trafficControllerUrl)) } return ws, err }
func checkForErrors(resp *http.Response) error { if resp.StatusCode == http.StatusUnauthorized { data, _ := ioutil.ReadAll(resp.Body) return noaa_errors.NewUnauthorizedError(string(data)) } if resp.StatusCode == http.StatusBadRequest { return ErrBadRequest } if resp.StatusCode != http.StatusOK { return ErrNotOK } return nil }
func (cnsmr *consumer) establishWebsocketConnection(path string, authToken string) (*websocket.Conn, error) { header := http.Header{"Origin": []string{"http://localhost"}, "Authorization": []string{authToken}} dialer := websocket.Dialer{HandshakeTimeout: handshakeTimeout, NetDial: cnsmr.proxyDial, TLSClientConfig: cnsmr.tlsConfig} url := cnsmr.endpoint + path cnsmr.debugPrinter.Print("WEBSOCKET REQUEST:", "GET "+path+" HTTP/1.1\n"+ "Host: "+cnsmr.endpoint+"\n"+ "Upgrade: websocket\nConnection: Upgrade\nSec-WebSocket-Version: 13\nSec-WebSocket-Key: [HIDDEN]\n"+ headersString(header)) ws, resp, err := dialer.Dial(url, header) if resp != nil { cnsmr.debugPrinter.Print("WEBSOCKET RESPONSE:", resp.Proto+" "+resp.Status+"\n"+ headersString(resp.Header)) } if resp != nil && resp.StatusCode == http.StatusUnauthorized { bodyData, _ := ioutil.ReadAll(resp.Body) err = noaa_errors.NewUnauthorizedError(string(bodyData)) return ws, err } if err == nil && cnsmr.callback != nil { cnsmr.callback() } if err != nil { return nil, errors.New(fmt.Sprintf("Error dialing loggregator server: %s.\nPlease ask your Cloud Foundry Operator to check the platform configuration (loggregator endpoint is %s).", err.Error(), cnsmr.endpoint)) } return ws, err }
func checkForErrors(resp *http.Response) *httpError { if resp.StatusCode == http.StatusUnauthorized { data, _ := ioutil.ReadAll(resp.Body) return &httpError{ statusCode: resp.StatusCode, error: noaa_errors.NewUnauthorizedError(string(data)), } } if resp.StatusCode == http.StatusBadRequest { return &httpError{ statusCode: resp.StatusCode, error: ErrBadRequest, } } if resp.StatusCode != http.StatusOK { return &httpError{ statusCode: resp.StatusCode, error: ErrNotOK, } } return nil }
BeforeEach(func() { fakeNoaaConsumer = &testapi.FakeNoaaConsumer{} config = testconfig.NewRepositoryWithDefaults() config.SetLoggregatorEndpoint("loggregator.test.com") config.SetDopplerEndpoint("doppler.test.com") config.SetAccessToken("the-access-token") fakeTokenRefresher = &testapi.FakeAuthenticationRepository{} repo = api.NewLogsNoaaRepository(config, fakeNoaaConsumer, fakeTokenRefresher) }) Describe("RecentLogsFor", func() { It("refreshes token and get metric once more if token has expired.", func() { fakeNoaaConsumer.RecentLogsReturns([]*events.LogMessage{}, noaa_errors.NewUnauthorizedError("Unauthorized token")) repo.RecentLogsFor("app-guid") Ω(fakeTokenRefresher.RefreshTokenCalled).To(BeTrue()) Ω(fakeNoaaConsumer.RecentLogsCallCount()).To(Equal(2)) }) It("refreshes token and get metric once more if token has expired.", func() { fakeNoaaConsumer.RecentLogsReturns([]*events.LogMessage{}, errors.New("error error error")) _, err := repo.RecentLogsFor("app-guid") Ω(err).To(HaveOccurred()) Ω(err.Error()).To(Equal("error error error")) }) Context("when an error does not occur", func() {
}) JustBeforeEach(func() { logsRepo = NewLoggregatorLogsRepository(configRepo, fakeConsumer, authRepo) }) Describe("RecentLogsFor", func() { Context("when a noaa_errors.UnauthorizedError occurs", func() { var recentCalled bool BeforeEach(func() { fakeConsumer.RecentStub = func(string, string) ([]*logmessage.LogMessage, error) { if recentCalled { return nil, nil } recentCalled = true return nil, noaa_errors.NewUnauthorizedError("i'm sorry dave") } }) It("refreshes the access token", func() { _, err := logsRepo.RecentLogsFor("app-guid") Expect(err).ToNot(HaveOccurred()) Expect(authRepo.RefreshAuthTokenCallCount()).To(Equal(1)) }) }) Context("when an error occurs", func() { BeforeEach(func() { fakeConsumer.RecentReturns(nil, errors.New("oops")) })
/* httpRecent connects to loggregator via its 'recent' http(s) endpoint and returns a slice of recent messages. It does not guarantee any order of the messages; they are in the order returned by loggregator. */ func (cnsmr *consumer) httpRecent(appGuid string, authToken string) ([]*logmessage.LogMessage, error) { endpointUrl, err := url.ParseRequestURI(cnsmr.endpoint) if err != nil { return nil, err } scheme := "https" if endpointUrl.Scheme == "ws" { scheme = "http" } recentPath := fmt.Sprintf("%s://%s/recent?app=%s", scheme, endpointUrl.Host, appGuid) transport := &http.Transport{Proxy: cnsmr.proxy, TLSClientConfig: cnsmr.tlsConfig, TLSHandshakeTimeout: handshakeTimeout} client := &http.Client{Timeout: handshakeTimeout, Transport: transport} req, _ := http.NewRequest("GET", recentPath, nil) req.Header.Set("Authorization", authToken) resp, err := client.Do(req) if err != nil { return nil, errors.New(fmt.Sprintf("Error dialing loggregator server: %s.\nPlease ask your Cloud Foundry Operator to check the platform configuration (loggregator endpoint is %s).", err.Error(), cnsmr.endpoint)) } defer resp.Body.Close() if resp.StatusCode == http.StatusUnauthorized { data, _ := ioutil.ReadAll(resp.Body) return nil, noaa_errors.NewUnauthorizedError(string(data)) } if resp.StatusCode == http.StatusBadRequest { return nil, ErrBadRequest } if resp.StatusCode != http.StatusOK { return nil, ErrNotFound } contentType := resp.Header.Get("Content-Type") if len(strings.TrimSpace(contentType)) == 0 { return nil, ErrBadResponse } matches := boundaryRegexp.FindStringSubmatch(contentType) if len(matches) != 2 || len(strings.TrimSpace(matches[1])) == 0 { return nil, ErrBadResponse } reader := multipart.NewReader(resp.Body, matches[1]) var buffer bytes.Buffer messages := make([]*logmessage.LogMessage, 0, 200) for part, loopErr := reader.NextPart(); loopErr == nil; part, loopErr = reader.NextPart() { buffer.Reset() msg := new(logmessage.LogMessage) _, err := buffer.ReadFrom(part) if err != nil { break } proto.Unmarshal(buffer.Bytes(), msg) messages = append(messages, msg) } return messages, err }
config.SetAccessToken("the-access-token") fakeTokenRefresher = &authenticationfakes.FakeRepository{} repo = logs.NewNoaaLogsRepository(config, fakeNoaaConsumer, fakeTokenRefresher) }) Describe("RecentLogsFor", func() { It("refreshes token and get metric once more if token has expired.", func() { var recentLogsCallCount int fakeNoaaConsumer.RecentLogsStub = func(appGuid, authToken string) ([]*events.LogMessage, error) { defer func() { recentLogsCallCount += 1 }() if recentLogsCallCount == 0 { return []*events.LogMessage{}, noaa_errors.NewUnauthorizedError("Unauthorized token") } return []*events.LogMessage{}, nil } repo.RecentLogsFor("app-guid") Expect(fakeTokenRefresher.RefreshAuthTokenCallCount()).To(Equal(1)) Expect(fakeNoaaConsumer.RecentLogsCallCount()).To(Equal(2)) }) It("refreshes token and get metric once more if token has expired.", func() { fakeNoaaConsumer.RecentLogsReturns([]*events.LogMessage{}, errors.New("error error error")) _, err := repo.RecentLogsFor("app-guid") Expect(err).To(HaveOccurred())