mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-11-04 03:27:23 -05:00 
			
		
		
		
	reverse_proxy, php_fastcgi: Fix upstream parsing regression (fix #3101)
This commit is contained in:
		
							parent
							
								
									e4ec08e977
								
							
						
					
					
						commit
						c83d40ccd4
					
				@ -101,19 +101,12 @@ func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
 | 
				
			|||||||
	// TODO: the logic in this function is kind of sensitive, we need
 | 
						// TODO: the logic in this function is kind of sensitive, we need
 | 
				
			||||||
	// to write tests before making any more changes to it
 | 
						// to write tests before making any more changes to it
 | 
				
			||||||
	upstreamDialAddress := func(upstreamAddr string) (string, error) {
 | 
						upstreamDialAddress := func(upstreamAddr string) (string, error) {
 | 
				
			||||||
		// slight hack, to ensure a non-URL parses correctly (simplifies our code paths)
 | 
							var network, scheme, host, port string
 | 
				
			||||||
		const undefinedScheme = "undefined"
 | 
					 | 
				
			||||||
		if !strings.Contains(upstreamAddr, "://") {
 | 
					 | 
				
			||||||
			upstreamAddr = undefinedScheme + "://" + upstreamAddr
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// convenient way to get desired scheme, host, and port
 | 
							if strings.Contains(upstreamAddr, "://") {
 | 
				
			||||||
			toURL, err := url.Parse(upstreamAddr)
 | 
								toURL, err := url.Parse(upstreamAddr)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
			return "", d.Errf("parsing upstream address: %v", err)
 | 
									return "", d.Errf("parsing upstream URL: %v", err)
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if toURL.Scheme == undefinedScheme {
 | 
					 | 
				
			||||||
			toURL.Scheme = ""
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// there is currently no way to perform a URL rewrite between choosing
 | 
								// there is currently no way to perform a URL rewrite between choosing
 | 
				
			||||||
@ -132,38 +125,56 @@ func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
 | 
				
			|||||||
				return "", d.Err("upstream address has conflicting scheme (https://) and port (:80, the HTTP port)")
 | 
									return "", d.Err("upstream address has conflicting scheme (https://) and port (:80, the HTTP port)")
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// dial addresses always need a port, so if no port was
 | 
								// if port is missing, attempt to infer from scheme
 | 
				
			||||||
		// specified, assume the default ports for HTTP(S)
 | 
								if toURL.Port() == "" {
 | 
				
			||||||
		if urlPort == "" {
 | 
					 | 
				
			||||||
				var toPort string
 | 
									var toPort string
 | 
				
			||||||
			if toURL.Scheme == "" {
 | 
									switch toURL.Scheme {
 | 
				
			||||||
				// if no port or scheme is specified, we assume HTTP
 | 
									case "", "http":
 | 
				
			||||||
					toPort = "80"
 | 
										toPort = "80"
 | 
				
			||||||
			} else if toURL.Scheme == "https" {
 | 
									case "https":
 | 
				
			||||||
					toPort = "443"
 | 
										toPort = "443"
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			toURL.Host = net.JoinHostPort(toURL.Host, toPort)
 | 
									toURL.Host = net.JoinHostPort(toURL.Hostname(), toPort)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// if port is known and scheme is not, set the scheme
 | 
								scheme, host, port = toURL.Scheme, toURL.Hostname(), toURL.Port()
 | 
				
			||||||
		if toURL.Scheme == "" {
 | 
							} else {
 | 
				
			||||||
			if urlPort == "80" {
 | 
								// extract network manually, since caddy.ParseNetworkAddress() will always add one
 | 
				
			||||||
				toURL.Scheme = "http"
 | 
								if idx := strings.Index(upstreamAddr, "/"); idx >= 0 {
 | 
				
			||||||
			} else if urlPort == "443" {
 | 
									network = strings.ToLower(strings.TrimSpace(upstreamAddr[:idx]))
 | 
				
			||||||
				toURL.Scheme = "https"
 | 
									upstreamAddr = upstreamAddr[idx+1:]
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								var err error
 | 
				
			||||||
 | 
								host, port, err = net.SplitHostPort(upstreamAddr)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									host = upstreamAddr
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// if scheme is not set, we may be able to infer it from a known port
 | 
				
			||||||
 | 
							if scheme == "" {
 | 
				
			||||||
 | 
								if port == "80" {
 | 
				
			||||||
 | 
									scheme = "http"
 | 
				
			||||||
 | 
								} else if port == "443" {
 | 
				
			||||||
 | 
									scheme = "https"
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// the underlying JSON does not yet support different
 | 
							// the underlying JSON does not yet support different
 | 
				
			||||||
		// transports (protocols or schemes) to each backend,
 | 
							// transports (protocols or schemes) to each backend,
 | 
				
			||||||
		// so we remember the last one we see and compare them
 | 
							// so we remember the last one we see and compare them
 | 
				
			||||||
		if commonScheme != "" && toURL.Scheme != commonScheme {
 | 
							if commonScheme != "" && scheme != commonScheme {
 | 
				
			||||||
			return "", d.Errf("for now, all proxy upstreams must use the same scheme (transport protocol); expecting '%s://' but got '%s://'",
 | 
								return "", d.Errf("for now, all proxy upstreams must use the same scheme (transport protocol); expecting '%s://' but got '%s://'",
 | 
				
			||||||
				commonScheme, toURL.Scheme)
 | 
									commonScheme, scheme)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		commonScheme = toURL.Scheme
 | 
							commonScheme = scheme
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return toURL.Host, nil
 | 
							// for simplest possible config, we only need to include
 | 
				
			||||||
 | 
							// the network portion if the user specified one
 | 
				
			||||||
 | 
							if network != "" {
 | 
				
			||||||
 | 
								return caddy.JoinNetworkAddress(network, host, port), nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return net.JoinHostPort(host, port), nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for d.Next() {
 | 
						for d.Next() {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user