func (p *proxy) ServeHTTP(responseWriter http.ResponseWriter, request *http.Request) { startedAt := time.Now() accessLog := access_log.AccessLogRecord{ Request: request, StartedAt: startedAt, } handler := NewRequestHandler(request, responseWriter, p.reporter, &accessLog) p.waitgroup.Add(1) defer func() { p.accessLogger.Log(accessLog) p.waitgroup.Done() }() if !isProtocolSupported(request) { handler.HandleUnsupportedProtocol() return } if isLoadBalancerHeartbeat(request) { handler.HandleHeartbeat() return } routePool := p.lookup(request) if routePool == nil { p.reporter.CaptureBadRequest(request) handler.HandleMissingRoute() return } stickyEndpointId := p.getStickySession(request) iter := &wrappedIterator{ nested: routePool.Endpoints(stickyEndpointId), afterNext: func(endpoint *route.Endpoint) { if endpoint != nil { handler.logger.Set("RouteEndpoint", endpoint.ToLogData()) accessLog.RouteEndpoint = endpoint p.reporter.CaptureRoutingRequest(endpoint, request) } }, } if isTcpUpgrade(request) { handler.HandleTcpRequest(iter) return } if isWebSocketUpgrade(request) { handler.HandleWebSocketRequest(iter) return } proxyWriter := newProxyResponseWriter(responseWriter) roundTripper := &proxyRoundTripper{ transport: p.transport, iter: iter, handler: &handler, after: func(rsp *http.Response, endpoint *route.Endpoint, err error) { accessLog.FirstByteAt = time.Now() if rsp != nil { accessLog.StatusCode = rsp.StatusCode } // disable keep-alives -- not needed with Go 1.3 responseWriter.Header().Set("Connection", "close") if p.traceKey != "" && request.Header.Get(router_http.VcapTraceHeader) == p.traceKey { setTraceHeaders(responseWriter, p.ip, endpoint.CanonicalAddr()) } latency := time.Since(startedAt) p.reporter.CaptureRoutingResponse(endpoint, rsp, startedAt, latency) if err != nil { p.reporter.CaptureBadGateway(request) handler.HandleBadGateway(err) proxyWriter.Done() return } if endpoint.PrivateInstanceId != "" { setupStickySession(responseWriter, rsp, endpoint) } }, } proxyTransport := autowire.InstrumentedRoundTripper(roundTripper) p.newReverseProxy(proxyTransport, request).ServeHTTP(proxyWriter, request) accessLog.FinishedAt = time.Now() accessLog.BodyBytesSent = int64(proxyWriter.Size()) }
It("returns the given Handler with no changes", func() { os.Setenv("DROPSONDE_ORIGIN", "") fake := FakeHandler{} autowire.Initialize() Expect(autowire.InstrumentedHandler(fake)).To(Equal(fake)) }) }) Describe("InstrumentedRoundTripper", func() { It("returns the given RoundTripper with no changes", func() { fake := FakeRoundTripper{} os.Setenv("DROPSONDE_ORIGIN", "") autowire.Initialize() Expect(autowire.InstrumentedRoundTripper(fake)).To(Equal(fake)) }) }) }) }) type FakeHandler struct{} func (fh FakeHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) {} type FakeRoundTripper struct{} func (frt FakeRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { return nil, nil }