curcuma

commit 4a5f85cc64e5b20bf77697bf386ca7a396f487ba

Author: Pedro Lucas Porcellis <porcellis@eletrotupi.com>

server: flesh out server and proxy requests to s3

 server.go | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++


diff --git a/server.go b/server.go
new file mode 100644
index 0000000000000000000000000000000000000000..853ab3df3dd2513b51b7f67f64d20473c4516dcb
--- /dev/null
+++ b/server.go
@@ -0,0 +1,88 @@
+package curcuma
+
+import (
+	"io"
+	"mime"
+	"path"
+	"log"
+	"fmt"
+
+	"net/http"
+	"github.com/go-chi/chi/v5"
+	"github.com/minio/minio-go/v7"
+	"github.com/vaughan0/go-ini"
+)
+
+type Server struct {
+	MinioClient *minio.Client
+	Config ini.File
+}
+
+func NewServer(mc *minio.Client, config ini.File) (*Server) {
+	return &Server{
+		MinioClient: mc,
+		Config: config,
+	}
+}
+
+func (s *Server) Start() {
+	router := chi.NewRouter()
+
+	router.Get("/*", func(w http.ResponseWriter, r *http.Request) {
+		s3Path := chi.URLParam(r, "*")
+		mc := s.MinioClient
+		bucketName, _ := s.Config.Get("s3", "bucket")
+
+		// XXX: We shouldn't just apply the route blindly
+		var (
+			object *minio.Object
+			err error
+		)
+
+		_, err = mc.StatObject(r.Context(), bucketName, s3Path, minio.StatObjectOptions{})
+		if err != nil {
+			log.Printf("404 on Stats")
+			w.WriteHeader(404)
+			w.Write([]byte("404 Not Found \n"))
+
+			return
+		}
+
+		object, err = mc.GetObject(r.Context(), bucketName, s3Path, minio.GetObjectOptions{})
+
+		if err != nil {
+			log.Printf("500 on Fetching Object, %s", err)
+			w.WriteHeader(500)
+			w.Write([]byte("500 There was an Internal Error\n"))
+
+			return
+		}
+
+		if object == nil {
+			log.Printf("404 after Fetching Object")
+			w.WriteHeader(404)
+			w.Write([]byte("404 Not Found \n"))
+
+			return
+		}
+
+		defer object.Close()
+		mimetype := mime.TypeByExtension(path.Ext(s3Path))
+
+		if mimetype != "" {
+			w.Header().Add("Content-Type", mimetype)
+		}
+
+		if _, err := io.Copy(w, object); err != nil {
+			w.WriteHeader(500)
+			w.Write([]byte(fmt.Sprintf("%s \n", err)))
+		}
+	})
+
+	addr, _ := s.Config.Get("meta", "port")
+	if addr == "" {
+		addr = ":8100"
+	}
+
+	http.ListenAndServe(addr, router)
+}