23
"io"
24
"net"
25
"net/http"
26
+ "net/textproto"
27
"net/url"
28
"regexp"
29
"strconv"
81
// Upstreams is the list of backends to proxy to.
82
Upstreams UpstreamPool `json:"upstreams,omitempty"`
83
83
- // Adjusts how often to flush the response buffer. A
84
- // negative value disables response buffering.
85
- // TODO: figure out good defaults and write docs for this
86
- // (see https://github.com/caddyserver/caddy/issues/1460)
84
+ // Adjusts how often to flush the response buffer. By default,
85
+ // no periodic flushing is done. A negative value disables
86
+ // response buffering, and flushes immediately after each
87
+ // write to the client. This option is ignored when the upstream's
88
+ // response is recognized as a streaming response, or if its
89
+ // content length is -1; for such responses, writes are flushed
90
+ // to the client immediately.
91
FlushInterval caddy.Duration `json:"flush_interval,omitempty"`
92
93
// Headers manipulates headers between Caddy and the backend.
532
// If we aren't the first proxy retain prior
533
// X-Forwarded-For information as a comma+space
534
// separated list and fold multiple headers into one.
531
- if prior, ok := req.Header["X-Forwarded-For"]; ok {
535
+ prior, ok := req.Header["X-Forwarded-For"]
536
+ omit := ok && prior == nil // Issue 38079: nil now means don't populate the header
537
+ if len(prior) > 0 {
538
clientIP = strings.Join(prior, ", ") + ", " + clientIP
539
}
534
- req.Header.Set("X-Forwarded-For", clientIP)
540
+ if !omit {
541
+ req.Header.Set("X-Forwarded-For", clientIP)
542
+ }
543
}
544
537
- if req.Header.Get("X-Forwarded-Proto") == "" {
545
+ prior, ok := req.Header["X-Forwarded-Proto"]
546
+ omit := ok && prior == nil
547
+ if len(prior) == 0 && !omit {
548
// set X-Forwarded-Proto; many backend apps expect this too
549
proto := "https"
550
if req.TLS == nil {
837
// removeConnectionHeaders removes hop-by-hop headers listed in the "Connection" header of h.
838
// See RFC 7230, section 6.1
839
func removeConnectionHeaders(h http.Header) {
830
- if c := h.Get("Connection"); c != "" {
831
- for _, f := range strings.Split(c, ",") {
832
- if f = strings.TrimSpace(f); f != "" {
833
- h.Del(f)
840
+ for _, f := range h["Connection"] {
841
+ for _, sf := range strings.Split(f, ",") {
842
+ if sf = textproto.TrimString(sf); sf != "" {
843
+ h.Del(sf)
844
}
845
}
846
}