func (s *Splitter) performSinkRequest(ctx context.Context, req *http.Request, sink config.Sink) (*httputils.RequestResponse, error) { result := httputils.NewRequestResponse(req, nil) // swap in sink address req.URL.Host = sink.Addr // assume "http" if no scheme is present if req.URL.Scheme == "" { req.URL.Scheme = "http" } resp, err := s.Client.Do(req) if err != nil { return nil, err } result.Response, err = httputils.NewRawResponse(resp) return result, err }
// ServeHTTP satisfies the net/http.Handler interface func (s *Splitter) ServeHTTP(rw http.ResponseWriter, r *http.Request) { teeRW := httputils.NewTeeResponseWriter(rw) r2, err := httputils.CopyRequest(r) // on request copy error attempt and early exit (which may be invalid, unfortunately) if err != nil { log.Println("splitter: error copying request:", err) s.upstreamProxy.ServeHTTP(teeRW, r) return } reqresp := httputils.NewRequestResponse(r2, teeRW) defer reqresp.MarkDone() select { case s.requests <- reqresp: default: log.Println("splitter: dropped request on the floor") } s.upstreamProxy.ServeHTTP(teeRW, r) }