Simple S3-like server for development purposes, written in Go
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 65 lines 1.9 kB view raw
1package main 2 3import ( 4 "flag" 5 "log" 6 "net/http" 7 "os" 8) 9 10func addServerHeaders(serverName string) func(http.Handler) http.Handler { 11 return func(next http.Handler) http.Handler { 12 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 13 w.Header().Add("Server", serverName) 14 next.ServeHTTP(w, r) 15 }) 16 } 17} 18 19func logging(logger *log.Logger) func(http.Handler) http.Handler { 20 return func(next http.Handler) http.Handler { 21 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 22 logger.Printf("%s %s %s", r.Method, r.URL.Path, r.RemoteAddr) 23 next.ServeHTTP(w, r) 24 }) 25 } 26} 27 28func main() { 29 // TODO: Use slog instead 30 logger := log.New(os.Stderr, "gos3dir: ", log.LstdFlags) 31 32 flag.Parse() 33 if flag.NArg() == 0 { 34 logger.Fatalf("Pass directory name: gos3dir [path]") 35 os.Exit(1) 36 } 37 38 rootDir := flag.Arg(0) 39 if info, err := os.Stat(rootDir); err != nil { 40 logger.Fatalf("Error accessing root directory %q: %v", rootDir, err) 41 } else if !info.IsDir() { 42 logger.Fatalf("Path %q is not a directory", rootDir) 43 } 44 logger.Printf("Using root directory: %s", rootDir) 45 46 srv := &server{rootDir: rootDir, logger: logger} 47 48 // TODO: Support virtual addressing style https://docs.aws.amazon.com/cli/latest/topic/s3-config.html#addressing-style 49 // for now it assumes path style 50 http.HandleFunc("GET /{$}", srv.ls) 51 http.HandleFunc("GET /{bucket}", srv.ls) 52 http.HandleFunc("GET /{bucket}/{key...}", srv.cpGet) 53 http.HandleFunc("PUT /{bucket}", srv.mb) 54 http.HandleFunc("PUT /{bucket}/{key...}", srv.cpPut) 55 http.HandleFunc("DELETE /{bucket}", srv.rb) 56 http.HandleFunc("DELETE /{bucket}/{key...}", srv.rm) 57 58 handler := addServerHeaders("gos3dir")(logging(logger)(http.DefaultServeMux)) 59 60 logger.Print("Server listening on :8041...") 61 // TODO: Graceful shutdown 62 if err := http.ListenAndServe(":8041", handler); err != nil { 63 logger.Fatal(err) 64 } 65}