mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-11-04 03:27:23 -05:00 
			
		
		
		
	reverseproxy: use http.Protocols to handle h2c requests (#6990)
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 15s
				
			
		
			
				
	
				Tests / test (s390x on IBM Z) (push) Has been skipped
				
			
		
			
				
	
				Tests / goreleaser-check (push) Has been skipped
				
			
		
			
				
	
				Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 14s
				
			
		
			
				
	
				Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 13s
				
			
		
			
				
	
				Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 14s
				
			
		
			
				
	
				Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 14s
				
			
		
			
				
	
				Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 15s
				
			
		
			
				
	
				Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 15s
				
			
		
			
				
	
				Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 15s
				
			
		
			
				
	
				Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 16s
				
			
		
			
				
	
				Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 13s
				
			
		
			
				
	
				Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 16s
				
			
		
			
				
	
				Lint / lint (ubuntu-latest, linux) (push) Failing after 14s
				
			
		
			
				
	
				Lint / govulncheck (push) Successful in 1m10s
				
			
		
			
				
	
				Lint / dependency-review (push) Failing after 15s
				
			
		
			
				
	
				OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 14s
				
			
		
			
				
	
				Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
				
			
		
			
				
	
				Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
				
			
		
			
				
	
				Lint / lint (macos-14, mac) (push) Has been cancelled
				
			
		
			
				
	
				Lint / lint (windows-latest, windows) (push) Has been cancelled
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 15s
				
			Tests / test (s390x on IBM Z) (push) Has been skipped
				
			Tests / goreleaser-check (push) Has been skipped
				
			Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 14s
				
			Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 13s
				
			Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 14s
				
			Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 14s
				
			Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 15s
				
			Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 15s
				
			Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 15s
				
			Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 16s
				
			Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 13s
				
			Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 16s
				
			Lint / lint (ubuntu-latest, linux) (push) Failing after 14s
				
			Lint / govulncheck (push) Successful in 1m10s
				
			Lint / dependency-review (push) Failing after 15s
				
			OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 14s
				
			Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
				
			Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
				
			Lint / lint (macos-14, mac) (push) Has been cancelled
				
			Lint / lint (windows-latest, windows) (push) Has been cancelled
				
			This commit is contained in:
		
							parent
							
								
									595aab8bc0
								
							
						
					
					
						commit
						1e21b660c4
					
				@ -160,7 +160,6 @@ type HTTPTransport struct {
 | 
				
			|||||||
	// `HTTPS_PROXY`, and `NO_PROXY` environment variables.
 | 
						// `HTTPS_PROXY`, and `NO_PROXY` environment variables.
 | 
				
			||||||
	NetworkProxyRaw json.RawMessage `json:"network_proxy,omitempty" caddy:"namespace=caddy.network_proxy inline_key=from"`
 | 
						NetworkProxyRaw json.RawMessage `json:"network_proxy,omitempty" caddy:"namespace=caddy.network_proxy inline_key=from"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	h2cTransport *http2.Transport
 | 
					 | 
				
			||||||
	h3Transport *http3.Transport // TODO: EXPERIMENTAL (May 2024)
 | 
						h3Transport *http3.Transport // TODO: EXPERIMENTAL (May 2024)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -472,12 +471,6 @@ func (h *HTTPTransport) NewTransport(caddyCtx caddy.Context) (*http.Transport, e
 | 
				
			|||||||
		rt.DisableCompression = !*h.Compression
 | 
							rt.DisableCompression = !*h.Compression
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if slices.Contains(h.Versions, "2") {
 | 
					 | 
				
			||||||
		if err := http2.ConfigureTransport(rt); err != nil {
 | 
					 | 
				
			||||||
			return nil, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// configure HTTP/3 transport if enabled; however, this does not
 | 
						// configure HTTP/3 transport if enabled; however, this does not
 | 
				
			||||||
	// automatically fall back to lower versions like most web browsers
 | 
						// automatically fall back to lower versions like most web browsers
 | 
				
			||||||
	// do (that'd add latency and complexity, besides, we expect that
 | 
						// do (that'd add latency and complexity, besides, we expect that
 | 
				
			||||||
@ -495,25 +488,22 @@ func (h *HTTPTransport) NewTransport(caddyCtx caddy.Context) (*http.Transport, e
 | 
				
			|||||||
		return nil, fmt.Errorf("if HTTP/3 is enabled to the upstream, no other HTTP versions are supported")
 | 
							return nil, fmt.Errorf("if HTTP/3 is enabled to the upstream, no other HTTP versions are supported")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// if h2c is enabled, configure its transport (std lib http.Transport
 | 
						// if h2/c is enabled, configure it explicitly
 | 
				
			||||||
	// does not "HTTP/2 over cleartext TCP")
 | 
						if slices.Contains(h.Versions, "2") || slices.Contains(h.Versions, "h2c") {
 | 
				
			||||||
 | 
							if err := http2.ConfigureTransport(rt); err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// DisableCompression from h2 is configured by http2.ConfigureTransport
 | 
				
			||||||
 | 
							// Likewise, DisableKeepAlives from h1 is used too.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Protocols field is only used when the request is not using TLS,
 | 
				
			||||||
 | 
							// http1/2 over tls is still allowed
 | 
				
			||||||
		if slices.Contains(h.Versions, "h2c") {
 | 
							if slices.Contains(h.Versions, "h2c") {
 | 
				
			||||||
		// crafting our own http2.Transport doesn't allow us to utilize
 | 
								rt.Protocols = new(http.Protocols)
 | 
				
			||||||
		// most of the customizations/preferences on the http.Transport,
 | 
								rt.Protocols.SetUnencryptedHTTP2(true)
 | 
				
			||||||
		// because, for some reason, only http2.ConfigureTransport()
 | 
								rt.Protocols.SetHTTP1(false)
 | 
				
			||||||
		// is allowed to set the unexported field that refers to a base
 | 
					 | 
				
			||||||
		// http.Transport config; oh well
 | 
					 | 
				
			||||||
		h2t := &http2.Transport{
 | 
					 | 
				
			||||||
			// kind of a hack, but for plaintext/H2C requests, pretend to dial TLS
 | 
					 | 
				
			||||||
			DialTLSContext: func(ctx context.Context, network, address string, _ *tls.Config) (net.Conn, error) {
 | 
					 | 
				
			||||||
				return dialContext(ctx, network, address)
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			AllowHTTP: true,
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if h.Compression != nil {
 | 
					 | 
				
			||||||
			h2t.DisableCompression = !*h.Compression
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		h.h2cTransport = h2t
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return rt, nil
 | 
						return rt, nil
 | 
				
			||||||
@ -528,15 +518,6 @@ func (h *HTTPTransport) RoundTrip(req *http.Request) (*http.Response, error) {
 | 
				
			|||||||
		return h.h3Transport.RoundTrip(req)
 | 
							return h.h3Transport.RoundTrip(req)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// if H2C ("HTTP/2 over cleartext") is enabled and the upstream request is
 | 
					 | 
				
			||||||
	// HTTP without TLS, use the alternate H2C-capable transport instead
 | 
					 | 
				
			||||||
	if req.URL.Scheme == "http" && h.h2cTransport != nil {
 | 
					 | 
				
			||||||
		// There is no dedicated DisableKeepAlives field in *http2.Transport.
 | 
					 | 
				
			||||||
		// This is an alternative way to disable keep-alive.
 | 
					 | 
				
			||||||
		req.Close = h.Transport.DisableKeepAlives
 | 
					 | 
				
			||||||
		return h.h2cTransport.RoundTrip(req)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return h.Transport.RoundTrip(req)
 | 
						return h.Transport.RoundTrip(req)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user