@marcel91200 / caddy Mirror · read-only / commits / d25008d2
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 14, 05:15 UTC

Move listen address functions into caddy package; fix unix bug

Matthew Holt committed Jul 8, 2019 at 16:46 UTC d25008d2c8e2eb5f96b2b37a1cca5b4e140cfe8d
4 files changed +94 -66
listeners.go
+72
@@ -17,6 +17,8 @@ package caddy
17 import (
18 "fmt"
19 "net"
20 + "strconv"
21 + "strings"
22 "sync"
23 "sync/atomic"
24 "time"
@@ -160,3 +162,73 @@ var (
162 listeners = make(map[string]*listenerUsage)
163 listenersMu sync.Mutex
164 )
165 +
166 +// ParseListenAddr parses addr, a string of the form "network/host:port"
167 +// (with any part optional) into its component parts. Because a port can
168 +// also be a port range, there may be multiple addresses returned.
169 +func ParseListenAddr(addr string) (network string, addrs []string, err error) {
170 + var host, port string
171 + network, host, port, err = SplitListenAddr(addr)
172 + if network == "" {
173 + network = "tcp"
174 + }
175 + if err != nil {
176 + return
177 + }
178 + if network == "unix" {
179 + addrs = []string{host}
180 + return
181 + }
182 + ports := strings.SplitN(port, "-", 2)
183 + if len(ports) == 1 {
184 + ports = append(ports, ports[0])
185 + }
186 + var start, end int
187 + start, err = strconv.Atoi(ports[0])
188 + if err != nil {
189 + return
190 + }
191 + end, err = strconv.Atoi(ports[1])
192 + if err != nil {
193 + return
194 + }
195 + if end < start {
196 + err = fmt.Errorf("end port must be greater than start port")
197 + return
198 + }
199 + for p := start; p <= end; p++ {
200 + addrs = append(addrs, net.JoinHostPort(host, fmt.Sprintf("%d", p)))
201 + }
202 + return
203 +}
204 +
205 +// SplitListenAddr splits a into its network, host, and port components.
206 +// Note that port may be a port range, or omitted for unix sockets.
207 +func SplitListenAddr(a string) (network, host, port string, err error) {
208 + if idx := strings.Index(a, "/"); idx >= 0 {
209 + network = strings.ToLower(strings.TrimSpace(a[:idx]))
210 + a = a[idx+1:]
211 + }
212 + if network == "unix" {
213 + host = a
214 + return
215 + }
216 + host, port, err = net.SplitHostPort(a)
217 + return
218 +}
219 +
220 +// JoinListenAddr combines network, host, and port into a single
221 +// address string of the form "network/host:port". Port may be a
222 +// port range. For unix sockets, the network should be "unix" and
223 +// the path to the socket should be given in the host argument.
224 +func JoinListenAddr(network, host, port string) string {
225 + var a string
226 + if network != "" {
227 + a = network + "/"
228 + }
229 + a += host
230 + if port != "" {
231 + a += ":" + port
232 + }
233 + return a
234 +}
listeners_test.go renamed
+15 -6
@@ -12,7 +12,7 @@
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 -package caddyhttp
15 +package caddy
16
17 import (
18 "reflect"
@@ -62,8 +62,13 @@ func TestSplitListenerAddr(t *testing.T) {
62 expectNetwork: "udp",
63 expectErr: true,
64 },
65 + {
66 + input: "unix//foo/bar",
67 + expectNetwork: "unix",
68 + expectHost: "/foo/bar",
69 + },
70 } {
66 - actualNetwork, actualHost, actualPort, err := splitListenAddr(tc.input)
71 + actualNetwork, actualHost, actualPort, err := SplitListenAddr(tc.input)
72 if tc.expectErr && err == nil {
73 t.Errorf("Test %d: Expected error but got: %v", i, err)
74 }
@@ -119,8 +124,12 @@ func TestJoinListenerAddr(t *testing.T) {
124 network: "udp", host: "", port: "1234",
125 expect: "udp/:1234",
126 },
127 + {
128 + network: "unix", host: "/foo/bar", port: "",
129 + expect: "unix//foo/bar",
130 + },
131 } {
123 - actual := joinListenAddr(tc.network, tc.host, tc.port)
132 + actual := JoinListenAddr(tc.network, tc.host, tc.port)
133 if actual != tc.expect {
134 t.Errorf("Test %d: Expected '%s' but got '%s'", i, tc.expect, actual)
135 }
@@ -165,9 +174,9 @@ func TestParseListenerAddr(t *testing.T) {
174 expectAddrs: []string{"localhost:1234"},
175 },
176 {
168 - input: "unix/localhost:1234-1236",
177 + input: "unix//foo/bar",
178 expectNetwork: "unix",
170 - expectAddrs: []string{"localhost:1234", "localhost:1235", "localhost:1236"},
179 + expectAddrs: []string{"/foo/bar"},
180 },
181 {
182 input: "localhost:1234-1234",
@@ -185,7 +194,7 @@ func TestParseListenerAddr(t *testing.T) {
194 expectAddrs: []string{"localhost:0"},
195 },
196 } {
188 - actualNetwork, actualAddrs, err := parseListenAddr(tc.input)
197 + actualNetwork, actualAddrs, err := ParseListenAddr(tc.input)
198 if tc.expectErr && err == nil {
199 t.Errorf("Test %d: Expected error but got: %v", i, err)
200 }
modules/caddyhttp/caddyhttp.go
+6 -59
@@ -96,7 +96,7 @@ func (app *App) Validate() error {
96 lnAddrs := make(map[string]string)
97 for srvName, srv := range app.Servers {
98 for _, addr := range srv.Listen {
99 - netw, expanded, err := parseListenAddr(addr)
99 + netw, expanded, err := caddy.ParseListenAddr(addr)
100 if err != nil {
101 return fmt.Errorf("invalid listener address '%s': %v", addr, err)
102 }
@@ -137,7 +137,7 @@ func (app *App) Start() error {
137 }
138
139 for _, lnAddr := range srv.Listen {
140 - network, addrs, err := parseListenAddr(lnAddr)
140 + network, addrs, err := caddy.ParseListenAddr(lnAddr)
141 if err != nil {
142 return fmt.Errorf("%s: parsing listen address '%s': %v", srvName, lnAddr, err)
143 }
@@ -289,7 +289,7 @@ func (app *App) automaticHTTPS() error {
289
290 // create HTTP->HTTPS redirects
291 for _, addr := range srv.Listen {
292 - netw, host, port, err := splitListenAddr(addr)
292 + netw, host, port, err := caddy.SplitListenAddr(addr)
293 if err != nil {
294 return fmt.Errorf("%s: invalid listener address: %v", srvName, addr)
295 }
@@ -298,7 +298,7 @@ func (app *App) automaticHTTPS() error {
298 if httpPort == 0 {
299 httpPort = DefaultHTTPPort
300 }
301 - httpRedirLnAddr := joinListenAddr(netw, host, strconv.Itoa(httpPort))
301 + httpRedirLnAddr := caddy.JoinListenAddr(netw, host, strconv.Itoa(httpPort))
302 lnAddrMap[httpRedirLnAddr] = struct{}{}
303
304 if parts := strings.SplitN(port, "-", 2); len(parts) == 2 {
@@ -339,7 +339,7 @@ func (app *App) automaticHTTPS() error {
339 var lnAddrs []string
340 mapLoop:
341 for addr := range lnAddrMap {
342 - netw, addrs, err := parseListenAddr(addr)
342 + netw, addrs, err := caddy.ParseListenAddr(addr)
343 if err != nil {
344 continue
345 }
@@ -364,7 +364,7 @@ func (app *App) automaticHTTPS() error {
364 func (app *App) listenerTaken(network, address string) bool {
365 for _, srv := range app.Servers {
366 for _, addr := range srv.Listen {
367 - netw, addrs, err := parseListenAddr(addr)
367 + netw, addrs, err := caddy.ParseListenAddr(addr)
368 if err != nil || netw != network {
369 continue
370 }
@@ -425,59 +425,6 @@ func (f HandlerFunc) ServeHTTP(w http.ResponseWriter, r *http.Request) error {
425 // sometimes better than a nil Handler pointer.
426 var emptyHandler HandlerFunc = func(w http.ResponseWriter, r *http.Request) error { return nil }
427
428 -func parseListenAddr(a string) (network string, addrs []string, err error) {
429 - var host, port string
430 - network, host, port, err = splitListenAddr(a)
431 - if network == "" {
432 - network = "tcp"
433 - }
434 - if err != nil {
435 - return
436 - }
437 - ports := strings.SplitN(port, "-", 2)
438 - if len(ports) == 1 {
439 - ports = append(ports, ports[0])
440 - }
441 - var start, end int
442 - start, err = strconv.Atoi(ports[0])
443 - if err != nil {
444 - return
445 - }
446 - end, err = strconv.Atoi(ports[1])
447 - if err != nil {
448 - return
449 - }
450 - if end < start {
451 - err = fmt.Errorf("end port must be greater than start port")
452 - return
453 - }
454 - for p := start; p <= end; p++ {
455 - addrs = append(addrs, net.JoinHostPort(host, fmt.Sprintf("%d", p)))
456 - }
457 - return
458 -}
459 -
460 -func splitListenAddr(a string) (network, host, port string, err error) {
461 - if idx := strings.Index(a, "/"); idx >= 0 {
462 - network = strings.ToLower(strings.TrimSpace(a[:idx]))
463 - a = a[idx+1:]
464 - }
465 - host, port, err = net.SplitHostPort(a)
466 - return
467 -}
468 -
469 -func joinListenAddr(network, host, port string) string {
470 - var a string
471 - if network != "" {
472 - a = network + "/"
473 - }
474 - a += host
475 - if port != "" {
476 - a += ":" + port
477 - }
478 - return a
479 -}
480 -
428 const (
429 // DefaultHTTPPort is the default port for HTTP.
430 DefaultHTTPPort = 80
modules/caddyhttp/server.go
+1 -1
@@ -156,7 +156,7 @@ func (s *Server) enforcementHandler(w http.ResponseWriter, r *http.Request, next
156
157 func (s *Server) listenersUseAnyPortOtherThan(otherPort int) bool {
158 for _, lnAddr := range s.Listen {
159 - _, addrs, err := parseListenAddr(lnAddr)
159 + _, addrs, err := caddy.ParseListenAddr(lnAddr)
160 if err == nil {
161 for _, a := range addrs {
162 _, port, err := net.SplitHostPort(a)