static server with basic options
This commit is contained in:
		
							parent
							
								
									717a4bcbb3
								
							
						
					
					
						commit
						c768866991
					
				
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,3 +1,5 @@ | |||||||
|  | /goserv | ||||||
|  | 
 | ||||||
| *_vfsdata.go | *_vfsdata.go | ||||||
| *.env | *.env | ||||||
| .env | .env | ||||||
|  | |||||||
							
								
								
									
										11
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								README.md
									
									
									
									
									
								
							| @ -1,3 +1,14 @@ | |||||||
| # goserv | # goserv | ||||||
| 
 | 
 | ||||||
| > Boilerplate for how I like to write a backend web service | > Boilerplate for how I like to write a backend web service | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | go mod tidy | ||||||
|  | go mod vendor | ||||||
|  | go generate -mod=vendor ./... | ||||||
|  | go build -mod=vendor . | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | ./goserv run --listen :3000 --serve-path ./overrides | ||||||
|  | ``` | ||||||
|  | |||||||
							
								
								
									
										4
									
								
								assets/assets.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								assets/assets.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | |||||||
|  | // +build !dev | ||||||
|  | //go:generate go run -mod vendor github.com/shurcooL/vfsgen/cmd/vfsgendev -source="git.coolaj86.com/coolaj86/goserv/assets".Assets | ||||||
|  | 
 | ||||||
|  | package assets | ||||||
							
								
								
									
										8
									
								
								assets/assets_dev.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								assets/assets_dev.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | |||||||
|  | // +build dev | ||||||
|  | 
 | ||||||
|  | package assets | ||||||
|  | 
 | ||||||
|  | import "net/http" | ||||||
|  | 
 | ||||||
|  | // Assets is the public file system which should be served by http | ||||||
|  | var Assets http.FileSystem = http.Dir("../public") | ||||||
							
								
								
									
										10
									
								
								go.mod
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								go.mod
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  | module git.coolaj86.com/coolaj86/goserv | ||||||
|  | 
 | ||||||
|  | go 1.15 | ||||||
|  | 
 | ||||||
|  | require ( | ||||||
|  | 	github.com/go-chi/chi v4.1.2+incompatible | ||||||
|  | 	github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect | ||||||
|  | 	github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 | ||||||
|  | 	golang.org/x/tools v0.0.0-20200925191224-5d1fdd8fa346 // indirect | ||||||
|  | ) | ||||||
							
								
								
									
										28
									
								
								go.sum
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								go.sum
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | |||||||
|  | github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec= | ||||||
|  | github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= | ||||||
|  | github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk= | ||||||
|  | github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= | ||||||
|  | github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 h1:pXY9qYc/MP5zdvqWEUH6SjNiu7VhSjuVFTFiTcphaLU= | ||||||
|  | github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= | ||||||
|  | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||||||
|  | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||||||
|  | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||||||
|  | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | ||||||
|  | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= | ||||||
|  | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||||||
|  | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||||
|  | golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= | ||||||
|  | golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= | ||||||
|  | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||||
|  | golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||||
|  | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||||
|  | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
|  | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
|  | golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= | ||||||
|  | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||||
|  | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | ||||||
|  | golang.org/x/tools v0.0.0-20200925191224-5d1fdd8fa346 h1:hzJjkvxUIF3bSt+v8N5tBQNx/605vszZJ+3XsIamzZo= | ||||||
|  | golang.org/x/tools v0.0.0-20200925191224-5d1fdd8fa346/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= | ||||||
|  | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||||
|  | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||||
|  | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||||
							
								
								
									
										131
									
								
								main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								main.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,131 @@ | |||||||
|  | package main | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"compress/flate" | ||||||
|  | 	"flag" | ||||||
|  | 	"fmt" | ||||||
|  | 	"net/http" | ||||||
|  | 	"os" | ||||||
|  | 
 | ||||||
|  | 	"git.coolaj86.com/coolaj86/goserv/assets" | ||||||
|  | 	"github.com/go-chi/chi" | ||||||
|  | 	"github.com/go-chi/chi/middleware" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	name    = "goserv" | ||||||
|  | 	version = "0.0.0" | ||||||
|  | 	date    = "0001-01-01T00:00:00Z" | ||||||
|  | 	commit  = "0000000" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func usage() { | ||||||
|  | 	ver() | ||||||
|  | 	fmt.Println("") | ||||||
|  | 	fmt.Println("Use 'help <command>'") | ||||||
|  | 	fmt.Println("  help") | ||||||
|  | 	fmt.Println("  init") | ||||||
|  | 	fmt.Println("  run") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func ver() { | ||||||
|  | 	fmt.Printf("%s v%s %s (%s)\n", name, version, commit[:7], date) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type runOptions struct { | ||||||
|  | 	listen     string | ||||||
|  | 	trustProxy bool | ||||||
|  | 	compress   bool | ||||||
|  | 	static     string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | var runFlags *flag.FlagSet | ||||||
|  | var runOpts runOptions | ||||||
|  | var initFlags *flag.FlagSet | ||||||
|  | 
 | ||||||
|  | func init() { | ||||||
|  | 	runOpts = runOptions{} | ||||||
|  | 	runFlags = flag.NewFlagSet("run", flag.ExitOnError) | ||||||
|  | 	runFlags.StringVar(&runOpts.listen, "listen", ":3000", "the address and port on which to listen") | ||||||
|  | 	runFlags.BoolVar(&runOpts.trustProxy, "trust-proxy", false, "trust X-Forwarded-For header") | ||||||
|  | 	runFlags.BoolVar(&runOpts.compress, "compress", true, "enable compression for text,html,js,css,etc") | ||||||
|  | 	runFlags.StringVar(&runOpts.static, "serve-path", "", "path to serve, falls back to built-in web app") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func main() { | ||||||
|  | 	args := os.Args[:] | ||||||
|  | 	if 1 == len(args) { | ||||||
|  | 		// "run" should be the default | ||||||
|  | 		args = append(args, "run") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if "help" == args[1] { | ||||||
|  | 		// top-level help | ||||||
|  | 		if 2 == len(args) { | ||||||
|  | 			usage() | ||||||
|  | 			os.Exit(0) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		// move help to subcommand argument | ||||||
|  | 		self := args[0] | ||||||
|  | 		args = append([]string{self}, args[2:]...) | ||||||
|  | 		args = append(args, "--help") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	switch args[1] { | ||||||
|  | 	case "version": | ||||||
|  | 		ver() | ||||||
|  | 		os.Exit(0) | ||||||
|  | 		return | ||||||
|  | 	case "init": | ||||||
|  | 		initFlags.Parse(args[2:]) | ||||||
|  | 	case "run": | ||||||
|  | 		runFlags.Parse(args[2:]) | ||||||
|  | 		serve() | ||||||
|  | 	default: | ||||||
|  | 		usage() | ||||||
|  | 		os.Exit(1) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func serve() { | ||||||
|  | 	r := chi.NewRouter() | ||||||
|  | 
 | ||||||
|  | 	// A good base middleware stack | ||||||
|  | 	if runOpts.trustProxy { | ||||||
|  | 		r.Use(middleware.RealIP) | ||||||
|  | 	} | ||||||
|  | 	if runOpts.compress { | ||||||
|  | 		r.Use(middleware.Compress(flate.DefaultCompression)) | ||||||
|  | 	} | ||||||
|  | 	r.Use(middleware.Logger) | ||||||
|  | 	r.Use(middleware.Recoverer) | ||||||
|  | 
 | ||||||
|  | 	pub := http.FileServer(assets.Assets) | ||||||
|  | 
 | ||||||
|  | 	var dev http.Handler | ||||||
|  | 	var devFS http.FileSystem | ||||||
|  | 	if len(runOpts.static) > 0 { | ||||||
|  | 		devFS = http.Dir(runOpts.static) | ||||||
|  | 		dev = http.FileServer(devFS) | ||||||
|  | 		r.Get("/*", func(w http.ResponseWriter, r *http.Request) { | ||||||
|  | 			if _, err := devFS.Open(r.URL.Path); nil != err { | ||||||
|  | 				pub.ServeHTTP(w, r) | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 			dev.ServeHTTP(w, r) | ||||||
|  | 		}) | ||||||
|  | 	} else { | ||||||
|  | 		r.Get("/*", func(w http.ResponseWriter, r *http.Request) { | ||||||
|  | 			pub.ServeHTTP(w, r) | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fmt.Println("Listening for http on", runOpts.listen) | ||||||
|  | 	if err := http.ListenAndServe(runOpts.listen, r); nil != err { | ||||||
|  | 		fmt.Fprintf(os.Stderr, "%s", err) | ||||||
|  | 		os.Exit(1) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										1
									
								
								public/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								public/index.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | Hello, World! | ||||||
							
								
								
									
										10
									
								
								tools/tools.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								tools/tools.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  | // +build tools | ||||||
|  | 
 | ||||||
|  | // Package tools is a faux package for tracking dependencies that don't make it into the code | ||||||
|  | package tools | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	// these are 'go generate' tooling dependencies, not including in the binary | ||||||
|  | 	_ "github.com/shurcooL/vfsgen" | ||||||
|  | 	_ "github.com/shurcooL/vfsgen/cmd/vfsgendev" | ||||||
|  | ) | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user