func (l *HttpLocation) copyRequest(req *http.Request, body netutils.MultiReader, endpoint endpoint.Endpoint) *http.Request { outReq := new(http.Request) *outReq = *req // includes shallow copies of maps, but we handle this below // Set the body to the enhanced body that can be re-read multiple times and buffered to disk outReq.Body = body endpointURL := endpoint.GetUrl() outReq.URL.Scheme = endpointURL.Scheme outReq.URL.Host = endpointURL.Host // workaround for https://github.com/golang/go/issues/10433 outReq.URL.Opaque = mergeStartingSlashes(req.RequestURI) // raw query is already included in RequestURI, so ignore it to avoid dupes outReq.URL.RawQuery = "" outReq.Proto = "HTTP/1.1" outReq.ProtoMajor = 1 outReq.ProtoMinor = 1 // Overwrite close flag so we can keep persistent connection for the backend servers outReq.Close = false outReq.Header = make(http.Header) netutils.CopyHeaders(outReq.Header, req.Header) return outReq }
func (w *WebhookSideEffect) Exec() error { r, err := http.NewRequest(w.w.Method, w.w.URL, w.getBody()) if err != nil { return err } if len(w.w.Headers) != 0 { netutils.CopyHeaders(r.Header, w.w.Headers) } if len(w.w.Form) != 0 { r.Header.Set("Content-Type", "application/x-www-form-urlencoded") } re, err := http.DefaultClient.Do(r) if err != nil { return err } if re.Body != nil { defer re.Body.Close() } body, err := ioutil.ReadAll(re.Body) if err != nil { return err } log.Infof("%v got response: (%s): %s", w, re.Status, string(body)) return nil }
// Round trips the request to the selected location and writes back the response func (p *Proxy) proxyRequest(w http.ResponseWriter, r *http.Request) error { // Create a unique request with sequential ids that will be passed to all interfaces. req := request.NewBaseRequest(r, atomic.AddInt64(&p.lastRequestId, 1), nil) location, err := p.router.Route(req) if err != nil { return err } // Router could not find a matching location, we can do nothing else. if location == nil { log.Errorf("%s failed to route", req) return errors.FromStatus(http.StatusBadGateway) } response, err := location.RoundTrip(req) if response != nil { netutils.CopyHeaders(w.Header(), response.Header) w.WriteHeader(response.StatusCode) io.Copy(w, response.Body) response.Body.Close() return nil } else { return err } }
func (tb *Recorder) ObserveRequest(req Request) { tb.mutex.Lock() defer tb.mutex.Unlock() if len(tb.Header) != 0 { netutils.CopyHeaders(req.GetHttpRequest().Header, tb.Header) } tb.ProcessedRequests = append(tb.ProcessedRequests, req) }
// replyError is a helper function that takes error and replies with HTTP compatible error to the client. func (p *Proxy) replyError(err error, w http.ResponseWriter, req *http.Request) { proxyError := convertError(err) statusCode, body, contentType := p.options.ErrorFormatter.Format(proxyError) w.Header().Set("Content-Type", contentType) if proxyError.Headers() != nil { netutils.CopyHeaders(w.Header(), proxyError.Headers()) } w.WriteHeader(statusCode) w.Write(body) }
func (tb *Recorder) ProcessRequest(req Request) (*http.Response, error) { tb.mutex.Lock() defer tb.mutex.Unlock() if len(tb.Header) != 0 { netutils.CopyHeaders(req.GetHttpRequest().Header, tb.Header) } tb.ProcessedRequests = append(tb.ProcessedRequests, req) return tb.Response, tb.Error }
func (tb *Recorder) ObserveResponse(req Request, a Attempt) { tb.mutex.Lock() defer tb.mutex.Unlock() if len(tb.Header) != 0 { netutils.CopyHeaders(req.GetHttpRequest().Header, tb.Header) } tb.ProcessedResponses = append(tb.ProcessedResponses, struct { R Request A Attempt }{R: req, A: a}) }
func MakeRequest(url string, opts Opts) (*http.Response, []byte, error) { method := "GET" if opts.Method != "" { method = opts.Method } request, _ := http.NewRequest(method, url, strings.NewReader(opts.Body)) if opts.Headers != nil { netutils.CopyHeaders(request.Header, opts.Headers) } if len(opts.Host) != 0 { request.Host = opts.Host } var tr *http.Transport if strings.HasPrefix(url, "https") { tr = &http.Transport{ DisableKeepAlives: true, TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } } else { tr = &http.Transport{ DisableKeepAlives: true, } } client := &http.Client{ Transport: tr, CheckRedirect: func(req *http.Request, via []*http.Request) error { return fmt.Errorf("No redirects") }, } response, err := client.Do(request) if err == nil { bodyBytes, err := ioutil.ReadAll(response.Body) return response, bodyBytes, err } return response, nil, err }