Skip to content

Commit b3ba87f

Browse files
author
Marius
authored
filestore: Expose .info path and fix absolute paths (#1162)
* filestore: Allow providing custom, absolute paths * filestore: Expose path to `.info` file in hooks
1 parent 585d7a5 commit b3ba87f

File tree

3 files changed

+64
-9
lines changed

3 files changed

+64
-9
lines changed

docs/_advanced-topics/hooks.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,11 @@ Below you can find an annotated, JSON-ish encoded example of a hook request:
8383
// Storage contains information about where the upload is stored. The exact values
8484
// depend on the storage that is used and are not available in the pre-create hook.
8585
"Storage": {
86-
// For example, the filestore supplies the absolute file path:
86+
// For example, the filestore supplies the absolute file paths where the upload data
87+
// (Path) and the associated info file (InfoPath) are stored:
8788
"Type": "filestore",
8889
"Path": "/my/upload/directory/14b1c4c77771671a8479bc0444bbc5ce",
90+
"InfoPath": "/my/upload/directory/14b1c4c77771671a8479bc0444bbc5ce.info",
8991

9092
// The S3Store and GCSStore supply the bucket name and object key:
9193
"Type": "s3store",

pkg/filestore/filestore.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,22 @@ func (store FileStore) NewUpload(ctx context.Context, info handler.FileInfo) (ha
6262
// The binary file's location might be modified by the pre-create hook.
6363
var binPath string
6464
if info.Storage != nil && info.Storage["Path"] != "" {
65-
binPath = filepath.Join(store.Path, info.Storage["Path"])
65+
// filepath.Join treats absolute and relative paths the same, so we must
66+
// handle them on our own. Absolute paths get used as-is, while relative
67+
// paths are joined to the storage path.
68+
if filepath.IsAbs(info.Storage["Path"]) {
69+
binPath = info.Storage["Path"]
70+
} else {
71+
binPath = filepath.Join(store.Path, info.Storage["Path"])
72+
}
6673
} else {
6774
binPath = store.defaultBinPath(info.ID)
6875
}
6976

7077
info.Storage = map[string]string{
71-
"Type": "filestore",
72-
"Path": binPath,
78+
"Type": "filestore",
79+
"Path": binPath,
80+
"InfoPath": infoPath,
7381
}
7482

7583
// Create binary file with no content

pkg/filestore/filestore_test.go

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,10 @@ func TestFilestore(t *testing.T) {
4343
a.EqualValues(42, info.Size)
4444
a.EqualValues(0, info.Offset)
4545
a.Equal(handler.MetaData{"hello": "world"}, info.MetaData)
46-
a.Equal(2, len(info.Storage))
46+
a.Equal(3, len(info.Storage))
4747
a.Equal("filestore", info.Storage["Type"])
4848
a.Equal(filepath.Join(tmp, info.ID), info.Storage["Path"])
49+
a.Equal(filepath.Join(tmp, info.ID+".info"), info.Storage["InfoPath"])
4950

5051
// Write data to upload
5152
bytesWritten, err := upload.WriteChunk(ctx, 0, strings.NewReader("hello world"))
@@ -104,9 +105,10 @@ func TestCreateDirectories(t *testing.T) {
104105
a.EqualValues(42, info.Size)
105106
a.EqualValues(0, info.Offset)
106107
a.Equal(handler.MetaData{"hello": "world"}, info.MetaData)
107-
a.Equal(2, len(info.Storage))
108+
a.Equal(3, len(info.Storage))
108109
a.Equal("filestore", info.Storage["Type"])
109110
a.Equal(filepath.Join(tmp, info.ID), info.Storage["Path"])
111+
a.Equal(filepath.Join(tmp, info.ID+".info"), info.Storage["InfoPath"])
110112

111113
// Write data to upload
112114
bytesWritten, err := upload.WriteChunk(ctx, 0, strings.NewReader("hello world"))
@@ -246,8 +248,9 @@ func TestDeclareLength(t *testing.T) {
246248
a.Equal(false, updatedInfo.SizeIsDeferred)
247249
}
248250

249-
// TestCustomPath tests whether the upload's destination can be customized.
250-
func TestCustomPath(t *testing.T) {
251+
// TestCustomRelativePath tests whether the upload's destination can be customized
252+
// relative to the storage directory.
253+
func TestCustomRelativePath(t *testing.T) {
251254
a := assert.New(t)
252255

253256
tmp, err := os.MkdirTemp("", "tusd-filestore-")
@@ -272,9 +275,10 @@ func TestCustomPath(t *testing.T) {
272275
a.NoError(err)
273276
a.EqualValues(42, info.Size)
274277
a.EqualValues(0, info.Offset)
275-
a.Equal(2, len(info.Storage))
278+
a.Equal(3, len(info.Storage))
276279
a.Equal("filestore", info.Storage["Type"])
277280
a.Equal(filepath.Join(tmp, "./folder2/bin"), info.Storage["Path"])
281+
a.Equal(filepath.Join(tmp, "./folder1/info.info"), info.Storage["InfoPath"])
278282

279283
// Write data to upload
280284
bytesWritten, err := upload.WriteChunk(ctx, 0, strings.NewReader("hello world"))
@@ -313,3 +317,44 @@ func TestCustomPath(t *testing.T) {
313317
a.Equal(nil, upload)
314318
a.Equal(handler.ErrNotFound, err)
315319
}
320+
321+
// TestCustomAbsolutePath tests whether the upload's destination can be customized
322+
// using an absolute path to the storage directory.
323+
func TestCustomAbsolutePath(t *testing.T) {
324+
a := assert.New(t)
325+
326+
tmp1, err := os.MkdirTemp("", "tusd-filestore-")
327+
a.NoError(err)
328+
329+
tmp2, err := os.MkdirTemp("", "tusd-filestore-")
330+
a.NoError(err)
331+
332+
store := FileStore{tmp1}
333+
ctx := context.Background()
334+
335+
// Create new upload, but the Path property points to a directory
336+
// outside of the directory given to FileStore
337+
binPath := filepath.Join(tmp2, "dir/my-upload.bin")
338+
upload, err := store.NewUpload(ctx, handler.FileInfo{
339+
ID: "my-upload",
340+
Size: 42,
341+
Storage: map[string]string{
342+
"Path": binPath,
343+
},
344+
})
345+
a.NoError(err)
346+
a.NotEqual(nil, upload)
347+
348+
info, err := upload.GetInfo(ctx)
349+
a.NoError(err)
350+
a.EqualValues(42, info.Size)
351+
a.EqualValues(0, info.Offset)
352+
a.Equal(3, len(info.Storage))
353+
a.Equal("filestore", info.Storage["Type"])
354+
a.Equal(binPath, info.Storage["Path"])
355+
a.Equal(filepath.Join(tmp1, "my-upload.info"), info.Storage["InfoPath"])
356+
357+
statInfo, err := os.Stat(binPath)
358+
a.NoError(err)
359+
a.True(statInfo.Mode().IsRegular())
360+
}

0 commit comments

Comments
 (0)