diff --git a/src/hmns3/hmns3.go b/src/hmns3/hmns3.go new file mode 100644 index 00000000..c762e9c4 --- /dev/null +++ b/src/hmns3/hmns3.go @@ -0,0 +1,78 @@ +package hmns3 + +import ( + _ "embed" + "fmt" + "git.handmade.network/hmn/hmn/src/website" + "github.com/spf13/cobra" + "io" + "io/fs" + "log" + "net/http" + "os" + "strings" +) + +func init() { + s3Command := &cobra.Command{ + Use: "hmns3 [storage folder]", + Short: "Run a local s3 server that stores in the filesystem", + Run: func(cmd *cobra.Command, args []string) { + targetFolder := "./tmp" + if len(args) > 0 { + targetFolder = args[0] + } + err := os.MkdirAll(targetFolder, fs.ModePerm) + if err != nil { + panic(err) + } + + handler := func(w http.ResponseWriter, r *http.Request) { + bucket, key := bucket_key(r) + + fmt.Println("\n\nIncoming request path:", r.URL.Path) + bodyBytes, err := io.ReadAll(r.Body) + fmt.Println("Bucket: ", bucket, " key: ", key, " method: ", r.Method, " len(body): ", len(bodyBytes)) + if err != nil { + panic(err) + } + if r.Method == http.MethodPut { + w.Header().Set("Location", fmt.Sprintf("/%s", bucket)) + err := os.MkdirAll(fmt.Sprintf("%s/%s", targetFolder, bucket), fs.ModePerm) + if err != nil { + panic(err) + } + if key != "" { + err = os.WriteFile(fmt.Sprintf("%s/%s/%s",targetFolder, bucket, key), bodyBytes, fs.ModePerm) + if err != nil { + panic(err) + } + } + } else if r.Method == http.MethodGet { + fileBytes, err := os.ReadFile(fmt.Sprintf("%s/%s/%s", targetFolder, bucket, key)) + if err != nil { + panic(err) + } + w.Write(fileBytes) + } else { + panic("Unimplemented method!") + } + } + + http.HandleFunc("/", handler) + log.Fatal(http.ListenAndServe(":80", nil)) + }, + } + + website.WebsiteCommand.AddCommand(s3Command) +} + + +func bucket_key(r *http.Request) (string, string) { + slashIdx := strings.IndexByte(r.URL.Path[1:], '/') + if slashIdx == -1 { + return r.URL.Path[1:], "" + } else { + return r.URL.Path[1 : 1+slashIdx], strings.Replace(r.URL.Path[2+slashIdx:], "/", "~", -1) + } +} diff --git a/src/main.go b/src/main.go index 2377cbc8..1820e0d7 100644 --- a/src/main.go +++ b/src/main.go @@ -2,6 +2,7 @@ package main import ( _ "git.handmade.network/hmn/hmn/src/admintools" + _ "git.handmade.network/hmn/hmn/src/hmns3" _ "git.handmade.network/hmn/hmn/src/assets" _ "git.handmade.network/hmn/hmn/src/buildscss" _ "git.handmade.network/hmn/hmn/src/discord/cmd"