try to detect and return mimetype with stream file info (#552)

This commit is contained in:
Mike Sawka 2024-04-05 10:52:04 -07:00 committed by GitHub
parent 1c23701181
commit 181e14f55c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 41 additions and 11 deletions

View File

@ -485,6 +485,7 @@ type FileInfo struct {
ModTs int64 `json:"modts"`
IsDir bool `json:"isdir,omitempty"`
Perm int `json:"perm"`
MimeType string `json:"mimetype,omitempty"`
NotFound bool `json:"notfound,omitempty"` // when NotFound is set, Perm will be set to permission for directory
}

View File

@ -575,12 +575,14 @@ func (m *MServer) streamFile(pk *packet.StreamFilePacketType) {
m.Sender.SendPacket(resp)
return
}
mimeType := utilfn.DetectMimeType(pk.Path)
resp.Info = &packet.FileInfo{
Name: pk.Path,
Size: finfo.Size(),
ModTs: finfo.ModTime().UnixMilli(),
IsDir: finfo.IsDir(),
Perm: int(finfo.Mode().Perm()),
Name: pk.Path,
Size: finfo.Size(),
ModTs: finfo.ModTime().UnixMilli(),
IsDir: finfo.IsDir(),
MimeType: mimeType,
Perm: int(finfo.Mode().Perm()),
}
if pk.StatOnly {
resp.Done = true

View File

@ -13,6 +13,8 @@ import (
"io"
"math"
mathrand "math/rand"
"net/http"
"os"
"regexp"
"sort"
"strings"
@ -611,3 +613,25 @@ func CopyToChannel(outputCh chan<- []byte, reader io.Reader) error {
}
}
}
// on error just returns ""
// does not return "application/octet-stream" as this is considered a detection failure
func DetectMimeType(path string) string {
fd, err := os.Open(path)
if err != nil {
return ""
}
defer fd.Close()
buf := make([]byte, 512)
// ignore the error (EOF / UnexpectedEOF is fine, just process how much we got back)
n, _ := io.ReadAtLeast(fd, buf, 512)
if n == 0 {
return ""
}
buf = buf[:n]
rtn := http.DetectContentType(buf)
if rtn == "application/octet-stream" {
return ""
}
return rtn
}

View File

@ -508,11 +508,8 @@ func HandleReadFile(w http.ResponseWriter, r *http.Request) {
qvals := r.URL.Query()
screenId := qvals.Get("screenid")
lineId := qvals.Get("lineid")
path := qvals.Get("path") // validate path?
contentType := qvals.Get("mimetype")
if contentType == "" {
contentType = "application/octet-stream"
}
path := qvals.Get("path") // validate path?
contentType := qvals.Get("mimetype") // force a mimetype
if screenId == "" || lineId == "" {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("must specify sessionid, screenid, and lineid"))
@ -533,7 +530,7 @@ func HandleReadFile(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(fmt.Sprintf(ErrorInvalidLineId, err)))
return
}
if !ContentTypeHeaderValidRe.MatchString(contentType) {
if contentType != "" && !ContentTypeHeaderValidRe.MatchString(contentType) {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("invalid mimetype specified"))
return
@ -599,6 +596,12 @@ func HandleReadFile(w http.ResponseWriter, r *http.Request) {
return
}
infoJson, _ := json.Marshal(resp.Info)
if contentType == "" && resp.Info.MimeType != "" {
contentType = resp.Info.MimeType
}
if contentType == "" {
contentType = "application/octet-stream"
}
w.Header().Set("X-FileInfo", base64.StdEncoding.EncodeToString(infoJson))
w.Header().Set(ContentTypeHeaderKey, contentType)
w.WriteHeader(http.StatusOK)