Handle missing files (previews)
This commit is contained in:
@@ -46,9 +46,14 @@ func (s *store) Namespace() string {
|
||||
}
|
||||
|
||||
func (s *store) check(filename string) error {
|
||||
if filename[:len(s.namespace)+1] != s.namespace+"/" {
|
||||
return errors.Errorf("Invalid namespace when trying to store file: %s (for %s)", filename, s.namespace)
|
||||
if len(filename) == 0 {
|
||||
return errors.Errorf("Invalid filename when trying to store file: '%s' (for %s)", filename, s.namespace)
|
||||
}
|
||||
|
||||
if filename[:len(s.namespace)+1] != s.namespace+"/" {
|
||||
return errors.Errorf("Invalid namespace when trying to store file: '%s' (for %s)", filename, s.namespace)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -68,3 +68,14 @@ func TestStore(t *testing.T) {
|
||||
assert(err != nil, "Expected error when deleting file outside of namespace")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoreCheckFunc(t *testing.T) {
|
||||
assert := func(ok bool, format string, params ...interface{}) {
|
||||
if !ok {
|
||||
t.Fatalf(format, params...)
|
||||
}
|
||||
}
|
||||
|
||||
// Should not cause panic
|
||||
assert((&store{}).check("") != nil, "Expecting an error to be returned on empty filename check")
|
||||
}
|
||||
|
||||
@@ -77,3 +77,7 @@ func (f *file) ModTime() time.Time {
|
||||
func (f *file) Content() io.ReadSeeker {
|
||||
return f.content
|
||||
}
|
||||
|
||||
func (f *file) Valid() bool {
|
||||
return f.content != nil
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/crusttech/crust/sam/rest/request"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/crusttech/crust/sam/rest/request"
|
||||
)
|
||||
|
||||
// HTTP API interface
|
||||
@@ -20,6 +20,7 @@ type Downloadable interface {
|
||||
Download() bool
|
||||
ModTime() time.Time
|
||||
Content() io.ReadSeeker
|
||||
Valid() bool
|
||||
}
|
||||
|
||||
func NewAttachmentDownloadable(ah AttachmentAPI) *Attachment {
|
||||
@@ -32,11 +33,15 @@ func NewAttachmentDownloadable(ah AttachmentAPI) *Attachment {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
} else if dl, ok := f.(Downloadable); ok {
|
||||
if dl.Download() {
|
||||
w.Header().Add("Content-Disposition", "attachment; filename="+url.QueryEscape(dl.Name()))
|
||||
}
|
||||
if !dl.Valid() {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
} else {
|
||||
if dl.Download() {
|
||||
w.Header().Add("Content-Disposition", "attachment; filename="+url.QueryEscape(dl.Name()))
|
||||
}
|
||||
|
||||
http.ServeContent(w, r, dl.Name(), dl.ModTime(), dl.Content())
|
||||
http.ServeContent(w, r, dl.Name(), dl.ModTime(), dl.Content())
|
||||
}
|
||||
} else {
|
||||
http.Error(w, "Got incompatible type from controller", http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
@@ -67,10 +67,18 @@ func (svc *attachment) FindByID(id uint64) (*types.Attachment, error) {
|
||||
}
|
||||
|
||||
func (svc *attachment) OpenOriginal(att *types.Attachment) (io.ReadSeeker, error) {
|
||||
if len(att.Url) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return svc.store.Open(att.Url)
|
||||
}
|
||||
|
||||
func (svc *attachment) OpenPreview(att *types.Attachment) (io.ReadSeeker, error) {
|
||||
if len(att.PreviewUrl) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return svc.store.Open(att.PreviewUrl)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user