From 0dcdb0cdf23964cd0529bec8df8801b411e68f42 Mon Sep 17 00:00:00 2001 From: Hadley Rich Date: Wed, 25 Oct 2023 18:26:53 +1300 Subject: [PATCH] Initial commit --- .gitignore | 1 + .gittea/workflows/go.yml | 29 +++++++++ go.mod | 14 +++++ go.sum | 10 +++ main.go | 128 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 182 insertions(+) create mode 100644 .gittea/workflows/go.yml create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go diff --git a/.gitignore b/.gitignore index adf8f72..a22606c 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ # Go workspace file go.work +snice \ No newline at end of file diff --git a/.gittea/workflows/go.yml b/.gittea/workflows/go.yml new file mode 100644 index 0000000..6a03714 --- /dev/null +++ b/.gittea/workflows/go.yml @@ -0,0 +1,29 @@ +name: Go + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + + build: + runs-on: ubuntu-latest + strategy: + matrix: + go: [ '1.21' ] + name: Go ${{ matrix.go }} test + steps: + - uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: ${{ matrix.go }} + + - name: Build + run: go build -v ./... + + # - name: Test + # run: go test -v ./... \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..842ea1b --- /dev/null +++ b/go.mod @@ -0,0 +1,14 @@ +module git.nice.net.nz/hads/snice + +go 1.21.3 + +require ( + github.com/urfave/cli/v2 v2.25.7 + golang.org/x/exp v0.0.0-20231006140011-7918f672742d +) + +require ( + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..baced2c --- /dev/null +++ b/go.sum @@ -0,0 +1,10 @@ +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= +github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= diff --git a/main.go b/main.go new file mode 100644 index 0000000..98e81ab --- /dev/null +++ b/main.go @@ -0,0 +1,128 @@ +package main + +import ( + "fmt" + "log" + "net" + "net/http" + "os" + "strings" + "time" + + "github.com/urfave/cli/v2" + "golang.org/x/exp/slog" +) + +func serveLogger(logger *log.Logger, next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + remoteHost, _, _ := strings.Cut(r.RemoteAddr, ":") + logger.Printf("%v %v %v\n", remoteHost, r.Method, r.URL.Path) + next.ServeHTTP(w, r) + }) +} + +func timeHandler(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, time.Now().Format("02 Jan 2006 15:04:05 MST")) +} + +func main() { + // handler := slog.NewJSONHandler(os.Stdout, nil) + handler := slog.NewTextHandler(os.Stdout, nil) + slog.SetDefault(slog.New(handler)) + logger := slog.NewLogLogger(handler, slog.LevelError) + + var host string + var port string + var directory string + + app := &cli.App{ + Name: "snice", + Usage: "Serve Static Files", + Version: "v0.1.0", + DefaultCommand: "", + Commands: []*cli.Command{ + { + Name: "serve", + Aliases: []string{"s"}, + Usage: "Serve directory", + Action: func(cCtx *cli.Context) error { + var addr string = host + ":" + port + + srv := &http.Server{ + Addr: addr, + ErrorLog: logger, + } + mux := http.NewServeMux() + mux.HandleFunc("/time", timeHandler) + fileHandler := serveLogger(logger, http.FileServer(http.Dir(directory))) + mux.Handle("/", fileHandler) + srv.Handler = mux + listener, err := net.Listen("tcp", addr) + if err != nil { + logger.Println(err) + } + scheme := "http://" + logger.Printf("Serving directory %q on %v%v", directory, scheme, listener.Addr()) + err = srv.Serve(listener) + if err != nil { + logger.Println(err) + } + return nil + }, + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "directory", + Aliases: []string{"dir", "d"}, + EnvVars: []string{"DIRECTORY"}, + Value: ".", + Usage: "Directory to serve", + Destination: &directory, + }, + &cli.StringFlag{ + Name: "host", + EnvVars: []string{"HOST"}, + Value: "127.0.0.1", + Usage: "Host to listen on", + Destination: &host, + }}, + }, + { + Name: "healthcheck", + Aliases: []string{"hc"}, + Usage: "Call healthcheck endpoint", + Action: func(cCtx *cli.Context) error { + _, err := http.Get(fmt.Sprintf("http://127.0.0.1:%s/health", port)) + if err != nil { + os.Exit(1) + } + return nil + }}}, + Flags: []cli.Flag{ + &cli.BoolFlag{Name: "quiet", Aliases: []string{"q"}}, + &cli.StringFlag{ + Name: "port", + Aliases: []string{"p"}, + EnvVars: []string{"PORT"}, + Value: "3000", + Usage: "Port to serve on", + Destination: &port, + }, + }, + EnableBashCompletion: true, + Compiled: time.Time{}, + Authors: []*cli.Author{}, + Reader: nil, + Writer: nil, + ErrWriter: nil, + SliceFlagSeparator: "", + DisableSliceFlagSeparator: false, + UseShortOptionHandling: true, + Suggest: true, + AllowExtFlags: false, + SkipFlagParsing: false, + } + + if err := app.Run(os.Args); err != nil { + log.Fatal(err) + } +}