Err: errors.New("error"), Op: "dial", } after round_tripper.AfterRoundTrip ) BeforeEach(func() { endpointIterator = &routefakes.FakeEndpointIterator{} req = test_util.NewRequest("GET", "myapp.com", "/", nil) req.URL.Scheme = "http" resp = &proxyfakes.FakeProxyResponseWriter{} nullVarz := test_helpers.NullVarz{} nullAccessRecord := &schema.AccessLogRecord{} logger = lagertest.NewTestLogger("test") handler = reqhandler.NewRequestHandler(req, resp, nullVarz, nullAccessRecord, logger) transport = &roundtripperfakes.FakeRoundTripper{} after = func(rsp *http.Response, endpoint *route.Endpoint, err error) { Expect(endpoint.Tags).ShouldNot(BeNil()) } }) Context("backend", func() { BeforeEach(func() { endpoint := &route.Endpoint{ Tags: map[string]string{}, } endpointIterator.NextReturns(endpoint)
func (p *proxy) ServeHTTP(responseWriter http.ResponseWriter, request *http.Request) { startedAt := time.Now() accessLog := schema.AccessLogRecord{ Request: request, StartedAt: startedAt, ExtraHeadersToLog: p.extraHeadersToLog, } requestBodyCounter := &countingReadCloser{delegate: request.Body} request.Body = requestBodyCounter proxyWriter := utils.NewProxyResponseWriter(responseWriter) handler := handler.NewRequestHandler(request, proxyWriter, p.reporter, &accessLog, p.logger) defer func() { accessLog.RequestBytesReceived = requestBodyCounter.GetCount() p.accessLogger.Log(accessLog) }() if !isProtocolSupported(request) { handler.HandleUnsupportedProtocol() return } if isLoadBalancerHeartbeat(request) { handler.HandleHeartbeat(atomic.LoadInt32(&p.heartbeatOK) != 0) 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.AddLoggingData(lager.Data{"route-endpoint": endpoint.ToLogData()}) accessLog.RouteEndpoint = endpoint p.reporter.CaptureRoutingRequest(endpoint, request) } }, } if isTcpUpgrade(request) { handler.HandleTcpRequest(iter) accessLog.FinishedAt = time.Now() return } if isWebSocketUpgrade(request) { handler.HandleWebSocketRequest(iter) accessLog.FinishedAt = time.Now() return } backend := true routeServiceUrl := routePool.RouteServiceUrl() // Attempted to use a route service when it is not supported if routeServiceUrl != "" && !p.routeServiceConfig.RouteServiceEnabled() { handler.HandleUnsupportedRouteService() return } var routeServiceArgs route_service.RouteServiceArgs if routeServiceUrl != "" { rsSignature := request.Header.Get(route_service.RouteServiceSignature) var recommendedScheme string if p.routeServiceRecommendHttps { recommendedScheme = "https" } else { recommendedScheme = "http" } forwardedUrlRaw := recommendedScheme + "://" + hostWithoutPort(request) + request.RequestURI if hasBeenToRouteService(routeServiceUrl, rsSignature) { // A request from a route service destined for a backend instances routeServiceArgs.UrlString = routeServiceUrl err := p.routeServiceConfig.ValidateSignature(&request.Header, forwardedUrlRaw) if err != nil { handler.HandleBadSignature(err) return } } else { var err error // should not hardcode http, will be addressed by #100982038 routeServiceArgs, err = buildRouteServiceArgs(p.routeServiceConfig, routeServiceUrl, forwardedUrlRaw) backend = false if err != nil { handler.HandleRouteServiceFailure(err) return } } } after := func(rsp *http.Response, endpoint *route.Endpoint, err error) { accessLog.FirstByteAt = time.Now() if rsp != nil { accessLog.StatusCode = rsp.StatusCode } 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, request) return } if endpoint.PrivateInstanceId != "" { setupStickySession(responseWriter, rsp, endpoint, stickyEndpointId, p.secureCookies, routePool.ContextPath()) } // if Content-Type not in response, nil out to suppress Go's auto-detect if _, ok := rsp.Header["Content-Type"]; !ok { responseWriter.Header()["Content-Type"] = nil } } roundTripper := round_tripper.NewProxyRoundTripper(backend, dropsonde.InstrumentedRoundTripper(p.transport), iter, handler, after) newReverseProxy(roundTripper, request, routeServiceArgs, p.routeServiceConfig).ServeHTTP(proxyWriter, request) accessLog.FinishedAt = time.Now() accessLog.BodyBytesSent = proxyWriter.Size() }