s3staticsite/serve.go

64 lines
1.5 KiB
Go
Raw Normal View History

2024-02-18 22:30:11 +00:00
package main
import (
"io"
"net/http"
minio "github.com/minio/minio-go/v7"
"golang.org/x/exp/slog"
)
func ListenAndServe(minioClient *minio.Client) error {
slog.Info("starting http server", "bind", config.Bind)
err := http.ListenAndServe(config.Bind, handler{minio: minioClient})
if err != nil {
return err
}
return nil
}
type handler struct {
minio *minio.Client
}
func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
domain := r.Host
path := r.URL.Path
if path == "" || path == "/" {
path = "index.html"
}
object, err := h.minio.GetObject(r.Context(), domain, path, minio.GetObjectOptions{})
if err != nil {
slog.Warn("error getting object from s3", "error", err, "domain", domain, "path", path)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
stat, err := object.Stat()
if err != nil {
resp := minio.ToErrorResponse(err)
if resp.StatusCode == http.StatusNotFound {
// TODO: custom 404 page
w.WriteHeader(http.StatusNotFound)
return
}
slog.Warn("failed to stat object", "err", err, "bucket", domain, "path", path)
2024-02-18 22:30:11 +00:00
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Add("Content-Type", stat.ContentType)
w.Header().Add("ETag", stat.ETag)
n, err := io.Copy(w, object)
if err != nil {
slog.Warn("error writting response", "error", err, "domain", domain, "path", path)
return
}
slog.Info("served request", "domain", domain, "path", path, "size_bytes", n)
}