func (r *RoundRobin) NextServer() (*url.URL, error) { srv, err := r.nextServer() if err != nil { return nil, err } return utils.CopyURL(srv.url), nil }
// In case if server is already present in the load balancer, returns error func (rr *RoundRobin) UpsertServer(u *url.URL, options ...ServerOption) error { rr.mutex.Lock() defer rr.mutex.Unlock() if u == nil { return fmt.Errorf("server URL can't be nil") } if s, _ := rr.findServerByURL(u); s != nil { for _, o := range options { if err := o(s); err != nil { return err } } rr.resetState() return nil } srv := &server{url: utils.CopyURL(u)} for _, o := range options { if err := o(srv); err != nil { return err } } if srv.weight == 0 { srv.weight = defaultWeight } rr.servers = append(rr.servers, srv) rr.resetState() return nil }
func (f *Forwarder) copyRequest(req *http.Request, u *url.URL) *http.Request { outReq := new(http.Request) *outReq = *req // includes shallow copies of maps, but we handle this below outReq.URL = utils.CopyURL(req.URL) outReq.URL.Scheme = u.Scheme outReq.URL.Host = u.Host outReq.URL.Opaque = req.RequestURI // raw query is already included in RequestURI, so ignore it to avoid dupes outReq.URL.RawQuery = "" // Do not pass client Host header unless optsetter PassHostHeader is set. if f.passHost != true { outReq.Host = u.Host } 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) utils.CopyHeaders(outReq.Header, req.Header) if f.rewriter != nil { f.rewriter.Rewrite(outReq) } return outReq }
func (s *Streamer) copyRequest(req *http.Request, body io.ReadCloser, bodySize int64) *http.Request { o := *req o.URL = utils.CopyURL(req.URL) o.Header = make(http.Header) utils.CopyHeaders(o.Header, req.Header) o.ContentLength = bodySize // remove TransferEncoding that could have been previously set because we have transformed the request from chunked encoding o.TransferEncoding = []string{} // http.Transport will close the request body on any error, we are controlling the close process ourselves, so we override the closer here o.Body = ioutil.NopCloser(body) return &o }
func (rb *Rebalancer) upsertServer(u *url.URL, weight int) error { if s, i := rb.findServer(u); i != -1 { s.origWeight = weight } meter, err := rb.newMeter() if err != nil { return err } rbSrv := &rbServer{ url: utils.CopyURL(u), origWeight: weight, curWeight: weight, meter: meter, } rb.servers = append(rb.servers, rbSrv) return nil }