Skip to content

Commit

Permalink
Centralize logic for checking archive extraction tools (#2063)
Browse files Browse the repository at this point in the history
* Centralize logic for checking archive extraction tools

* simplify
  • Loading branch information
ahrav authored Oct 31, 2023
1 parent 57203a5 commit a9b056d
Showing 1 changed file with 26 additions and 19 deletions.
45 changes: 26 additions & 19 deletions pkg/handlers/archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,36 +233,45 @@ func (a *Archive) ReadToMax(ctx context.Context, reader io.Reader) (data []byte,
return fileContent.Bytes(), nil
}

type mimeType string

const (
arMimeType = "application/x-unix-archive"
rpmMimeType = "application/x-rpm"
arMimeType mimeType = "application/x-unix-archive"
rpmMimeType mimeType = "application/x-rpm"
)

// Define a map of mime types to corresponding command-line tools
var mimeTools = map[string][]string{
// mimeTools maps MIME types to the necessary command-line tools to handle them.
// This centralizes the tool requirements for different file types.
var mimeTools = map[mimeType][]string{
arMimeType: {"ar"},
rpmMimeType: {"rpm2cpio", "cpio"},
}

// Check if the command-line tool is installed.
func isToolInstalled(tool string) bool {
_, err := exec.LookPath(tool)
return err == nil
// extractToolCache stores the availability of extraction tools, eliminating the need for repeated filesystem lookups.
var extractToolCache map[string]bool

func init() {
// Preload the extractToolCache with the availability status of each required tool.
extractToolCache = make(map[string]bool)
for _, tools := range mimeTools {
for _, tool := range tools {
_, err := exec.LookPath(tool)
extractToolCache[tool] = err == nil
}
}
}

// Ensure all tools are available for given mime type.
func ensureToolsForMimeType(mimeType string) error {
func ensureToolsForMimeType(mimeType mimeType) error {
tools, exists := mimeTools[mimeType]
if !exists {
return fmt.Errorf("unsupported mime type")
return fmt.Errorf("unsupported mime type: %s", mimeType)
}

for _, tool := range tools {
if !isToolInstalled(tool) {
return fmt.Errorf("Required tool " + tool + " is not installed")
if installed := extractToolCache[tool]; !installed {
return fmt.Errorf("required tool %s is not installed", tool)
}
}

return nil
}

Expand Down Expand Up @@ -389,9 +398,7 @@ func (a *Archive) handleNestedFileMIME(ctx logContext.Context, tempEnv tempEnv,
}

switch mimeType {
case arMimeType:
_, _, err = a.HandleSpecialized(ctx, reader)
case rpmMimeType:
case arMimeType, rpmMimeType:
_, _, err = a.HandleSpecialized(ctx, reader)
default:
return "", nil
Expand All @@ -406,7 +413,7 @@ func (a *Archive) handleNestedFileMIME(ctx logContext.Context, tempEnv tempEnv,

// determineMimeType reads from the provided reader to detect the MIME type.
// It returns the detected MIME type and a new reader that includes the read portion.
func determineMimeType(reader io.Reader) (string, io.Reader, error) {
func determineMimeType(reader io.Reader) (mimeType, io.Reader, error) {
buffer := make([]byte, 512)
n, err := reader.Read(buffer)
if err != nil {
Expand All @@ -422,7 +429,7 @@ func determineMimeType(reader io.Reader) (string, io.Reader, error) {
return "", nil, fmt.Errorf("unable to determine file type: %w", err)
}

return kind.MIME.Value, reader, nil
return mimeType(kind.MIME.Value), reader, nil
}

// handleExtractedFiles processes each file in the extracted directory using a provided handler function.
Expand Down

0 comments on commit a9b056d

Please sign in to comment.