@marcel91200 / caddy Mirror · read-only / commits / 1edc1a45
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 13, 14:15 UTC

core: Plugins can register listener networks (#5002)

* core: Plugins can register listener networks This can be useful for custom listeners. This feature/API is experimental and may change! * caddyhttp: Expose server listeners

Matt Holt committed Sep 1, 2022 at 16:30 UTC 1edc1a45e3aee1f7d86b68c3ddaf2fd16ba8ab73
2 files changed +46
listeners.go
+38
@@ -31,6 +31,7 @@ import (
31
32 "github.com/lucas-clemente/quic-go"
33 "github.com/lucas-clemente/quic-go/http3"
34 + "go.uber.org/zap"
35 )
36
37 // Listen is like net.Listen, except Caddy's listeners can overlap
@@ -42,6 +43,14 @@ import (
43 // the socket have been finished. Always be sure to close listeners
44 // when you are done with them, just like normal listeners.
45 func Listen(network, addr string) (net.Listener, error) {
46 + network = strings.TrimSpace(strings.ToLower(network))
47 +
48 + // get listener from plugin if network type is registered
49 + if getListener, ok := networkTypes[network]; ok {
50 + Log().Debug("getting listener from plugin", zap.String("network", network))
51 + return getListener(network, addr)
52 + }
53 +
54 lnKey := listenerKey(network, addr)
55
56 sharedLn, _, err := listenerPool.LoadOrNew(lnKey, func() (Destructor, error) {
@@ -551,6 +560,35 @@ func JoinNetworkAddress(network, host, port string) string {
560 return a
561 }
562
563 +// RegisterNetwork registers a network type with Caddy so that if a listener is
564 +// created for that network type, getListener will be invoked to get the listener.
565 +// This should be called during init() and will panic if the network type is standard
566 +// or reserved, or if it is already registered. EXPERIMENTAL and subject to change.
567 +func RegisterNetwork(network string, getListener ListenerFunc) {
568 + network = strings.TrimSpace(strings.ToLower(network))
569 +
570 + if network == "tcp" || network == "tcp4" || network == "tcp6" ||
571 + network == "udp" || network == "udp4" || network == "udp6" ||
572 + network == "unix" || network == "unixpacket" || network == "unixgram" ||
573 + strings.HasPrefix("ip:", network) || strings.HasPrefix("ip4:", network) || strings.HasPrefix("ip6:", network) {
574 + panic("network type " + network + " is reserved")
575 + }
576 +
577 + if _, ok := networkTypes[strings.ToLower(network)]; ok {
578 + panic("network type " + network + " is already registered")
579 + }
580 +
581 + networkTypes[network] = getListener
582 +}
583 +
584 +// ListenerFunc is a function that can return a listener given a network and address.
585 +// The listeners must be capable of overlapping: with Caddy, new configs are loaded
586 +// before old ones are unloaded, so listeners may overlap briefly if the configs
587 +// both need the same listener. EXPERIMENTAL and subject to change.
588 +type ListenerFunc func(network, addr string) (net.Listener, error)
589 +
590 +var networkTypes = map[string]ListenerFunc{}
591 +
592 // ListenerWrapper is a type that wraps a listener
593 // so it can modify the input listener's methods.
594 // Modules that implement this interface are found
modules/caddyhttp/server.go
+8
@@ -579,6 +579,14 @@ func (s *Server) protocol(proto string) bool {
579 return false
580 }
581
582 +// Listeners returns the server's listeners. These are active listeners,
583 +// so calling Accept() or Close() on them will probably break things.
584 +// They are made available here for read-only purposes (e.g. Addr())
585 +// and for type-asserting for purposes where you know what you're doing.
586 +//
587 +// EXPERIMENTAL: Subject to change or removal.
588 +func (s *Server) Listeners() []net.Listener { return s.listeners }
589 +
590 // ServerLogConfig describes a server's logging configuration. If
591 // enabled without customization, all requests to this server are
592 // logged to the default logger; logger destinations may be