webdav: add MIMEType to FileInfo

This commit is contained in:
Simon Ser 2020-01-21 22:43:13 +01:00
parent c673e7c7e7
commit 02d1a7dbe8
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48
3 changed files with 24 additions and 27 deletions

View File

@ -2,6 +2,7 @@ package webdav
import (
"io"
"mime"
"net/http"
"os"
"path"
@ -38,6 +39,8 @@ func fileInfoFromOS(href string, fi os.FileInfo) *FileInfo {
Size: fi.Size(),
ModTime: fi.ModTime(),
IsDir: fi.IsDir(),
// TODO: fallback to http.DetectContentType?
MIMEType: mime.TypeByExtension(path.Ext(href)),
}
}

View File

@ -3,10 +3,8 @@ package webdav
import (
"encoding/xml"
"io"
"mime"
"net/http"
"os"
"path"
"strconv"
"github.com/emersion/go-webdav/internal"
@ -88,22 +86,18 @@ func (b *backend) HeadGet(w http.ResponseWriter, r *http.Request) error {
}
defer f.Close()
if fi.MIMEType != "" {
w.Header().Set("Content-Type", fi.MIMEType)
}
if !fi.ModTime.IsZero() {
w.Header().Set("Last-Modified", fi.ModTime.UTC().Format(http.TimeFormat))
}
w.Header().Set("Content-Length", strconv.FormatInt(fi.Size, 10))
if rs, ok := f.(io.ReadSeeker); ok {
// If it's an io.Seeker, use http.ServeContent which supports ranges
http.ServeContent(w, r, r.URL.Path, fi.ModTime, rs)
} else {
// TODO: fallback to http.DetectContentType
t := mime.TypeByExtension(path.Ext(r.URL.Path))
if t != "" {
w.Header().Set("Content-Type", t)
}
if !fi.ModTime.IsZero() {
w.Header().Set("Last-Modified", fi.ModTime.UTC().Format(http.TimeFormat))
}
w.Header().Set("Content-Length", strconv.FormatInt(fi.Size, 10))
if r.Method != http.MethodHead {
io.Copy(w, f)
}
@ -172,17 +166,16 @@ func (b *backend) propfindFile(propfind *internal.Propfind, fi *FileInfo) (*inte
props[internal.GetContentLengthName] = func(*internal.RawXMLValue) (interface{}, error) {
return &internal.GetContentLength{Length: fi.Size}, nil
}
props[internal.GetContentTypeName] = func(*internal.RawXMLValue) (interface{}, error) {
t := mime.TypeByExtension(path.Ext(fi.Href))
if t == "" {
// TODO: use http.DetectContentType
return nil, &internal.HTTPError{Code: http.StatusNotFound}
}
return &internal.GetContentType{Type: t}, nil
}
props[internal.GetLastModifiedName] = func(*internal.RawXMLValue) (interface{}, error) {
return &internal.GetLastModified{LastModified: internal.Time(fi.ModTime)}, nil
}
if fi.MIMEType != "" {
props[internal.GetContentTypeName] = func(*internal.RawXMLValue) (interface{}, error) {
return &internal.GetContentType{Type: fi.MIMEType}, nil
}
}
// TODO: getetag
}

View File

@ -7,11 +7,12 @@ import (
"time"
)
// TODO: add ETag, MIMEType to FileInfo
// TODO: add ETag to FileInfo
type FileInfo struct {
Href string
Size int64
ModTime time.Time
IsDir bool
MIMEType string
}