gabriel-vasile / mimetype

A fast Golang library for media type and file extension detection, based on magic numbers
https://pkg.go.dev/github.com/gabriel-vasile/mimetype#pkg-overview
MIT License
1.63k stars 162 forks source link

Add ReaderDetector to use a non global limit #510

Closed ctunon-align closed 5 months ago

ctunon-align commented 5 months ago

Hello!

Im currently using this library in a server and stumbled upon the issue about the msword files being detected as x-ole-storage files due to them having the file type signature at the end. The SetLimit function seems to be modifying a global limit variable. Since I want to avoid reading the whole file if I dont need to, I added a struct to hold a separated limit.

I would like to be able to do stuff like this:

        reader, err := fileData()
    if err != nil {
        return nil, err
    }
    defer reader.Close()

    mime, err := mimetype.DetectReader(reader)
    if err != nil {
        return nil, err
    }

    // If catch all mime type, use greedy detector.
    if mime.String() == "application/x-ole-storage" {
        reader, err := fileData()
        if err != nil {
            return nil, err
        }
        defer reader.Close()
        return NewReaderDetector(0).Detect(reader)
    }
gabriel-vasile commented 5 months ago

I'll have to refuse this PR. I'm not sure about exposing more APIs. There is an issue that might bite library users and I would like fixing it before adding more functions. I have a rough idea how to proceed, but I just didn't have the time for it.

In the meantime I think something like this can solve your problem:

shortRead := 3000
longRead := 10*shortRead
mimetype.SetLimit(longRead)

mime, _ := mimetype.DetectReader(io.LimitReader(r, shortRead))
if mime.Is("application/x-ole-storage") {
    mime, _ := mimetype.DetectReader(io.LimitReader(r, longRead))
}
ctunon-align commented 5 months ago

Totally understandable. Thank you so much for providing a workaround tho. Wasn't aware of that io.LimitReader.