caddyhttp: support unix sockets in caddy respond command (#6010)

previously the `caddy respond` command would treat the argument
passed to --listen as a TCP socket address, iterating over a possible
port range.

this patch factors the server creation out into a separate function,
allowing this to be reused in case the listen address is a unix network
address.
This commit is contained in:
networkException 2024-01-01 04:34:00 +01:00 committed by GitHub
parent 8f9ffc587e
commit b568a10dd4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -257,6 +257,53 @@ func (s StaticResponse) ServeHTTP(w http.ResponseWriter, r *http.Request, next H
return nil return nil
} }
func buildHTTPServer(i int, port uint, addr string, statusCode int, hdr http.Header, body string, accessLog bool) (*Server, error) {
var handlers []json.RawMessage
// response body supports a basic template; evaluate it
tplCtx := struct {
N int // server number
Port uint // only the port
Address string // listener address
}{
N: i,
Port: port,
Address: addr,
}
tpl, err := template.New("body").Parse(body)
if err != nil {
return nil, err
}
buf := new(bytes.Buffer)
err = tpl.Execute(buf, tplCtx)
if err != nil {
return nil, err
}
// create route with handler
handler := StaticResponse{
StatusCode: WeakString(fmt.Sprintf("%d", statusCode)),
Headers: hdr,
Body: buf.String(),
}
handlers = append(handlers, caddyconfig.JSONModuleObject(handler, "handler", "static_response", nil))
route := Route{HandlersRaw: handlers}
server := &Server{
Listen: []string{addr},
ReadHeaderTimeout: caddy.Duration(10 * time.Second),
IdleTimeout: caddy.Duration(30 * time.Second),
MaxHeaderBytes: 1024 * 10,
Routes: RouteList{route},
AutoHTTPS: &AutoHTTPSConfig{DisableRedir: true},
}
if accessLog {
server.Logs = new(ServerLogConfig)
}
return server, nil
}
func cmdRespond(fl caddycmd.Flags) (int, error) { func cmdRespond(fl caddycmd.Flags) (int, error) {
caddy.TrapSignals() caddy.TrapSignals()
@ -332,65 +379,38 @@ func cmdRespond(fl caddycmd.Flags) (int, error) {
hdr.Set(key, val) hdr.Set(key, val)
} }
// build each HTTP server
httpApp := App{Servers: make(map[string]*Server)}
// expand listen address, if more than one port // expand listen address, if more than one port
listenAddr, err := caddy.ParseNetworkAddress(listen) listenAddr, err := caddy.ParseNetworkAddress(listen)
if err != nil { if err != nil {
return caddy.ExitCodeFailedStartup, err return caddy.ExitCodeFailedStartup, err
} }
listenAddrs := make([]string, 0, listenAddr.PortRangeSize())
for offset := uint(0); offset < listenAddr.PortRangeSize(); offset++ {
listenAddrs = append(listenAddrs, listenAddr.JoinHostPort(offset))
}
// build each HTTP server if !listenAddr.IsUnixNetwork() {
httpApp := App{Servers: make(map[string]*Server)} listenAddrs := make([]string, 0, listenAddr.PortRangeSize())
for offset := uint(0); offset < listenAddr.PortRangeSize(); offset++ {
for i, addr := range listenAddrs { listenAddrs = append(listenAddrs, listenAddr.JoinHostPort(offset))
var handlers []json.RawMessage
// response body supports a basic template; evaluate it
tplCtx := struct {
N int // server number
Port uint // only the port
Address string // listener address
}{
N: i,
Port: listenAddr.StartPort + uint(i),
Address: addr,
} }
tpl, err := template.New("body").Parse(body)
for i, addr := range listenAddrs {
server, err := buildHTTPServer(i, listenAddr.StartPort+uint(i), addr, statusCode, hdr, body, accessLog)
if err != nil {
return caddy.ExitCodeFailedStartup, err
}
// save server
httpApp.Servers[fmt.Sprintf("static%d", i)] = server
}
} else {
server, err := buildHTTPServer(0, 0, listen, statusCode, hdr, body, accessLog)
if err != nil { if err != nil {
return caddy.ExitCodeFailedStartup, err return caddy.ExitCodeFailedStartup, err
} }
buf := new(bytes.Buffer)
err = tpl.Execute(buf, tplCtx)
if err != nil {
return caddy.ExitCodeFailedStartup, err
}
// create route with handler
handler := StaticResponse{
StatusCode: WeakString(fmt.Sprintf("%d", statusCode)),
Headers: hdr,
Body: buf.String(),
}
handlers = append(handlers, caddyconfig.JSONModuleObject(handler, "handler", "static_response", nil))
route := Route{HandlersRaw: handlers}
server := &Server{
Listen: []string{addr},
ReadHeaderTimeout: caddy.Duration(10 * time.Second),
IdleTimeout: caddy.Duration(30 * time.Second),
MaxHeaderBytes: 1024 * 10,
Routes: RouteList{route},
AutoHTTPS: &AutoHTTPSConfig{DisableRedir: true},
}
if accessLog {
server.Logs = new(ServerLogConfig)
}
// save server // save server
httpApp.Servers[fmt.Sprintf("static%d", i)] = server httpApp.Servers[fmt.Sprintf("static%d", 0)] = server
} }
// finish building the config // finish building the config