mimetype: github.com/gabriel-vasile/mimetype Index | Examples | Files | Directories

package mimetype

import "github.com/gabriel-vasile/mimetype"

Package mimetype uses magic number signatures to detect the MIME type of a file.

mimetype stores the list of MIME types in a tree structure with "application/octet-stream" at the root of the hierarchy. The hierarchy approach minimizes the number of checks that need to be done on the input and allows for more precise results once the base type of file has been identified.

To check if some bytes/reader/file has a specific MIME type, first perform a detect on the input and then test against the MIME.

Is method can also be called with MIME aliases.

Code:

mime, err := mimetype.DetectFile("testdata/zip.zip")
// application/x-zip is an alias of application/zip,
// therefore Is returns true both times.
fmt.Println(mime.Is("application/zip"), mime.Is("application/x-zip"), err)

Output:

true true <nil>

To find the MIME type of some input, perform a detect. In addition to the basic Detect,

mimetype.Detect([]byte) *MIME

there are shortcuts for detecting from a reader:

mimetype.DetectReader(io.Reader) (*MIME, error)

or from a file:

mimetype.DetectFile(string) (*MIME, error)

Code:

file := "testdata/pdf.pdf"

// Detect the MIME type of a file stored as a byte slice.
data, _ := ioutil.ReadFile(file) // ignoring error for brevity's sake
mime := mimetype.Detect(data)
fmt.Println(mime.String(), mime.Extension())

// Detect the MIME type of a reader.
reader, _ := os.Open(file) // ignoring error for brevity's sake
mime, rerr := mimetype.DetectReader(reader)
fmt.Println(mime.String(), mime.Extension(), rerr)

// Detect the MIME type of a file.
mime, ferr := mimetype.DetectFile(file)
fmt.Println(mime.String(), mime.Extension(), ferr)

Output:

application/pdf .pdf
application/pdf .pdf <nil>
application/pdf .pdf <nil>

It may happen that the returned MIME type is more accurate than needed.

Suppose we have a text file containing HTML code. Detection performed on this file will retrieve the `text/html` MIME. If you are interested in telling if the input can be used as a text file, you can walk up the MIME hierarchy until `text/plain` is found.

Remember to always check for nil before using the result of the Parent() method.

          .Parent()              .Parent()
text/html ----------> text/plain ----------> application/octet-stream

Code:

detectedMIME, err := mimetype.DetectFile("testdata/html.html")

isText := false
for mime := detectedMIME; mime != nil; mime = mime.Parent() {
    if mime.Is("text/plain") {
        isText = true
    }
}

// isText is true, even if the detected MIME was text/html.
fmt.Println(isText, detectedMIME, err)

Output:

true text/html; charset=utf-8 <nil>

Considering the definition of a binary file as "a computer file that is not a text file", they can differentiated by searching for the text/plain MIME in it's MIME hierarchy.

Code:

detectedMIME, err := mimetype.DetectFile("testdata/xml.xml")

isBinary := true
for mime := detectedMIME; mime != nil; mime = mime.Parent() {
    if mime.Is("text/plain") {
        isBinary = false
    }
}

fmt.Println(isBinary, detectedMIME, err)

Output:

false text/xml; charset=utf-8 <nil>

Index

Examples

Package Files

mime.go mimetype.go tree.go

type MIME Uses

type MIME struct {
    // contains filtered or unexported fields
}

MIME struct holds information about a file format: the string representation of the MIME type, the extension and the parent file format.

This struct should not be instantiated by clients. It is exposed purely for documentation purposes.

func Detect Uses

func Detect(in []byte) (mime *MIME)

Detect returns the MIME type found from the provided byte slice.

The result is always a valid MIME type, with application/octet-stream returned when identification failed.

Code:

data, err := ioutil.ReadFile("testdata/zip.zip")
mime := mimetype.Detect(data)

fmt.Println(mime.String(), err)

Output:

application/zip <nil>

func DetectFile Uses

func DetectFile(file string) (mime *MIME, err error)

DetectFile returns the MIME type of the provided file.

The result is always a valid MIME type, with application/octet-stream returned when identification failed with or without an error. Any error returned is related to the opening and reading from the input file.

To prevent loading entire files into memory, DetectFile reads at most matchers.ReadLimit bytes from the reader.

Code:

mime, err := mimetype.DetectFile("testdata/zip.zip")

fmt.Println(mime.String(), err)

Output:

application/zip <nil>

func DetectReader Uses

func DetectReader(r io.Reader) (mime *MIME, err error)

DetectReader returns the MIME type of the provided reader.

The result is always a valid MIME type, with application/octet-stream returned when identification failed with or without an error. Any error returned is related to the reading from the input reader.

DetectReader assumes the reader offset is at the start. If the input is a ReadSeeker you read from before, it should be rewinded before detection:

reader.Seek(0, io.SeekStart)

To prevent loading entire files into memory, DetectReader reads at most matchers.ReadLimit bytes from the reader.

Code:

data, oerr := os.Open("testdata/zip.zip")
mime, merr := mimetype.DetectReader(data)

fmt.Println(mime.String(), oerr, merr)

Output:

application/zip <nil> <nil>

func (*MIME) Extension Uses

func (n *MIME) Extension() string

Extension returns the file extension associated with the MIME type. It includes the leading dot, as in ".html". When the file format does not have an extension, the empty string is returned.

func (*MIME) Is Uses

func (n *MIME) Is(expectedMIME string) bool

Is checks whether this MIME type, or any of its aliases, is equal to the expected MIME type. MIME type equality test is done on the "type/subtype" sections, ignores any optional MIME parameters, ignores any leading and trailing whitespace, and is case insensitive.

Code:

mime, err := mimetype.DetectFile("testdata/pdf.pdf")

pdf := mime.Is("application/pdf")
xpdf := mime.Is("application/x-pdf")
txt := mime.Is("text/plain")
fmt.Println(pdf, xpdf, txt, err)

Output:

true true false <nil>

func (*MIME) Parent Uses

func (n *MIME) Parent() *MIME

Parent returns the parent MIME type from the hierarchy. Each MIME type has a non-nil parent, except for the root MIME type.

For example, the application/json and text/html MIME types have text/plain as their parent because they are text files who happen to contain JSON or HTML. Another example is the ZIP format, which is used as container for Microsoft Office files, EPUB files, JAR files and others.

func (*MIME) String Uses

func (n *MIME) String() string

String returns the string representation of the MIME type, e.g., "application/zip".

Directories

PathSynopsis
internal/jsonPackage json provides a JSON value parser state machine.
internal/matchersPackage matchers holds the matching functions used to find MIME types.

Package mimetype imports 4 packages (graph) and is imported by 84 packages. Updated 2020-02-24. Refresh now. Tools for package owners.