1
1
package azurestore
2
2
3
3
import (
4
- "bufio"
5
4
"bytes"
6
5
"context"
7
- "encoding/binary"
8
6
"encoding/json"
7
+ "errors"
9
8
"fmt"
10
9
"io"
10
+ "io/fs"
11
+ "os"
11
12
"strings"
12
13
13
14
"github.com/tus/tusd/v2/internal/uid"
@@ -18,13 +19,20 @@ type AzureStore struct {
18
19
Service AzService
19
20
ObjectPrefix string
20
21
Container string
22
+
23
+ // TemporaryDirectory is the path where AzureStore will create temporary files
24
+ // on disk during the upload. An empty string ("", the default value) will
25
+ // cause AzureStore to use the operating system's default temporary directory.
26
+ TemporaryDirectory string
21
27
}
22
28
23
29
type AzUpload struct {
24
30
ID string
25
31
InfoBlob AzBlob
26
32
BlockBlob AzBlob
27
33
InfoHandler * handler.FileInfo
34
+
35
+ tempDir string
28
36
}
29
37
30
38
func New (service AzService ) * AzureStore {
@@ -73,6 +81,7 @@ func (store AzureStore) NewUpload(ctx context.Context, info handler.FileInfo) (h
73
81
InfoHandler : & info ,
74
82
InfoBlob : infoBlob ,
75
83
BlockBlob : blockBlob ,
84
+ tempDir : store .TemporaryDirectory ,
76
85
}
77
86
78
87
err = azUpload .writeInfo (ctx )
@@ -128,6 +137,7 @@ func (store AzureStore) GetUpload(ctx context.Context, id string) (handler.Uploa
128
137
InfoHandler : & info ,
129
138
InfoBlob : infoBlob ,
130
139
BlockBlob : blockBlob ,
140
+ tempDir : store .TemporaryDirectory ,
131
141
}, nil
132
142
}
133
143
@@ -140,21 +150,38 @@ func (store AzureStore) AsLengthDeclarableUpload(upload handler.Upload) handler.
140
150
}
141
151
142
152
func (upload * AzUpload ) WriteChunk (ctx context.Context , offset int64 , src io.Reader ) (int64 , error ) {
143
- r := bufio .NewReader (src )
144
- buf := new (bytes.Buffer )
145
- n , err := r .WriteTo (buf )
153
+ // Create a temporary file for holding the uploaded data
154
+ file , err := os .CreateTemp (upload .tempDir , "tusd-az-tmp-" )
155
+ if err != nil {
156
+ return 0 , err
157
+ }
158
+ defer os .Remove (file .Name ())
159
+
160
+ // Copy the entire request body into the file
161
+ n , err := io .Copy (file , src )
146
162
if err != nil {
163
+ file .Close ()
147
164
return 0 , err
148
165
}
149
166
150
- chunkSize := int64 (binary .Size (buf .Bytes ()))
151
- if chunkSize > MaxBlockBlobChunkSize {
152
- return 0 , fmt .Errorf ("azurestore: Chunk of size %v too large. Max chunk size is %v" , chunkSize , MaxBlockBlobChunkSize )
167
+ // Seek to the beginning
168
+ if _ , err := file .Seek (0 , 0 ); err != nil {
169
+ file .Close ()
170
+ return 0 , err
171
+ }
172
+
173
+ if n > MaxBlockBlobChunkSize {
174
+ file .Close ()
175
+ return 0 , fmt .Errorf ("azurestore: Chunk of size %v too large. Max chunk size is %v" , n , MaxBlockBlobChunkSize )
153
176
}
154
177
155
- re := bytes .NewReader (buf .Bytes ())
156
- err = upload .BlockBlob .Upload (ctx , re )
178
+ err = upload .BlockBlob .Upload (ctx , file )
157
179
if err != nil {
180
+ file .Close ()
181
+ return 0 , err
182
+ }
183
+
184
+ if err := file .Close (); err != nil && ! errors .Is (err , fs .ErrClosed ) {
158
185
return 0 , err
159
186
}
160
187
0 commit comments