From 5e4f1618a46c2b596aaf2be5cb904dfeb16466b5 Mon Sep 17 00:00:00 2001 From: Christine Dodrill Date: Sun, 21 Jan 2018 23:55:59 -0800 Subject: [PATCH] cmd/construct: add HTTP test server --- Gopkg.lock | 2 +- cmd/construct/builtin.go | 69 +++++++++++++++++++++++++++ cmd/construct/main.go | 2 + vendor/github.com/Xe/eclier/router.go | 10 +++- 4 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 cmd/construct/builtin.go diff --git a/Gopkg.lock b/Gopkg.lock index 04ade6f..b5781c2 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -11,7 +11,7 @@ branch = "master" name = "github.com/Xe/eclier" packages = ["."] - revision = "f56dc59db6b1cf87ae6bbaaf6aa985a285da33a1" + revision = "3cde6c5f47044f4875c4b7fe6b12e4e6000608ea" [[projects]] branch = "master" diff --git a/cmd/construct/builtin.go b/cmd/construct/builtin.go new file mode 100644 index 0000000..0591051 --- /dev/null +++ b/cmd/construct/builtin.go @@ -0,0 +1,69 @@ +package main + +import ( + "context" + "flag" + "fmt" + "log" + "net/http" + "os" + "runtime" + + "github.com/kr/pretty" + "go.uber.org/atomic" +) + +var ( + hits *atomic.Int64 +) + +func init() { + hits = atomic.NewInt64(0) +} + +func demoServerHandler(msg string) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintln(w, "Route is go!") + fmt.Fprintf(w, "%s\n", pretty.Sprintf("%s", r.Header)) + hn, _ := os.Hostname() + fmt.Fprintf(w, "message: %s\n", msg) + fmt.Fprintf(w, "Served by %s running %s\n", hn, runtime.GOOS) + fmt.Fprintf(w, "Hit count: %d", hits.Inc()) + + ip := r.Header.Get("X-Remote-Ip") + if ip != "" { + log.Printf("Hit from %s: %s", ip, r.RequestURI) + } + }) +} + +func demoServer(ctx context.Context, args []string) error { + fs := flag.NewFlagSet("server", flag.ContinueOnError) + + addr := fs.String("addr", ":9090", "http address to listen on") + msg := fs.String("msg", "now here's a little lesson in trickery...", "custom message to add to each page render") + + err := fs.Parse(args) + if err != nil { + return err + } + + hs := &http.Server{ + Addr: *addr, + Handler: demoServerHandler(*msg), + } + + go hs.ListenAndServe() + + log.Printf("listening on %s", *addr) + + for { + select { + case <-ctx.Done(): + sctx := context.Background() + hs.Shutdown(sctx) + + return nil + } + } +} diff --git a/cmd/construct/main.go b/cmd/construct/main.go index 970469d..01425a1 100644 --- a/cmd/construct/main.go +++ b/cmd/construct/main.go @@ -98,6 +98,8 @@ func main() { log.Fatal(err) } + r.AddCommand(eclier.NewBuiltinCommand("server", "spawns a http server for testing", "[-addr host:port|-msg \"some message\"]", demoServer)) + r.Run(ctx, flag.Args()) } diff --git a/vendor/github.com/Xe/eclier/router.go b/vendor/github.com/Xe/eclier/router.go index 82414cc..1ed610e 100644 --- a/vendor/github.com/Xe/eclier/router.go +++ b/vendor/github.com/Xe/eclier/router.go @@ -68,7 +68,7 @@ func NewRouter(opts ...RouterOption) (*Router, error) { } } - var helpCommand Command = NewBuiltinCommand("help", "shows help for subcommands", "[subcommand]", func(ctx context.Context, arg []string) error { + var helpCommand Command = NewBuiltinCommand("help", "shows help for subcommands", "help [subcommand]", func(ctx context.Context, arg []string) error { if len(arg) == 0 { table := tablewriter.NewWriter(os.Stdout) table.SetHeader([]string{"Verb", "Author", "Version", "Help"}) @@ -97,6 +97,14 @@ func NewRouter(opts ...RouterOption) (*Router, error) { return r, nil } +// AddCommand adds a given command instance to the eclier router. +func (r *Router) AddCommand(cmd Command) { + r.lock.Lock() + defer r.lock.Unlock() + + r.cmds[cmd.Verb()] = cmd +} + // Run executes a single command given in slot 0 of the argument array. func (r *Router) Run(ctx context.Context, arg []string) error { r.lock.Lock()