// Proxy the request to the given endpoint, execute observers and middlewares chains func (l *HttpLocation) proxyToEndpoint(tr *http.Transport, o *Options, endpoint endpoint.Endpoint, req request.Request) (*http.Response, error) { a := &request.BaseAttempt{Endpoint: endpoint} l.observerChain.ObserveRequest(req) defer l.observerChain.ObserveResponse(req, a) defer req.AddAttempt(a) it := l.middlewareChain.GetIter() defer l.unwindIter(it, req, a) for v := it.Next(); v != nil; v = it.Next() { a.Response, a.Error = v.ProcessRequest(req) if a.Response != nil || a.Error != nil { // Move the iterator forward to count it again once we unwind the chain it.Next() log.Errorf("Midleware intercepted request with response=%s, error=%s", a.Response.Status, a.Error) return a.Response, a.Error } } // Forward the request and mirror the response start := o.TimeProvider.UtcNow() a.Response, a.Error = tr.RoundTrip(req.GetHttpRequest()) a.Duration = o.TimeProvider.UtcNow().Sub(start) return a.Response, a.Error }