Emit post-finish event for empty uploads
See https://github.com/tus/tus-js-client/issues/106
This commit is contained in:
parent
e4017ff47e
commit
c470fe3a9d
|
@ -223,6 +223,7 @@ func TestPatch(t *testing.T) {
|
||||||
|
|
||||||
gomock.InOrder(
|
gomock.InOrder(
|
||||||
store.EXPECT().GetInfo("yes").Return(FileInfo{
|
store.EXPECT().GetInfo("yes").Return(FileInfo{
|
||||||
|
ID: "yes",
|
||||||
Offset: 5,
|
Offset: 5,
|
||||||
Size: 20,
|
Size: 20,
|
||||||
}, nil),
|
}, nil),
|
||||||
|
|
36
post_test.go
36
post_test.go
|
@ -52,6 +52,42 @@ func TestPost(t *testing.T) {
|
||||||
a.Equal(int64(300), info.Size)
|
a.Equal(int64(300), info.Size)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
SubTest(t, "CreateEmptyUpload", func(t *testing.T, store *MockFullDataStore) {
|
||||||
|
store.EXPECT().NewUpload(FileInfo{
|
||||||
|
Size: 0,
|
||||||
|
MetaData: map[string]string{},
|
||||||
|
}).Return("foo", nil)
|
||||||
|
|
||||||
|
store.EXPECT().FinishUpload("foo").Return(nil)
|
||||||
|
|
||||||
|
handler, _ := NewHandler(Config{
|
||||||
|
DataStore: store,
|
||||||
|
BasePath: "https://buy.art/files/",
|
||||||
|
NotifyCompleteUploads: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
handler.CompleteUploads = make(chan FileInfo, 1)
|
||||||
|
|
||||||
|
(&httpTest{
|
||||||
|
Method: "POST",
|
||||||
|
ReqHeader: map[string]string{
|
||||||
|
"Tus-Resumable": "1.0.0",
|
||||||
|
"Upload-Length": "0",
|
||||||
|
},
|
||||||
|
Code: http.StatusCreated,
|
||||||
|
ResHeader: map[string]string{
|
||||||
|
"Location": "https://buy.art/files/foo",
|
||||||
|
},
|
||||||
|
}).Run(handler, t)
|
||||||
|
|
||||||
|
info := <-handler.CompleteUploads
|
||||||
|
|
||||||
|
a := assert.New(t)
|
||||||
|
a.Equal("foo", info.ID)
|
||||||
|
a.Equal(int64(0), info.Size)
|
||||||
|
a.Equal(int64(0), info.Offset)
|
||||||
|
})
|
||||||
|
|
||||||
SubTest(t, "CreateExceedingMaxSizeFail", func(t *testing.T, store *MockFullDataStore) {
|
SubTest(t, "CreateExceedingMaxSizeFail", func(t *testing.T, store *MockFullDataStore) {
|
||||||
handler, _ := NewHandler(Config{
|
handler, _ := NewHandler(Config{
|
||||||
MaxSize: 400,
|
MaxSize: 400,
|
||||||
|
|
|
@ -284,6 +284,8 @@ func (handler *UnroutedHandler) PostFile(w http.ResponseWriter, r *http.Request)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info.ID = id
|
||||||
|
|
||||||
// Add the Location header directly after creating the new resource to even
|
// Add the Location header directly after creating the new resource to even
|
||||||
// include it in cases of failure when an error is returned
|
// include it in cases of failure when an error is returned
|
||||||
url := handler.absFileURL(r, id)
|
url := handler.absFileURL(r, id)
|
||||||
|
@ -293,7 +295,6 @@ func (handler *UnroutedHandler) PostFile(w http.ResponseWriter, r *http.Request)
|
||||||
handler.log("UploadCreated", "id", id, "size", i64toa(size), "url", url)
|
handler.log("UploadCreated", "id", id, "size", i64toa(size), "url", url)
|
||||||
|
|
||||||
if handler.config.NotifyCreatedUploads {
|
if handler.config.NotifyCreatedUploads {
|
||||||
info.ID = id
|
|
||||||
handler.CreatedUploads <- info
|
handler.CreatedUploads <- info
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,7 +306,6 @@ func (handler *UnroutedHandler) PostFile(w http.ResponseWriter, r *http.Request)
|
||||||
info.Offset = size
|
info.Offset = size
|
||||||
|
|
||||||
if handler.config.NotifyCompleteUploads {
|
if handler.config.NotifyCompleteUploads {
|
||||||
info.ID = id
|
|
||||||
handler.CompleteUploads <- info
|
handler.CompleteUploads <- info
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -325,6 +325,11 @@ func (handler *UnroutedHandler) PostFile(w http.ResponseWriter, r *http.Request)
|
||||||
handler.sendError(w, r, err)
|
handler.sendError(w, r, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
} else if size == 0 {
|
||||||
|
// Directly finish the upload if the upload is empty (i.e. has a size of 0).
|
||||||
|
// This statement is in an else-if block to avoid causing duplicate calls
|
||||||
|
// to finishUploadIfComplete if an upload is empty and contains a chunk.
|
||||||
|
handler.finishUploadIfComplete(info)
|
||||||
}
|
}
|
||||||
|
|
||||||
handler.sendResp(w, r, http.StatusCreated)
|
handler.sendResp(w, r, http.StatusCreated)
|
||||||
|
@ -381,7 +386,8 @@ func (handler *UnroutedHandler) HeadFile(w http.ResponseWriter, r *http.Request)
|
||||||
handler.sendResp(w, r, http.StatusOK)
|
handler.sendResp(w, r, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PatchFile adds a chunk to an upload. Only allowed enough space is left.
|
// PatchFile adds a chunk to an upload. This operation is only allowed
|
||||||
|
// if enough space in the upload is left.
|
||||||
func (handler *UnroutedHandler) PatchFile(w http.ResponseWriter, r *http.Request) {
|
func (handler *UnroutedHandler) PatchFile(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
// Check for presence of application/offset+octet-stream
|
// Check for presence of application/offset+octet-stream
|
||||||
|
@ -445,7 +451,9 @@ func (handler *UnroutedHandler) PatchFile(w http.ResponseWriter, r *http.Request
|
||||||
handler.sendResp(w, r, http.StatusNoContent)
|
handler.sendResp(w, r, http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PatchFile adds a chunk to an upload. Only allowed enough space is left.
|
// writeChunk reads the body from the requests r and appends it to the upload
|
||||||
|
// with the corresponding id. Afterwards, it will set the necessary response
|
||||||
|
// headers but will not send the response.
|
||||||
func (handler *UnroutedHandler) writeChunk(id string, info FileInfo, w http.ResponseWriter, r *http.Request) error {
|
func (handler *UnroutedHandler) writeChunk(id string, info FileInfo, w http.ResponseWriter, r *http.Request) error {
|
||||||
// Get Content-Length if possible
|
// Get Content-Length if possible
|
||||||
length := r.ContentLength
|
length := r.ContentLength
|
||||||
|
@ -489,19 +497,26 @@ func (handler *UnroutedHandler) writeChunk(id string, info FileInfo, w http.Resp
|
||||||
newOffset := offset + bytesWritten
|
newOffset := offset + bytesWritten
|
||||||
w.Header().Set("Upload-Offset", strconv.FormatInt(newOffset, 10))
|
w.Header().Set("Upload-Offset", strconv.FormatInt(newOffset, 10))
|
||||||
go handler.Metrics.incBytesReceived(uint64(bytesWritten))
|
go handler.Metrics.incBytesReceived(uint64(bytesWritten))
|
||||||
|
info.Offset = newOffset
|
||||||
|
|
||||||
|
return handler.finishUploadIfComplete(info)
|
||||||
|
}
|
||||||
|
|
||||||
|
// finishUploadIfComplete checks whether an upload is completed (i.e. upload offset
|
||||||
|
// matches upload size) and if so, it will call the data store's FinishUpload
|
||||||
|
// function and send the necessary message on the CompleteUpload channel.
|
||||||
|
func (handler *UnroutedHandler) finishUploadIfComplete(info FileInfo) error {
|
||||||
// If the upload is completed, ...
|
// If the upload is completed, ...
|
||||||
if newOffset == info.Size {
|
if info.Offset == info.Size {
|
||||||
// ... allow custom mechanism to finish and cleanup the upload
|
// ... allow custom mechanism to finish and cleanup the upload
|
||||||
if handler.composer.UsesFinisher {
|
if handler.composer.UsesFinisher {
|
||||||
if err := handler.composer.Finisher.FinishUpload(id); err != nil {
|
if err := handler.composer.Finisher.FinishUpload(info.ID); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... send the info out to the channel
|
// ... send the info out to the channel
|
||||||
if handler.config.NotifyCompleteUploads {
|
if handler.config.NotifyCompleteUploads {
|
||||||
info.Offset = newOffset
|
|
||||||
handler.CompleteUploads <- info
|
handler.CompleteUploads <- info
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue