Skip to content

Commit 06614de

Browse files
authored
server(filesystem): handle individual compressed files (#184)
1 parent 2b0e353 commit 06614de

File tree

1 file changed

+65
-1
lines changed

1 file changed

+65
-1
lines changed

server/filesystem/compress.go

+65-1
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ func (fs *Filesystem) DecompressFile(ctx context.Context, dir string, file strin
156156
}
157157

158158
return fs.extractStream(ctx, extractStreamOptions{
159+
FileName: file,
159160
Directory: dir,
160161
Format: format,
161162
Reader: input,
@@ -190,11 +191,74 @@ type extractStreamOptions struct {
190191
}
191192

192193
func (fs *Filesystem) extractStream(ctx context.Context, opts extractStreamOptions) error {
193-
// Decompress and extract archive
194+
195+
// See if it's a compressed archive, such as TAR or a ZIP
194196
ex, ok := opts.Format.(archiver.Extractor)
195197
if !ok {
198+
199+
// If not, check if it's a single-file compression, such as
200+
// .log.gz, .sql.gz, and so on
201+
de, ok := opts.Format.(archiver.Decompressor)
202+
if !ok {
203+
return nil
204+
}
205+
206+
// Strip the compression suffix
207+
p := filepath.Join(opts.Directory, strings.TrimSuffix(opts.FileName, opts.Format.Name()))
208+
209+
// Make sure it's not ignored
210+
if err := fs.IsIgnored(p); err != nil {
211+
return nil
212+
}
213+
214+
reader, err := de.OpenReader(opts.Reader)
215+
if err != nil {
216+
return err
217+
}
218+
defer reader.Close()
219+
220+
// Open the file for creation/writing
221+
f, err := fs.unixFS.OpenFile(p, ufs.O_WRONLY|ufs.O_CREATE, 0o644)
222+
if err != nil {
223+
return err
224+
}
225+
defer f.Close()
226+
227+
// Read in 4 KB chunks
228+
buf := make([]byte, 4096)
229+
for {
230+
n, err := reader.Read(buf)
231+
if n > 0 {
232+
233+
// Check quota before writing the chunk
234+
if quotaErr := fs.HasSpaceFor(int64(n)); quotaErr != nil {
235+
return quotaErr
236+
}
237+
238+
// Write the chunk
239+
if _, writeErr := f.Write(buf[:n]); writeErr != nil {
240+
return writeErr
241+
}
242+
243+
// Add to quota
244+
fs.addDisk(int64(n))
245+
}
246+
247+
if err != nil {
248+
// EOF are expected
249+
if err == io.EOF {
250+
break
251+
}
252+
253+
// Return any other
254+
return err
255+
}
256+
}
257+
196258
return nil
197259
}
260+
261+
// Decompress and extract archive
198262
return ex.Extract(ctx, opts.Reader, nil, func(ctx context.Context, f archiver.File) error {
199263
if f.IsDir() {
200264
return nil

0 commit comments

Comments
 (0)