50 lines
1.2 KiB
Go
50 lines
1.2 KiB
Go
|
|
package static
|
||
|
|
|
||
|
|
import (
|
||
|
|
"io"
|
||
|
|
"net/http"
|
||
|
|
"strings"
|
||
|
|
|
||
|
|
"haixun-backend/internal/library/storage"
|
||
|
|
)
|
||
|
|
|
||
|
|
func PublicAssetHandler(reader storage.ObjectReader) http.HandlerFunc {
|
||
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
if reader == nil {
|
||
|
|
http.Error(w, "asset storage is not configured", http.StatusServiceUnavailable)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
key := strings.TrimSpace(r.URL.Query().Get("key"))
|
||
|
|
if key == "" {
|
||
|
|
http.Error(w, "missing asset key", http.StatusBadRequest)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
if !storage.IsPublicAssetKey(key) {
|
||
|
|
http.Error(w, "asset not found", http.StatusNotFound)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
if strings.HasPrefix(key, storage.EphemeralKeyPrefix) {
|
||
|
|
data, contentType, ok := storage.DefaultEphemeralAssetStore().Get(key)
|
||
|
|
if !ok {
|
||
|
|
http.Error(w, "asset not found", http.StatusNotFound)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
w.Header().Set("Content-Type", contentType)
|
||
|
|
w.Header().Set("Cache-Control", "no-store")
|
||
|
|
_, _ = w.Write(data)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
body, contentType, err := reader.GetObject(r.Context(), key)
|
||
|
|
if err != nil {
|
||
|
|
http.Error(w, "asset not found", http.StatusNotFound)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
defer body.Close()
|
||
|
|
|
||
|
|
w.Header().Set("Content-Type", contentType)
|
||
|
|
w.Header().Set("Cache-Control", "public, max-age=3600")
|
||
|
|
_, _ = io.Copy(w, body)
|
||
|
|
}
|
||
|
|
}
|