Files
byre/internal/server/blobs.go
T

75 lines
1.8 KiB
Go

package server
import (
"errors"
"fmt"
"io"
"net/http"
"os"
"g.fc.run/ai/byre/internal/store"
)
func (s *Server) UploadBlob(w http.ResponseWriter, r *http.Request) {
data, err := io.ReadAll(http.MaxBytesReader(w, r.Body, store.MaxBlobBytes))
maxErr := &http.MaxBytesError{}
if errors.As(err, &maxErr) {
writeError(w, http.StatusRequestEntityTooLarge, fmt.Errorf("images are limited to %d MiB", store.MaxBlobBytes>>20))
return
}
if err != nil {
writeError(w, http.StatusBadRequest, err)
return
}
contentType := http.DetectContentType(data)
if !store.ImageTypes[contentType] {
writeError(w, http.StatusBadRequest, fmt.Errorf("unsupported image type %s; use PNG, JPEG, GIF or WebP", contentType))
return
}
b, err := s.store.CreateBlob(r.Context(), contentType, data, actor(r))
if err != nil {
writeError(w, http.StatusInternalServerError, err)
return
}
writeJSON(w, http.StatusCreated, b)
}
func (s *Server) GetBlob(w http.ResponseWriter, r *http.Request, blobID string) {
b, path, err := s.store.GetBlob(r.Context(), blobID)
if err != nil {
writeStoreError(w, err)
return
}
f, err := os.Open(path)
if err != nil {
writeError(w, http.StatusInternalServerError, err)
return
}
defer f.Close()
w.Header().Set("Content-Type", b.ContentType)
w.Header().Set("Cache-Control", "private, max-age=31536000, immutable")
http.ServeContent(w, r, "", b.CreatedAt, f)
}
func (s *Server) images(w http.ResponseWriter, r *http.Request, ids *[]string) ([]string, bool) {
if ids == nil {
return nil, true
}
for _, id := range *ids {
_, _, err := s.store.GetBlob(r.Context(), id)
if errors.Is(err, store.ErrNotFound) {
writeError(w, http.StatusBadRequest, err)
return nil, false
}
if err != nil {
writeError(w, http.StatusInternalServerError, err)
return nil, false
}
}
return *ids, true
}