diff --git a/pkg/handlers/archive.go b/pkg/handlers/archive.go index d46016656222..b1257be7e3c7 100644 --- a/pkg/handlers/archive.go +++ b/pkg/handlers/archive.go @@ -78,7 +78,7 @@ func (a *Archive) FromFile(originalCtx context.Context, data io.Reader) chan []b if errors.Is(err, archiver.ErrNoMatch) { return } - logger.V(2).Info("Error unarchiving chunk.") + logger.Error(err, "error unarchiving chunk.") } }() return archiveChan diff --git a/pkg/handlers/archive_test.go b/pkg/handlers/archive_test.go index f70eab293a1f..5c371faa642b 100644 --- a/pkg/handlers/archive_test.go +++ b/pkg/handlers/archive_test.go @@ -9,6 +9,7 @@ import ( "regexp" "strings" "testing" + "time" diskbufferreader "github.com/bill-rich/disk-buffer-reader" "github.com/stretchr/testify/assert" @@ -248,3 +249,25 @@ func TestOpenInvalidArchive(t *testing.T) { err := a.openArchive(ctx, 0, reader, archiveChan) assert.Error(t, err) } + +func TestNestedDirArchive(t *testing.T) { + file, err := os.Open("testdata/dir-archive.zip") + assert.Nil(t, err) + defer file.Close() + + ctx, cancel := logContext.WithTimeout(logContext.Background(), 5*time.Second) + defer cancel() + sourceChan := make(chan *sources.Chunk, 1) + + go func() { + defer close(sourceChan) + HandleFile(ctx, file, &sources.Chunk{}, sourceChan) + }() + + count := 0 + want := 4 + for range sourceChan { + count++ + } + assert.Equal(t, want, count) +} diff --git a/pkg/handlers/handlers.go b/pkg/handlers/handlers.go index cce0fe1bf0d0..5ff59a7a766f 100644 --- a/pkg/handlers/handlers.go +++ b/pkg/handlers/handlers.go @@ -47,40 +47,42 @@ func HandleFile(ctx context.Context, file io.Reader, chunkSkel *sources.Chunk, c // an io.MultiReader, which is used by the SpecializedHandler. reReader, err := diskbufferreader.New(file) if err != nil { - aCtx.Logger().Error(err, "error creating re-reader reader") + aCtx.Logger().Error(err, "error creating reusable reader") return false } - defer reReader.Close() - // Check if the handler implements SpecializedHandler and process accordingly. - if specialHandler, ok := h.(SpecializedHandler); ok { - file, isSpecial, err := specialHandler.HandleSpecialized(aCtx, reReader) - if isSpecial { - return handleChunks(aCtx, h.FromFile(ctx, file), chunkSkel, chunksChan) - } - - if err != nil { - aCtx.Logger().Error(err, "error handling file") - } + if success := processHandler(aCtx, h, reReader, chunkSkel, chunksChan); success { + return true } + } - if err := reReader.Reset(); err != nil { - aCtx.Logger().Error(err, "error resetting re-reader") - return false + return false +} + +func processHandler(ctx logContext.Context, h Handler, reReader *diskbufferreader.DiskBufferReader, chunkSkel *sources.Chunk, chunksChan chan *sources.Chunk) bool { + defer reReader.Close() + defer reReader.Stop() + + if specialHandler, ok := h.(SpecializedHandler); ok { + file, isSpecial, err := specialHandler.HandleSpecialized(ctx, reReader) + if isSpecial { + return handleChunks(ctx, h.FromFile(ctx, file), chunkSkel, chunksChan) } - if _, isType := h.IsFiletype(aCtx, reReader); !isType { - continue + if err != nil { + ctx.Logger().Error(err, "error handling file") } + } - if err := reReader.Reset(); err != nil { - aCtx.Logger().Error(err, "error resetting re-reader") - return false - } - reReader.Stop() - return handleChunks(aCtx, h.FromFile(ctx, reReader), chunkSkel, chunksChan) + if _, err := reReader.Seek(0, io.SeekStart); err != nil { + ctx.Logger().Error(err, "error seeking to start of file") + return false } - return false + if _, isType := h.IsFiletype(ctx, reReader); !isType { + return false + } + + return handleChunks(ctx, h.FromFile(ctx, reReader), chunkSkel, chunksChan) } func handleChunks(ctx context.Context, handlerChan chan []byte, chunkSkel *sources.Chunk, chunksChan chan *sources.Chunk) bool { diff --git a/pkg/handlers/testdata/dir-archive.zip b/pkg/handlers/testdata/dir-archive.zip new file mode 100644 index 000000000000..501eee4e6296 Binary files /dev/null and b/pkg/handlers/testdata/dir-archive.zip differ