From 08bdc63d7701d916bf414e26a9b1858623c22b48 Mon Sep 17 00:00:00 2001 From: Michael Quigley Date: Fri, 25 Aug 2023 10:50:16 -0400 Subject: [PATCH] early progress on embedded Caddy for --backend-mode web (#392) --- cmd/zrok/main.go | 1 + cmd/zrok/sharePublic.go | 8 +-- {cmd/zrok => endpoints}/caddyListener.go | 24 ++++----- endpoints/proxy/caddyWebBackend.go | 69 ++++++++++++++++++++++++ 4 files changed, 86 insertions(+), 16 deletions(-) rename {cmd/zrok => endpoints}/caddyListener.go (66%) create mode 100644 endpoints/proxy/caddyWebBackend.go diff --git a/cmd/zrok/main.go b/cmd/zrok/main.go index 27c885fa..fd8d52f8 100644 --- a/cmd/zrok/main.go +++ b/cmd/zrok/main.go @@ -5,6 +5,7 @@ import ( "github.com/openziti/transport/v2" "github.com/openziti/transport/v2/tcp" "github.com/openziti/transport/v2/udp" + _ "github.com/openziti/zrok/endpoints" "github.com/openziti/zrok/tui" "github.com/sirupsen/logrus" "github.com/spf13/cobra" diff --git a/cmd/zrok/sharePublic.go b/cmd/zrok/sharePublic.go index 8f572143..4f525a05 100644 --- a/cmd/zrok/sharePublic.go +++ b/cmd/zrok/sharePublic.go @@ -157,11 +157,11 @@ func (cmd *sharePublicCommand) run(_ *cobra.Command, args []string) { } case "web": - cfg := &proxy.WebBackendConfig{ + cfg := &proxy.CaddyWebBackendConfig{ IdentityPath: zif, WebRoot: target, ShrToken: resp.Payload.ShrToken, - RequestsChan: requestsChan, + Requests: requestsChan, } _, err = cmd.webBackendMode(cfg) if err != nil { @@ -223,8 +223,8 @@ func (cmd *sharePublicCommand) proxyBackendMode(cfg *proxy.BackendConfig) (endpo return be, nil } -func (cmd *sharePublicCommand) webBackendMode(cfg *proxy.WebBackendConfig) (endpoints.RequestHandler, error) { - be, err := proxy.NewWebBackend(cfg) +func (cmd *sharePublicCommand) webBackendMode(cfg *proxy.CaddyWebBackendConfig) (endpoints.RequestHandler, error) { + be, err := proxy.NewCaddyWebBackend(cfg) if err != nil { return nil, errors.Wrap(err, "error creating http web backend") } diff --git a/cmd/zrok/caddyListener.go b/endpoints/caddyListener.go similarity index 66% rename from cmd/zrok/caddyListener.go rename to endpoints/caddyListener.go index 6675a6d1..ed33f35e 100644 --- a/cmd/zrok/caddyListener.go +++ b/endpoints/caddyListener.go @@ -1,4 +1,4 @@ -package main +package endpoints import ( "context" @@ -14,38 +14,38 @@ import ( ) func init() { - caddy.RegisterNetwork("zrok", newZrokListener) + caddy.RegisterNetwork("zrok", NewZrokListener) } -type zrokListener struct { +type ZrokListener struct { zctx ziti.Context share string l edge.Listener } -func (l *zrokListener) String() string { +func (l *ZrokListener) String() string { return fmt.Sprintf("zrok/%s", l.share) } -func (l *zrokListener) Network() string { +func (l *ZrokListener) Network() string { return "zrok" } -func (l *zrokListener) Accept() (net.Conn, error) { +func (l *ZrokListener) Accept() (net.Conn, error) { return l.l.Accept() } -func (l *zrokListener) Close() error { +func (l *ZrokListener) Close() error { _ = l.l.Close() l.zctx.Close() return nil } -func (l *zrokListener) Addr() net.Addr { +func (l *ZrokListener) Addr() net.Addr { return l } -func newZrokListener(ctx context.Context, _ string, addr string, cfg net.ListenConfig) (any, error) { +func NewZrokListener(_ context.Context, _ string, addr string, _ net.ListenConfig) (any, error) { shrToken := strings.Split(addr, ":")[0] env, err := environment.LoadRoot() if err != nil { @@ -66,7 +66,7 @@ func newZrokListener(ctx context.Context, _ string, addr string, cfg net.ListenC if err != nil { return nil, err } - l := &zrokListener{ + l := &ZrokListener{ zctx: zctx, share: shrToken, l: conn, @@ -75,6 +75,6 @@ func newZrokListener(ctx context.Context, _ string, addr string, cfg net.ListenC } var ( - _ net.Addr = (*zrokListener)(nil) - _ net.Listener = (*zrokListener)(nil) + _ net.Addr = (*ZrokListener)(nil) + _ net.Listener = (*ZrokListener)(nil) ) diff --git a/endpoints/proxy/caddyWebBackend.go b/endpoints/proxy/caddyWebBackend.go new file mode 100644 index 00000000..6530e541 --- /dev/null +++ b/endpoints/proxy/caddyWebBackend.go @@ -0,0 +1,69 @@ +package proxy + +import ( + "encoding/json" + "fmt" + "github.com/caddyserver/caddy/v2" + "github.com/caddyserver/caddy/v2/caddyconfig" + "github.com/caddyserver/caddy/v2/modules/caddyhttp" + "github.com/caddyserver/caddy/v2/modules/caddyhttp/fileserver" + "github.com/openziti/zrok/endpoints" + "time" +) + +type CaddyWebBackendConfig struct { + IdentityPath string + WebRoot string + ShrToken string + Requests chan *endpoints.Request +} + +type CaddyWebBackend struct { + cfg *CaddyWebBackendConfig + caddyCfg *caddy.Config +} + +func NewCaddyWebBackend(cfg *CaddyWebBackendConfig) (*CaddyWebBackend, error) { + handler := fileserver.FileServer{Root: cfg.WebRoot} + handler.Browse = new(fileserver.Browse) + + var handlers []json.RawMessage + handlers = append(handlers, caddyconfig.JSONModuleObject(handler, "handler", "file_server", nil)) + + route := caddyhttp.Route{HandlersRaw: handlers} + + server := &caddyhttp.Server{ + ReadHeaderTimeout: caddy.Duration(10 * time.Second), + IdleTimeout: caddy.Duration(30 * time.Second), + MaxHeaderBytes: 1024 * 10, + Routes: caddyhttp.RouteList{route}, + } + server.Listen = []string{fmt.Sprintf("zrok/%s", cfg.ShrToken)} + + httpApp := caddyhttp.App{ + Servers: map[string]*caddyhttp.Server{"static": server}, + } + + var false bool + caddyCfg := &caddy.Config{ + Admin: &caddy.AdminConfig{ + Disabled: true, + Config: &caddy.ConfigSettings{ + Persist: &false, + }, + }, + AppsRaw: caddy.ModuleMap{ + "http": caddyconfig.JSON(httpApp, nil), + }, + } + + return &CaddyWebBackend{cfg: cfg, caddyCfg: caddyCfg}, nil +} + +func (c *CaddyWebBackend) Run() error { + return caddy.Run(c.caddyCfg) +} + +func (c *CaddyWebBackend) Requests() func() int32 { + return func() int32 { return 0 } +}