Skip to content

Commit

Permalink
Fix Go 1.19 compatibility for unix socket reverse proxy URLs
Browse files Browse the repository at this point in the history
Since Go 1.19 the net/url URL.Parse function is changed when there is no
host authority. This change broke the unix socket URL handling in the
reverse proxy code. This change adds auto detection for the behavior
and thus supports both old and new Go versions without having to add
build constraints.

Related: golang/go#46059
  • Loading branch information
longsleep committed Dec 6, 2022
1 parent 309bbe3 commit f9f0c00
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 2 deletions.
4 changes: 2 additions & 2 deletions caddyhttp/proxy/reverseproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ type ReverseProxy struct {
// "unix:///var/run/www.socket", hence the ambiguous trimming.
func socketDial(hostName string, timeout time.Duration) func(network, addr string) (conn net.Conn, err error) {
return func(network, addr string) (conn net.Conn, err error) {
return net.DialTimeout("unix", hostName[len("unix://"):], timeout)
return net.DialTimeout("unix", hostName[unixProtocolPrefixLength:], timeout)
}
}

Expand Down Expand Up @@ -217,7 +217,7 @@ func NewSingleHostReverseProxy(target *url.URL, without string, keepalive int, t
// to /var/run/www.socket/test, rendering paths useless.
if target.Scheme == "unix" {
// See comment on socketDial for the trim
socketPrefix := target.String()[len("unix://"):]
socketPrefix := target.String()[unixProtocolPrefixLength:]
req.URL.Path = strings.TrimPrefix(req.URL.Path, socketPrefix)
if req.URL.Opaque != "" {
req.URL.Opaque = strings.TrimPrefix(req.URL.Opaque, socketPrefix)
Expand Down
21 changes: 21 additions & 0 deletions caddyhttp/proxy/unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package proxy

import (
"net/url"
"strings"
)

// unixProtocolPrefixLength defines the length of the prefix of parsed URLs
// starting with unix: scheme. The actual value is different since Go 1.19 where
// the prefix no longer contains a // as unix: is not a registered scheme.
// See https://github.com/golang/go/commit/ab0f7611d739fe10d0265dbc6bdc17684423bfc8
// for reference.
var unixProtocolPrefixLength = func() int {
u, _ := url.Parse("unix:/some/path")

if strings.HasPrefix(u.String(), "unix://") {
// For Go < 1.19 url parse generates strings with an injected //.
return len("unix://")
}
return len("unix:")
}()

0 comments on commit f9f0c00

Please sign in to comment.