GoBlog/micropubMedia.go

86 lines
2.2 KiB
Go
Raw Normal View History

2020-10-14 19:20:17 +00:00
package main
import (
2022-02-11 18:39:07 +00:00
"crypto/sha256"
"fmt"
"io"
2020-10-14 19:20:17 +00:00
"mime"
"net/http"
"path/filepath"
"strings"
"go.goblog.app/app/pkgs/contenttype"
2020-10-14 19:20:17 +00:00
)
const micropubMediaSubPath = "/media"
func (a *goBlog) serveMicropubMedia(w http.ResponseWriter, r *http.Request) {
2022-02-11 18:39:07 +00:00
// Check scope
2022-02-26 19:38:52 +00:00
if !a.micropubCheckScope(w, r, "media") {
2020-11-22 19:30:02 +00:00
return
2020-10-14 19:20:17 +00:00
}
2022-02-11 18:39:07 +00:00
// Check if request is multipart
if ct := r.Header.Get(contentType); !strings.Contains(ct, contenttype.MultipartForm) {
a.serveError(w, r, "wrong content-type", http.StatusBadRequest)
2020-10-14 19:20:17 +00:00
return
}
2022-02-11 18:39:07 +00:00
// Parse multipart form
2020-10-14 19:20:17 +00:00
err := r.ParseMultipartForm(0)
if err != nil {
2023-02-03 22:33:48 +00:00
a.serveError(w, r, "failed to parse multipart form", http.StatusBadRequest)
2020-10-14 19:20:17 +00:00
return
}
2022-02-11 18:39:07 +00:00
// Get file
2020-10-14 19:20:17 +00:00
file, header, err := r.FormFile("file")
if err != nil {
2023-02-03 22:33:48 +00:00
a.serveError(w, r, "failed to get multipart file", http.StatusBadRequest)
2020-10-14 19:20:17 +00:00
return
}
2023-02-03 22:33:48 +00:00
defer file.Close()
// Generate sha256 hash for file
2022-02-11 18:39:07 +00:00
hash := sha256.New()
2023-02-03 22:33:48 +00:00
_, err = io.Copy(hash, file)
if err != nil {
a.serveError(w, r, "failed to get file hash", http.StatusBadRequest)
return
}
2022-02-11 18:39:07 +00:00
// Get file extension
2020-10-14 19:20:17 +00:00
fileExtension := filepath.Ext(header.Filename)
2022-02-25 15:29:42 +00:00
if fileExtension == "" {
2020-10-14 19:20:17 +00:00
// Find correct file extension if original filename does not contain one
mimeType := header.Header.Get(contentType)
if len(mimeType) > 0 {
allExtensions, _ := mime.ExtensionsByType(mimeType)
if len(allExtensions) > 0 {
fileExtension = allExtensions[0]
}
}
}
2022-02-11 18:39:07 +00:00
// Generate the file name
fileName := fmt.Sprintf("%x%s", hash.Sum(nil), fileExtension)
2021-01-10 14:59:43 +00:00
// Save file
2023-02-03 22:33:48 +00:00
_, err = file.Seek(0, io.SeekStart)
if err != nil {
a.serveError(w, r, "failed to read multipart file", http.StatusInternalServerError)
return
}
location, err := a.saveMediaFile(fileName, file)
2020-10-14 19:20:17 +00:00
if err != nil {
2023-02-03 22:33:48 +00:00
a.serveError(w, r, "failed to save original file", http.StatusInternalServerError)
2020-10-14 19:20:17 +00:00
return
}
// Try to compress file (only when not in private mode)
if !a.isPrivate() {
2021-06-20 13:18:02 +00:00
compressedLocation, compressionErr := a.compressMediaFile(location)
if compressionErr != nil {
a.serveError(w, r, "failed to compress file: "+compressionErr.Error(), http.StatusInternalServerError)
return
}
2021-06-20 13:18:02 +00:00
// Overwrite location
if compressedLocation != "" {
location = compressedLocation
2020-10-14 19:20:17 +00:00
}
}
2020-12-13 10:28:46 +00:00
http.Redirect(w, r, location, http.StatusCreated)
2020-10-14 19:20:17 +00:00
}