func buildRouteServiceArgs(routeServiceConfig *route_service.RouteServiceConfig, routeServiceUrl, forwardedUrlRaw string) (route_service.RouteServiceArgs, error) { var routeServiceArgs route_service.RouteServiceArgs sig, metadata, err := routeServiceConfig.GenerateSignatureAndMetadata(forwardedUrlRaw) if err != nil { return routeServiceArgs, err } routeServiceArgs.UrlString = routeServiceUrl routeServiceArgs.Signature = sig routeServiceArgs.Metadata = metadata routeServiceArgs.ForwardedUrlRaw = forwardedUrlRaw rsURL, err := url.Parse(routeServiceUrl) if err != nil { return routeServiceArgs, err } routeServiceArgs.ParsedUrl = rsURL return routeServiceArgs, nil }
func (p *proxy) ServeHTTP(responseWriter http.ResponseWriter, request *http.Request) { startedAt := time.Now() accessLog := access_log.AccessLogRecord{ Request: request, StartedAt: startedAt, ExtraHeadersToLog: p.ExtraHeadersToLog, } requestBodyCounter := &countingReadCloser{delegate: request.Body} request.Body = requestBodyCounter proxyWriter := NewProxyResponseWriter(responseWriter) handler := NewRequestHandler(request, proxyWriter, p.reporter, &accessLog) defer func() { accessLog.RequestBytesReceived = requestBodyCounter.count p.accessLogger.Log(accessLog) }() 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) 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) forwardedUrlRaw := "http" + "://" + request.Host + 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) return } if endpoint.PrivateInstanceId != "" { setupStickySession(responseWriter, rsp, endpoint, stickyEndpointId, p.secureCookies, routePool.ContextPath()) } } roundTripper := 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() }