From 52b0342078e6ee922625bb0366a559507ec1821c Mon Sep 17 00:00:00 2001 From: Michael Quigley Date: Fri, 25 Aug 2023 12:05:36 -0400 Subject: [PATCH] integrate tui requests handler (#392) --- cmd/zrok/caddyModule.go | 88 ------------------------------ cmd/zrok/sharePublic.go | 12 ++-- endpoints/proxy/caddyRequests.go | 73 +++++++++++++++++++++++++ endpoints/proxy/caddyWebBackend.go | 12 ++++ 4 files changed, 91 insertions(+), 94 deletions(-) delete mode 100644 cmd/zrok/caddyModule.go create mode 100644 endpoints/proxy/caddyRequests.go diff --git a/cmd/zrok/caddyModule.go b/cmd/zrok/caddyModule.go deleted file mode 100644 index 1537daca..00000000 --- a/cmd/zrok/caddyModule.go +++ /dev/null @@ -1,88 +0,0 @@ -package main - -import ( - "fmt" - "io" - "net/http" - "os" - - "github.com/caddyserver/caddy/v2" - "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" - "github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile" - "github.com/caddyserver/caddy/v2/modules/caddyhttp" -) - -func init() { - caddy.RegisterModule(Middleware{}) - httpcaddyfile.RegisterHandlerDirective("visitor_ip", parseCaddyfile) -} - -// Middleware implements an HTTP handler that writes the -// visitor's IP address to a file or stream. -type Middleware struct { - // The file or stream to write to. Can be "stdout" - // or "stderr". - Output string `json:"output,omitempty"` - - w io.Writer -} - -// CaddyModule returns the Caddy module information. -func (Middleware) CaddyModule() caddy.ModuleInfo { - return caddy.ModuleInfo{ - ID: "http.handlers.visitor_ip", - New: func() caddy.Module { return new(Middleware) }, - } -} - -// Provision implements caddy.Provisioner. -func (m *Middleware) Provision(ctx caddy.Context) error { - switch m.Output { - case "stdout": - m.w = os.Stdout - case "stderr": - m.w = os.Stderr - default: - return fmt.Errorf("an output stream is required") - } - return nil -} - -// Validate implements caddy.Validator. -func (m *Middleware) Validate() error { - if m.w == nil { - return fmt.Errorf("no writer") - } - return nil -} - -// ServeHTTP implements caddyhttp.MiddlewareHandler. -func (m Middleware) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error { - m.w.Write([]byte(r.RemoteAddr + "\n")) - return next.ServeHTTP(w, r) -} - -// UnmarshalCaddyfile implements caddyfile.Unmarshaler. -func (m *Middleware) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { - for d.Next() { - if !d.Args(&m.Output) { - return d.ArgErr() - } - } - return nil -} - -// parseCaddyfile unmarshals tokens from h into a new Middleware. -func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) { - var m Middleware - err := m.UnmarshalCaddyfile(h.Dispenser) - return m, err -} - -// Interface guards -var ( - _ caddy.Provisioner = (*Middleware)(nil) - _ caddy.Validator = (*Middleware)(nil) - _ caddyhttp.MiddlewareHandler = (*Middleware)(nil) - _ caddyfile.Unmarshaler = (*Middleware)(nil) -) diff --git a/cmd/zrok/sharePublic.go b/cmd/zrok/sharePublic.go index 4f525a05..2eb2867a 100644 --- a/cmd/zrok/sharePublic.go +++ b/cmd/zrok/sharePublic.go @@ -138,7 +138,7 @@ func (cmd *sharePublicCommand) run(_ *cobra.Command, args []string) { os.Exit(0) }() - requestsChan := make(chan *endpoints.Request, 1024) + requests := make(chan *endpoints.Request, 1024) switch cmd.backendMode { case "proxy": cfg := &proxy.BackendConfig{ @@ -146,7 +146,7 @@ func (cmd *sharePublicCommand) run(_ *cobra.Command, args []string) { EndpointAddress: target, ShrToken: resp.Payload.ShrToken, Insecure: cmd.insecure, - RequestsChan: requestsChan, + RequestsChan: requests, } _, err = cmd.proxyBackendMode(cfg) if err != nil { @@ -161,7 +161,7 @@ func (cmd *sharePublicCommand) run(_ *cobra.Command, args []string) { IdentityPath: zif, WebRoot: target, ShrToken: resp.Payload.ShrToken, - Requests: requestsChan, + Requests: requests, } _, err = cmd.webBackendMode(cfg) if err != nil { @@ -179,7 +179,7 @@ func (cmd *sharePublicCommand) run(_ *cobra.Command, args []string) { logrus.Infof("access your zrok share at the following endpoints:\n %v", strings.Join(resp.Payload.FrontendProxyEndpoints, "\n")) for { select { - case req := <-requestsChan: + case req := <-requests: logrus.Infof("%v -> %v %v", req.RemoteAddr, req.Method, req.Path) } } @@ -193,7 +193,7 @@ func (cmd *sharePublicCommand) run(_ *cobra.Command, args []string) { go func() { for { select { - case req := <-requestsChan: + case req := <-requests: prg.Send(req) } } @@ -203,7 +203,7 @@ func (cmd *sharePublicCommand) run(_ *cobra.Command, args []string) { tui.Error("An error occurred", err) } - close(requestsChan) + close(requests) cmd.destroy(env.Environment().ZitiIdentity, resp.Payload.ShrToken, zrok, auth) } } diff --git a/endpoints/proxy/caddyRequests.go b/endpoints/proxy/caddyRequests.go new file mode 100644 index 00000000..71a85020 --- /dev/null +++ b/endpoints/proxy/caddyRequests.go @@ -0,0 +1,73 @@ +package proxy + +import ( + "fmt" + "github.com/openziti/zrok/endpoints" + "net/http" + "time" + + "github.com/caddyserver/caddy/v2" + "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" + "github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile" + "github.com/caddyserver/caddy/v2/modules/caddyhttp" +) + +var middlewareRequests chan *endpoints.Request + +func init() { + caddy.RegisterModule(ZrokRequestsMiddleware{}) + httpcaddyfile.RegisterHandlerDirective("zrok_requests", parseCaddyfile) +} + +type ZrokRequestsMiddleware struct{} + +// CaddyModule returns the Caddy module information. +func (ZrokRequestsMiddleware) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + ID: "http.handlers.zrok_requests", + New: func() caddy.Module { return new(ZrokRequestsMiddleware) }, + } +} + +// Provision implements caddy.Provisioner. +func (m *ZrokRequestsMiddleware) Provision(ctx caddy.Context) error { + return nil +} + +// Validate implements caddy.Validator. +func (m ZrokRequestsMiddleware) Validate() error { + return nil +} + +// ServeHTTP implements caddyhttp.MiddlewareHandler. +func (m ZrokRequestsMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error { + if middlewareRequests != nil { + middlewareRequests <- &endpoints.Request{ + Stamp: time.Now(), + RemoteAddr: fmt.Sprintf("%v", r.Header["X-Real-Ip"]), + Method: r.Method, + Path: r.URL.String(), + } + } + return next.ServeHTTP(w, r) +} + +// UnmarshalCaddyfile implements caddyfile.Unmarshaler. +func (m *ZrokRequestsMiddleware) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { + return nil +} + +// parseCaddyfile unmarshals tokens from h into a new ZrokRequestsMiddleware. +func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) { + var m ZrokRequestsMiddleware + err := m.UnmarshalCaddyfile(h.Dispenser) + return m, err +} + +// Interface guards +var ( + _ caddy.Provisioner = (*ZrokRequestsMiddleware)(nil) + _ caddy.Validator = (*ZrokRequestsMiddleware)(nil) + _ caddyhttp.MiddlewareHandler = (*ZrokRequestsMiddleware)(nil) + _ caddyfile.Unmarshaler = (*ZrokRequestsMiddleware)(nil) +) diff --git a/endpoints/proxy/caddyWebBackend.go b/endpoints/proxy/caddyWebBackend.go index 6530e541..2e52644b 100644 --- a/endpoints/proxy/caddyWebBackend.go +++ b/endpoints/proxy/caddyWebBackend.go @@ -8,6 +8,7 @@ import ( "github.com/caddyserver/caddy/v2/modules/caddyhttp" "github.com/caddyserver/caddy/v2/modules/caddyhttp/fileserver" "github.com/openziti/zrok/endpoints" + "go.uber.org/zap" "time" ) @@ -28,6 +29,8 @@ func NewCaddyWebBackend(cfg *CaddyWebBackendConfig) (*CaddyWebBackend, error) { handler.Browse = new(fileserver.Browse) var handlers []json.RawMessage + middlewareRequests = cfg.Requests + handlers = append(handlers, caddyconfig.JSONModuleObject(&ZrokRequestsMiddleware{}, "handler", "zrok_requests", nil)) handlers = append(handlers, caddyconfig.JSONModuleObject(handler, "handler", "file_server", nil)) route := caddyhttp.Route{HandlersRaw: handlers} @@ -55,6 +58,15 @@ func NewCaddyWebBackend(cfg *CaddyWebBackendConfig) (*CaddyWebBackend, error) { AppsRaw: caddy.ModuleMap{ "http": caddyconfig.JSON(httpApp, nil), }, + Logging: &caddy.Logging{ + Logs: map[string]*caddy.CustomLog{ + "default": { + BaseLog: caddy.BaseLog{ + Level: zap.ErrorLevel.CapitalString(), + }, + }, + }, + }, } return &CaddyWebBackend{cfg: cfg, caddyCfg: caddyCfg}, nil