vendor: update dependencies for press

This commit is contained in:
buengese 2020-02-11 16:11:35 +01:00
parent 0cf94ae6ac
commit ae06b050a4
36 changed files with 1306 additions and 701 deletions

7
go.mod
View file

@ -7,6 +7,7 @@ require (
github.com/Azure/azure-storage-blob-go v0.8.0
github.com/Azure/go-autorest/autorest/adal v0.6.0 // indirect
github.com/Unknwon/goconfig v0.0.0-20191126170842-860a72fb44fd
github.com/OneOfOne/xxhash v1.2.7
github.com/a8m/tree v0.0.0-20181222104329-6a0b80129de4
github.com/abbot/go-http-auth v0.4.0
github.com/anacrolix/dms v1.1.0
@ -15,10 +16,16 @@ require (
github.com/billziss-gh/cgofuse v1.2.0
github.com/djherbis/times v1.2.0
github.com/dropbox/dropbox-sdk-go-unofficial v5.6.0+incompatible
github.com/etcd-io/bbolt v1.3.3
github.com/gabriel-vasile/mimetype v1.0.2
github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 // indirect
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db
github.com/google/go-cmp v0.3.1 // indirect
github.com/google/go-querystring v1.0.0 // indirect
github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f // indirect
github.com/hanwen/go-fuse/v2 v2.0.3-0.20191108143333-152e6ac32d54
github.com/jlaffaye/ftp v0.0.0-20191218041957-e1b8fdd0dcc3
github.com/id01/go-lz4 v1.0.3
github.com/jzelinskie/whirlpool v0.0.0-20170603002051-c19460b8caa6
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect

8
go.sum
View file

@ -42,7 +42,8 @@ github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbt
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/OneOfOne/xxhash v1.2.7 h1:fzrmmkskv067ZQbd9wERNGuxckWw67dyzoMG62p7LMo=
github.com/OneOfOne/xxhash v1.2.7/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
github.com/RoaringBitmap/roaring v0.4.7/go.mod h1:8khRDP4HmeXns4xIj9oGrKSz7XTQiJx2zgh7AcNke4w=
github.com/Unknwon/goconfig v0.0.0-20191126170842-860a72fb44fd h1:+CYOsXi89xOqBkj7CuEJjA2It+j+R3ngUZEydr6mtkw=
github.com/Unknwon/goconfig v0.0.0-20191126170842-860a72fb44fd/go.mod h1:wngxua9XCNjvHjDiTiV26DaKDT+0c63QR6H5hjVUUxw=
@ -109,6 +110,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gabriel-vasile/mimetype v1.0.2 h1:GKCo1TUCg0pV0R4atTcaLv/9SI2W9xPgMySZxUxcJOE=
github.com/gabriel-vasile/mimetype v1.0.2/go.mod h1:6CDPel/o/3/s4+bp6kIbsWATq8pmgOisOPG40CJa6To=
github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
github.com/glycerine/goconvey v0.0.0-20180728074245-46e3a41ad493/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
@ -140,6 +143,7 @@ github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180124185431-e89373fe6b4a/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@ -182,6 +186,8 @@ github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/id01/go-lz4 v1.0.3 h1:D3krbAf5BppFsRSVa75yFo+JMxlTqFwuYpyHQAOgYds=
github.com/id01/go-lz4 v1.0.3/go.mod h1:G8scWkW5nw6fEwIREHZcWy3qddP/Go9IImmcit+bTzw=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jlaffaye/ftp v0.0.0-20190624084859-c1312a7102bf/go.mod h1:lli8NYPQOFy3O++YmYbqVgOcQ1JPCwdOy+5zSjKJ9qY=

View file

@ -1,5 +1,7 @@
package xxhash
import "hash"
const (
prime32x1 uint32 = 2654435761
prime32x2 uint32 = 2246822519
@ -22,6 +24,9 @@ const (
zero64x4 = 0x61c8864e7a143579
)
func NewHash32() hash.Hash { return New32() }
func NewHash64() hash.Hash { return New64() }
// Checksum32 returns the checksum of the input data with the seed set to 0.
func Checksum32(in []byte) uint32 {
return Checksum32S(in, 0)

View file

@ -49,9 +49,10 @@ func (xx *XXHash64) WriteString(s string) (int, error) {
return 0, nil
}
ss := (*reflect.StringHeader)(unsafe.Pointer(&s))
return xx.Write((*[maxInt32]byte)(unsafe.Pointer(ss.Data))[:len(s)])
return xx.Write((*[maxInt32]byte)(unsafe.Pointer(ss.Data))[:len(s):len(s)])
}
//go:nocheckptr
func checksum64(in []byte, seed uint64) uint64 {
var (
wordsLen = len(in) >> 3
@ -103,6 +104,7 @@ func checksum64(in []byte, seed uint64) uint64 {
return mix64(h)
}
//go:nocheckptr
func checksum64Short(in []byte, seed uint64) uint64 {
var (
h = seed + prime64x5 + uint64(len(in))

View file

@ -0,0 +1 @@
testdata/* linguist-vendored

14
vendor/github.com/gabriel-vasile/mimetype/.travis.yml generated vendored Normal file
View file

@ -0,0 +1,14 @@
language: go
go:
- "1.12"
- "master"
before_install:
- go get github.com/mattn/goveralls
- go get github.com/client9/misspell/cmd/misspell
before_script:
- go vet .
script:
- diff -u <(echo -n) <(gofmt -d ./)
- go test -v
- $GOPATH/bin/goveralls -service=travis-ci
- misspell -locale US -error *.md *.go

79
vendor/github.com/gabriel-vasile/mimetype/EXAMPLES.md generated vendored Normal file
View file

@ -0,0 +1,79 @@
## Examples
- [Detect MIME type](#detect)
- [Check against MIME type](#check)
- [Check base MIME type](#check-parent)
- [Binary file vs text file](#binary-file-vs-text-file)
### Detect
Get the MIME type from a slice of bytes, from a reader and from a file.
```go
// Detect the MIME type of a file stored as a byte slice.
file := "testdata/pdf.pdf"
// Detect the MIME type of a file.
mime, ferr := mimetype.DetectFile(file)
fmt.Println(mime, ferr)
// Output: application/pdf nil
// 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, rerr)
// Output: application/pdf nil
mime := mimetype.Detect(data)
fmt.Println(mime)
// Output: application/pdf
```
### Check
Test if a file has a specific MIME type. Also accepts MIME type aliases.
```go
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>
```
### Check parent
Test if a file has a specific base MIME type. First perform a detect on the
input and then navigate the parents until the base MIME type is found.
Considering JAR files are just ZIPs containing some metadata files,
if, for example, you need to tell if the input can be unzipped, go up the
MIME hierarchy until zip is found or the root is reached.
```go
detectedMIME, err := mimetype.DetectFile("testdata/jar.jar")
zip := false
for mime := detectedMIME; mime != nil; mime = mime.Parent() {
if mime.Is("application/zip") {
zip = true
}
}
// zip is true, even if the detected MIME was application/jar.
fmt.Println(zip, detectedMIME, err)
// Output: true application/jar <nil>
```
### Binary file vs text file
Considering the definition of a binary file as "a computer file that is not
a text file", they can be differentiated by searching for the text/plain MIME
in it's MIME hierarchy.
```go
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>
```

View file

@ -6,7 +6,7 @@
A package for detecting MIME types and extensions based on magic numbers
</h4>
<h6 align="center">
No bindings, all written in pure go
No C bindings, zero dependencies and thread safe
</h6>
<p align="center">
@ -32,30 +32,40 @@
go get github.com/gabriel-vasile/mimetype
```
## Use
The library exposes three functions you can use in order to detect a file type.
See [Godoc](https://godoc.org/github.com/gabriel-vasile/mimetype) for full reference.
```go
func Detect(in []byte) (mime, extension string) {...}
func DetectReader(r io.Reader) (mime, extension string, err error) {...}
func DetectFile(file string) (mime, extension string, err error) {...}
```
When detecting from a `ReadSeeker` interface, such as `os.File`, make sure
to reset the offset of the reader to the beginning if needed:
```go
_, err = file.Seek(0, io.SeekStart)
```
## Usage
There are quick [examples](EXAMPLES.md) and
[GoDoc](https://godoc.org/github.com/gabriel-vasile/mimetype) for full reference.
## Upgrade from v0.3.x to v1.x
In v1.x the detect functions no longer return the MIME type and extension as
strings. Instead they return a [MIME](https://godoc.org/github.com/gabriel-vasile/mimetype#MIME)
struct. To get the string value of the MIME and the extension, call the
`String()` and the `Extension()` methods.
In order to play better with the stdlib `mime` package, v1.x file extensions
include the leading dot, as in ".html".
In v1.x the `text/plain` MIME type is `text/plain; charset=utf-8`.
## Supported MIME types
See [supported mimes](supported_mimes.md) for the list of detected MIME types.
If support is needed for a specific file format, please open an [issue](https://github.com/gabriel-vasile/mimetype/issues/new/choose).
## Structure
**mimetype** uses an hierarchical structure to keep the matching functions.
**mimetype** uses an hierarchical structure to keep the MIME type detection logic.
This reduces the number of calls needed for detecting the file type. The reason
behind this choice is that there are file formats used as containers for other
file formats. For example, Microsoft office files are just zip archives,
containing specific metadata files.
file formats. For example, Microsoft Office files are just zip archives,
containing specific metadata files. Once a file a file has been identified as a
zip, there is no need to check if it is a text file, but it is worth checking if
it is an Microsoft Office file.
To prevent loading entire files into memory, when detecting from a
[reader](https://godoc.org/github.com/gabriel-vasile/mimetype#DetectReader)
or from a [file](https://godoc.org/github.com/gabriel-vasile/mimetype#DetectFile)
**mimetype** limits itself to reading only the first
[3072](https://github.com/gabriel-vasile/mimetype/blob/master/internal/matchers/matchers.go#L6)
bytes from the input.
<div align="center">
<img alt="structure" src="mimetype.gif" width="88%">
</div>

View file

@ -1 +1,3 @@
module github.com/gabriel-vasile/mimetype
go 1.12

View file

@ -26,7 +26,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// JSON value parser state machine.
// Package json provides a JSON value parser state machine.
// This package is almost entirely copied from the Go stdlib.
// Changes made to it permit users of the package to tell
// if some slice of bytes is a valid beginning of a json string.

View file

@ -1,39 +0,0 @@
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package json
import "testing"
var scanTests = []struct {
data string
length int
ok bool
}{
{`foo`, 2, false},
{`}{`, 1, false},
{`{]`, 2, false},
{`{}`, 2, true},
{`{"foo":"bar"}`, 13, true},
{`{"foo":"bar","bar":{"baz":["qux"]}`, 34, false},
{`{"foo":"bar","bar":{"baz":["qux"]}}`, 35, true},
}
func TestScan(t *testing.T) {
for _, st := range scanTests {
scanned, err := Scan([]byte(st.data))
if scanned != st.length {
t.Errorf("Scan length error: expected: %d; got: %d; input: %s",
st.length, scanned, st.data)
}
if err != nil && st.ok {
t.Errorf("Scan failed with err: %s; input: %s", err, st.data)
}
if err == nil && !st.ok {
t.Errorf("Scan should fail for input: %s", st.data)
}
}
}

View file

@ -12,8 +12,7 @@ func Zip(in []byte) bool {
// SevenZ matches a 7z archive.
func SevenZ(in []byte) bool {
return len(in) > 6 &&
bytes.Equal(in[:6], []byte{0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C})
return bytes.HasPrefix(in, []byte{0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C})
}
// Epub matches an EPUB file.
@ -28,12 +27,12 @@ func Jar(in []byte) bool {
// Gzip matched gzip files based on http://www.zlib.org/rfc-gzip.html#header-trailer.
func Gzip(in []byte) bool {
return len(in) > 2 && bytes.Equal(in[:2], []byte{0x1f, 0x8b})
return bytes.HasPrefix(in, []byte{0x1f, 0x8b})
}
// Crx matches a Chrome extension file: a zip archive prepended by "Cr24".
func Crx(in []byte) bool {
return len(in) > 4 && bytes.Equal(in[:4], []byte("Cr24"))
return bytes.HasPrefix(in, []byte("Cr24"))
}
// Tar matches a (t)ape (ar)chive file.
@ -43,9 +42,11 @@ func Tar(in []byte) bool {
// Fits matches an Flexible Image Transport System file.
func Fits(in []byte) bool {
return bytes.HasPrefix(in, []byte{0x53, 0x49, 0x4D, 0x50, 0x4C, 0x45, 0x20,
0x20, 0x3D, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54})
return bytes.HasPrefix(in, []byte{
0x53, 0x49, 0x4D, 0x50, 0x4C, 0x45, 0x20, 0x20, 0x3D, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54,
})
}
// Xar matches an eXtensible ARchive format file.
@ -63,8 +64,35 @@ func Ar(in []byte) bool {
return bytes.HasPrefix(in, []byte{0x21, 0x3C, 0x61, 0x72, 0x63, 0x68, 0x3E})
}
// Deb matches a Debian package file
// Deb matches a Debian package file.
func Deb(in []byte) bool {
return len(in) > 8 && bytes.HasPrefix(in[8:], []byte{0x64, 0x65, 0x62, 0x69,
0x61, 0x6E, 0x2D, 0x62, 0x69, 0x6E, 0x61, 0x72, 0x79})
return len(in) > 8 && bytes.HasPrefix(in[8:], []byte{
0x64, 0x65, 0x62, 0x69, 0x61, 0x6E, 0x2D,
0x62, 0x69, 0x6E, 0x61, 0x72, 0x79,
})
}
// Rar matches a RAR archive file.
func Rar(in []byte) bool {
if !bytes.HasPrefix(in, []byte{0x52, 0x61, 0x72, 0x21, 0x1A, 0x07}) {
return false
}
return len(in) > 8 && (bytes.Equal(in[6:8], []byte{0x01, 0x00}) || in[6] == 0x00)
}
// Warc matches a Web ARChive file.
func Warc(in []byte) bool {
return bytes.HasPrefix(in, []byte("WARC/"))
}
// Zstd matches a Zstandard archive file.
func Zstd(in []byte) bool {
return len(in) >= 4 &&
(0x22 <= in[0] && in[0] <= 0x28 || in[0] == 0x1E) && // Different Zstandard versions.
bytes.HasPrefix(in[1:], []byte{0xB5, 0x2F, 0xFD})
}
// Cab matches a Cabinet archive file.
func Cab(in []byte) bool {
return bytes.HasPrefix(in, []byte("MSCF"))
}

View file

@ -2,11 +2,35 @@ package matchers
import (
"bytes"
"encoding/binary"
)
// Mp3 matches an mp3 file.
func Mp3(in []byte) bool {
return bytes.HasPrefix(in, []byte("\x49\x44\x33"))
if len(in) < 3 {
return false
}
if bytes.HasPrefix(in, []byte("ID3")) {
// MP3s with an ID3v2 tag will start with "ID3"
// ID3v1 tags, however appear at the end of the file.
return true
}
// Match MP3 files without tags
switch binary.BigEndian.Uint16(in[:2]) & 0xFFFE {
case 0xFFFA:
// MPEG ADTS, layer III, v1
return true
case 0xFFF2:
// MPEG ADTS, layer III, v2
return true
case 0xFFE2:
// MPEG ADTS, layer III, v2.5
return true
}
return false
}
// Flac matches a Free Lossless Audio Codec file.
@ -26,13 +50,13 @@ func Ape(in []byte) bool {
// MusePack matches a Musepack file.
func MusePack(in []byte) bool {
return len(in) > 4 && bytes.Equal(in[:4], []byte("MPCK"))
return bytes.HasPrefix(in, []byte("MPCK"))
}
// Wav matches a Waveform Audio File Format file.
func Wav(in []byte) bool {
return len(in) > 12 &&
bytes.Equal(in[:4], []byte("\x52\x49\x46\x46")) &&
bytes.Equal(in[:4], []byte("RIFF")) &&
bytes.Equal(in[8:12], []byte("\x57\x41\x56\x45"))
}
@ -43,17 +67,29 @@ func Aiff(in []byte) bool {
bytes.Equal(in[8:12], []byte("\x41\x49\x46\x46"))
}
// Ogg matches an Ogg file.
func Ogg(in []byte) bool {
return len(in) > 5 && bytes.Equal(in[:5], []byte("\x4F\x67\x67\x53\x00"))
}
// Au matches a Sun Microsystems au file.
func Au(in []byte) bool {
return len(in) > 4 && bytes.Equal(in[:4], []byte("\x2E\x73\x6E\x64"))
return bytes.HasPrefix(in, []byte("\x2E\x73\x6E\x64"))
}
// Amr matches an Adaptive Multi-Rate file.
func Amr(in []byte) bool {
return len(in) > 5 && bytes.Equal(in[:5], []byte("\x23\x21\x41\x4D\x52"))
return bytes.HasPrefix(in, []byte("\x23\x21\x41\x4D\x52"))
}
// Aac matches an Advanced Audio Coding file.
func Aac(in []byte) bool {
return bytes.HasPrefix(in, []byte{0xFF, 0xF1}) || bytes.HasPrefix(in, []byte{0xFF, 0xF9})
}
// Voc matches a Creative Voice file.
func Voc(in []byte) bool {
return bytes.HasPrefix(in, []byte("Creative Voice File"))
}
// Qcp matches a Qualcomm Pure Voice file.
func Qcp(in []byte) bool {
return len(in) > 12 &&
bytes.Equal(in[:4], []byte("RIFF")) &&
bytes.Equal(in[8:12], []byte("QLCM"))
}

View file

@ -2,29 +2,62 @@ package matchers
import (
"bytes"
"debug/macho"
"encoding/binary"
)
// Class matches an java class file.
// Java bytecode and Mach-O binaries share the same magic number.
// More info here https://github.com/threatstack/libmagic/blob/master/magic/Magdir/cafebabe
func classOrMachOFat(in []byte) bool {
// There should be at least 8 bytes for both of them because the only way to
// quickly distinguish them is by comparing byte at position 7
if len(in) < 8 {
return false
}
return bytes.HasPrefix(in, []byte{0xCA, 0xFE, 0xBA, 0xBE})
}
// Class matches a java class file.
func Class(in []byte) bool {
return len(in) > 4 && bytes.Equal(in[:4], []byte{0xCA, 0xFE, 0xBA, 0xBE})
return classOrMachOFat(in) && in[7] > 30
}
// MachO matches Mach-O binaries format.
func MachO(in []byte) bool {
if classOrMachOFat(in) && in[7] < 20 {
return true
}
if len(in) < 4 {
return false
}
be := binary.BigEndian.Uint32(in)
le := binary.LittleEndian.Uint32(in)
return be == macho.Magic32 || le == macho.Magic32 || be == macho.Magic64 || le == macho.Magic64
}
// Swf matches an Adobe Flash swf file.
func Swf(in []byte) bool {
return len(in) > 3 &&
bytes.Equal(in[:3], []byte("CWS")) ||
bytes.Equal(in[:3], []byte("FWS")) ||
bytes.Equal(in[:3], []byte("ZWS"))
return bytes.HasPrefix(in, []byte("CWS")) ||
bytes.HasPrefix(in, []byte("FWS")) ||
bytes.HasPrefix(in, []byte("ZWS"))
}
// Wasm matches a web assembly File Format file.
func Wasm(in []byte) bool {
return len(in) > 4 && bytes.Equal(in[:4], []byte{0x00, 0x61, 0x73, 0x6D})
return bytes.HasPrefix(in, []byte{0x00, 0x61, 0x73, 0x6D})
}
// Dbf matches a dBase file.
// https://www.dbase.com/Knowledgebase/INT/db7_file_fmt.htm
func Dbf(in []byte) bool {
if len(in) < 4 {
return false
}
// 3rd and 4th bytes contain the last update month and day of month
if !(0 < in[2] && in[2] < 13 && 0 < in[3] && in[3] < 32) {
return false
@ -83,3 +116,31 @@ func Dcm(in []byte) bool {
return len(in) > 131 &&
bytes.Equal(in[128:132], []byte{0x44, 0x49, 0x43, 0x4D})
}
// Nes matches a Nintendo Entertainment system ROM file.
func Nes(in []byte) bool {
return bytes.HasPrefix(in, []byte{0x4E, 0x45, 0x53, 0x1A})
}
// Marc matches a MARC21 (MAchine-Readable Cataloging) file.
func Marc(in []byte) bool {
// File is at least 24 bytes ("leader" field size)
if len(in) < 24 {
return false
}
// Fixed bytes at offset 20
if !bytes.Equal(in[20:24], []byte("4500")) {
return false
}
// First 5 bytes are ASCII digits
for i := 0; i < 5; i++ {
if in[i] < '0' || in[i] > '9' {
return false
}
}
// Field terminator is present
return bytes.Contains(in, []byte{0x1E})
}

View file

@ -0,0 +1,25 @@
package matchers
import "bytes"
// Sqlite matches an SQLite database file.
func Sqlite(in []byte) bool {
return bytes.HasPrefix(in, []byte{
0x53, 0x51, 0x4c, 0x69, 0x74, 0x65, 0x20, 0x66,
0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x33, 0x00,
})
}
// MsAccessAce matches Microsoft Access dababase file.
func MsAccessAce(in []byte) bool {
return msAccess(in, []byte("Standard ACE DB"))
}
// MsAccessMdb matches legacy Microsoft Access database file (JET, 2003 and earlier).
func MsAccessMdb(in []byte) bool {
return msAccess(in, []byte("Standard Jet DB"))
}
func msAccess(in []byte, magic []byte) bool {
return len(in) > 19 && bytes.Equal(in[4:19], magic)
}

View file

@ -4,5 +4,29 @@ import "bytes"
// Pdf matches a Portable Document Format file.
func Pdf(in []byte) bool {
return len(in) > 4 && bytes.Equal(in[:4], []byte{0x25, 0x50, 0x44, 0x46})
return bytes.HasPrefix(in, []byte{0x25, 0x50, 0x44, 0x46})
}
// DjVu matches a DjVu file.
func DjVu(in []byte) bool {
if len(in) < 12 {
return false
}
if !bytes.HasPrefix(in, []byte{0x41, 0x54, 0x26, 0x54, 0x46, 0x4F, 0x52, 0x4D}) {
return false
}
return bytes.HasPrefix(in[12:], []byte("DJVM")) ||
bytes.HasPrefix(in[12:], []byte("DJVU")) ||
bytes.HasPrefix(in[12:], []byte("DJVI")) ||
bytes.HasPrefix(in[12:], []byte("THUM"))
}
// Mobi matches a Mobi file.
func Mobi(in []byte) bool {
return len(in) > 67 && bytes.Equal(in[60:68], []byte("BOOKMOBI"))
}
// Lit matches a Microsoft Lit file.
func Lit(in []byte) bool {
return bytes.HasPrefix(in, []byte("ITOLITLS"))
}

View file

@ -0,0 +1,27 @@
package matchers
import "bytes"
// Woff matches a Web Open Font Format file.
func Woff(in []byte) bool {
return bytes.HasPrefix(in, []byte("wOFF"))
}
// Woff2 matches a Web Open Font Format version 2 file.
func Woff2(in []byte) bool {
return bytes.HasPrefix(in, []byte("wOF2"))
}
// Otf matches an OpenType font file.
func Otf(in []byte) bool {
return bytes.HasPrefix(in, []byte{0x4F, 0x54, 0x54, 0x4F, 0x00})
}
// Eot matches an Embedded OpenType font file.
func Eot(in []byte) bool {
return len(in) > 35 &&
bytes.Equal(in[34:36], []byte{0x4C, 0x50}) &&
(bytes.Equal(in[8:11], []byte{0x02, 0x00, 0x01}) ||
bytes.Equal(in[8:11], []byte{0x01, 0x00, 0x00}) ||
bytes.Equal(in[8:11], []byte{0x02, 0x00, 0x02}))
}

View file

@ -1,13 +0,0 @@
package matchers
import "bytes"
// Woff matches a Web Open Font Format file.
func Woff(in []byte) bool {
return len(in) > 4 && bytes.Equal(in[:4], []byte("wOFF"))
}
// Woff2 matches a Web Open Font Format version 2 file.
func Woff2(in []byte) bool {
return len(in) > 4 && bytes.Equal(in[:4], []byte("wOF2"))
}

View file

@ -40,5 +40,5 @@ func Shp(in []byte) bool {
// Shx matches a shape index format file.
// https://www.esri.com/library/whitepapers/pdfs/shapefile.pdf
func Shx(in []byte) bool {
return len(in) > 4 && bytes.Equal(in[:4], []byte{0x00, 0x00, 0x27, 0x0A})
return bytes.HasPrefix(in, []byte{0x00, 0x00, 0x27, 0x0A})
}

View file

@ -4,13 +4,38 @@ import "bytes"
// Png matches a Portable Network Graphics file.
func Png(in []byte) bool {
return len(in) > 8 &&
bytes.Equal(in[:8], []byte{0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A})
return bytes.HasPrefix(in, []byte{0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A})
}
// Jpg matches a Joint Photographic Experts Group file.
func Jpg(in []byte) bool {
return len(in) > 3 && bytes.Equal(in[:3], []byte{0xFF, 0xD8, 0xFF})
return bytes.HasPrefix(in, []byte{0xFF, 0xD8, 0xFF})
}
// isJpeg2k matches a generic JPEG2000 file.
func isJpeg2k(in []byte) bool {
if len(in) < 24 {
return false
}
signature := in[4:8]
return bytes.Equal(signature, []byte{0x6A, 0x50, 0x20, 0x20}) ||
bytes.Equal(signature, []byte{0x6A, 0x50, 0x32, 0x20})
}
// Jp2 matches a JPEG 2000 Image file (ISO 15444-1).
func Jp2(in []byte) bool {
return isJpeg2k(in) && bytes.Equal(in[20:24], []byte{0x6a, 0x70, 0x32, 0x20})
}
// Jpx matches a JPEG 2000 Image file (ISO 15444-2).
func Jpx(in []byte) bool {
return isJpeg2k(in) && bytes.Equal(in[20:24], []byte{0x6a, 0x70, 0x78, 0x20})
}
// Jpm matches a JPEG 2000 Image file (ISO 15444-6).
func Jpm(in []byte) bool {
return isJpeg2k(in) && bytes.Equal(in[20:24], []byte{0x6a, 0x70, 0x6D, 0x20})
}
// Gif matches a Graphics Interchange Format file.
@ -22,7 +47,7 @@ func Gif(in []byte) bool {
// Webp matches a WebP file.
func Webp(in []byte) bool {
return len(in) > 12 &&
bytes.Equal(in[0:4], []byte{0x52, 0x49, 0x46, 0x46}) &&
bytes.Equal(in[0:4], []byte("RIFF")) &&
bytes.Equal(in[8:12], []byte{0x57, 0x45, 0x42, 0x50})
}
@ -43,14 +68,97 @@ func Psd(in []byte) bool {
// Ico matches an ICO file.
func Ico(in []byte) bool {
return len(in) > 3 &&
in[0] == 0x00 && in[1] == 0x00 &&
in[2] == 0x01 && in[3] == 0x00
return bytes.HasPrefix(in, []byte{0x00, 0x00, 0x01, 0x00})
}
// Icns matches an ICNS (Apple Icon Image format) file.
func Icns(in []byte) bool {
return bytes.HasPrefix(in, []byte("icns"))
}
// Tiff matches a Tagged Image File Format file.
func Tiff(in []byte) bool {
return len(in) > 4 &&
(bytes.Equal(in[:4], []byte{0x49, 0x49, 0x2A, 0x00}) ||
bytes.Equal(in[:4], []byte{0x4D, 0x4D, 0x00, 0x2A}))
return bytes.HasPrefix(in, []byte{0x49, 0x49, 0x2A, 0x00}) ||
bytes.HasPrefix(in, []byte{0x4D, 0x4D, 0x00, 0x2A})
}
// Bpg matches a Better Portable Graphics file.
func Bpg(in []byte) bool {
return bytes.HasPrefix(in, []byte{0x42, 0x50, 0x47, 0xFB})
}
// Dwg matches a CAD drawing file.
func Dwg(in []byte) bool {
if len(in) < 6 || in[0] != 0x41 || in[1] != 0x43 {
return false
}
dwgVersions := [][]byte{
{0x31, 0x2E, 0x34, 0x30},
{0x31, 0x2E, 0x35, 0x30},
{0x32, 0x2E, 0x31, 0x30},
{0x31, 0x30, 0x30, 0x32},
{0x31, 0x30, 0x30, 0x33},
{0x31, 0x30, 0x30, 0x34},
{0x31, 0x30, 0x30, 0x36},
{0x31, 0x30, 0x30, 0x39},
{0x31, 0x30, 0x31, 0x32},
{0x31, 0x30, 0x31, 0x34},
{0x31, 0x30, 0x31, 0x35},
{0x31, 0x30, 0x31, 0x38},
{0x31, 0x30, 0x32, 0x31},
{0x31, 0x30, 0x32, 0x34},
{0x31, 0x30, 0x33, 0x32},
}
for _, d := range dwgVersions {
if bytes.Equal(in[2:6], d) {
return true
}
}
return false
}
// Heic matches a High Efficiency Image Coding (HEIC) file.
func Heic(in []byte) bool {
if len(in) <= 12 {
return false
}
return bytes.Equal(in[4:12], []byte("ftypheic")) ||
bytes.Equal(in[4:12], []byte("ftypheix"))
}
// HeicSequence matches a High Efficiency Image Coding (HEIC) file sequence.
func HeicSequence(in []byte) bool {
if len(in) <= 12 {
return false
}
return bytes.Equal(in[4:12], []byte("ftyphevc")) ||
bytes.Equal(in[4:12], []byte("ftyphevx"))
}
// Heif matches a High Efficiency Image File Format (HEIF) file.
func Heif(in []byte) bool {
if len(in) <= 12 {
return false
}
return bytes.Equal(in[4:12], []byte("ftypmif1")) ||
bytes.Equal(in[4:12], []byte("ftypheim")) ||
bytes.Equal(in[4:12], []byte("ftypheis")) ||
bytes.Equal(in[4:12], []byte("ftypavic"))
}
// HeifSequence matches a High Efficiency Image File Format (HEIF) file sequence.
func HeifSequence(in []byte) bool {
if len(in) <= 12 {
return false
}
return bytes.Equal(in[4:12], []byte("ftypmsf1")) ||
bytes.Equal(in[4:12], []byte("ftyphevm")) ||
bytes.Equal(in[4:12], []byte("ftyphevs")) ||
bytes.Equal(in[4:12], []byte("ftypavcs"))
}

View file

@ -1,20 +1,15 @@
// Package matchers holds the matching functions used to find mime types.
// Package matchers holds the matching functions used to find MIME types.
package matchers
// ReadLimit is the maximum number of bytes read
// from the input when detecting a reader.
const ReadLimit = 2048
const ReadLimit = 3072
// True is a dummy matching function used to match any input.
func True([]byte) bool {
return true
}
// False is a dummy matching function used to never match input.
func False([]byte) bool {
return false
}
// trimLWS trims whitespace from beginning of the input.
func trimLWS(in []byte) []byte {
firstNonWS := 0
@ -44,3 +39,10 @@ func firstLine(in []byte) []byte {
func isWS(b byte) bool {
return b == '\t' || b == '\n' || b == '\x0c' || b == '\r' || b == ' '
}
func min(a, b int) int {
if a < b {
return a
}
return b
}

View file

@ -2,35 +2,76 @@ package matchers
import (
"bytes"
"fmt"
"strings"
"encoding/binary"
"regexp"
)
var msoXMLreg = regexp.MustCompile("\\[Content_Types\\]\\.xml|_rels/\\.rels|docProps")
// msoXML walks through the first 4 zip local file headers and returns whether
// any of the headers contain a file whose name starts with sig.
func msoXML(in, sig []byte) bool {
pkSig := []byte("PK\003\004")
if !msoXMLreg.Match(in[:min(len(in), 8000)]) {
return false
}
// 30 is the offset where the file name is located in each zip header.
lastCheckedIndex := 0
check := func(in, sig []byte, offset int) bool {
return len(in) > offset && bytes.HasPrefix(in[offset:], sig)
}
// github.com/file/file looks for the msoXML signature in the first 4 local
// headers, but some xlsx files have their signature in later headers.
// testdata/xlsx.1.xlsx is such an example, with the signature in the 5th header.
for i := 0; i < 6 && lastCheckedIndex < len(in); i++ {
in = in[lastCheckedIndex:]
pkIndex := bytes.Index(in, pkSig)
if pkIndex == -1 {
return false
}
if check(in, sig, pkIndex+30) {
return true
}
lastCheckedIndex = pkIndex + 30
}
return false
}
// Xlsx matches a Microsoft Excel 2007 file.
func Xlsx(in []byte) bool {
return bytes.Contains(in, []byte("xl/"))
return msoXML(in, []byte("xl/"))
}
// Docx matches a Microsoft Office 2007 file.
func Docx(in []byte) bool {
return bytes.Contains(in, []byte("word/"))
return msoXML(in, []byte("word/"))
}
// Pptx matches a Microsoft PowerPoint 2007 file.
func Pptx(in []byte) bool {
return bytes.Contains(in, []byte("ppt/"))
return msoXML(in, []byte("ppt/"))
}
// Ole matches an Open Linking and Embedding file.
//
// https://en.wikipedia.org/wiki/Object_Linking_and_Embedding
func Ole(in []byte) bool {
return bytes.HasPrefix(in, []byte{0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1})
}
// Doc matches a Microsoft Office 97-2003 file.
//
// BUG(gabriel-vasile): Doc should look for subheaders like Ppt and Xls does.
//
// Ole is a container for Doc, Ppt, Pub and Xls.
// Right now, when an Ole file is detected, it is considered to be a Doc file
// if the checks for Ppt, Pub and Xls failed.
func Doc(in []byte) bool {
if len(in) < 516 {
return false
}
head := fmt.Sprintf("%X", in[:8])
offset512 := fmt.Sprintf("%X", in[512:516])
return head == "D0CF11E0A1B11AE1" && offset512 == "ECA5C100"
return true
}
// Ppt matches a Microsoft PowerPoint 97-2003 file.
@ -38,43 +79,76 @@ func Ppt(in []byte) bool {
if len(in) < 520 {
return false
}
if fmt.Sprintf("%X", in[:8]) == "D0CF11E0A1B11AE1" {
offset512 := fmt.Sprintf("%X", in[512:516])
if offset512 == "A0461DF0" || offset512 == "006E1EF0" || offset512 == "0F00E803" {
return true
}
if offset512 == "FDFFFFFF" && fmt.Sprintf("%x", in[518:520]) == "0000" {
pptSubHeaders := [][]byte{
{0xA0, 0x46, 0x1D, 0xF0},
{0x00, 0x6E, 0x1E, 0xF0},
{0x0F, 0x00, 0xE8, 0x03},
}
for _, h := range pptSubHeaders {
if bytes.HasPrefix(in[512:], h) {
return true
}
}
return false
if bytes.HasPrefix(in[512:], []byte{0xFD, 0xFF, 0xFF, 0xFF}) &&
in[518] == 0x00 && in[519] == 0x00 {
return true
}
return bytes.Contains(in, []byte("MS PowerPoint 97")) ||
bytes.Contains(in, []byte("P\x00o\x00w\x00e\x00r\x00P\x00o\x00i\x00n\x00t\x00 D\x00o\x00c\x00u\x00m\x00e\x00n\x00t"))
}
// Xls matches a Microsoft Excel 97-2003 file.
func Xls(in []byte) bool {
if len(in) < 520 {
if len(in) <= 512 {
return false
}
if fmt.Sprintf("%X", in[:8]) == "D0CF11E0A1B11AE1" {
offset512 := fmt.Sprintf("%X", in[512:520])
subheaders := []string{
"0908100000060500",
"FDFFFFFF10",
"FDFFFFFF1F",
"FDFFFFFF22",
"FDFFFFFF23",
"FDFFFFFF28",
"FDFFFFFF29",
}
for _, h := range subheaders {
if strings.HasPrefix(offset512, h) {
return true
}
xlsSubHeaders := [][]byte{
{0x09, 0x08, 0x10, 0x00, 0x00, 0x06, 0x05, 0x00},
{0xFD, 0xFF, 0xFF, 0xFF, 0x10},
{0xFD, 0xFF, 0xFF, 0xFF, 0x1F},
{0xFD, 0xFF, 0xFF, 0xFF, 0x22},
{0xFD, 0xFF, 0xFF, 0xFF, 0x23},
{0xFD, 0xFF, 0xFF, 0xFF, 0x28},
{0xFD, 0xFF, 0xFF, 0xFF, 0x29},
}
for _, h := range xlsSubHeaders {
if bytes.HasPrefix(in[512:], h) {
return true
}
}
return false
return bytes.Contains(in, []byte("Microsoft Excel")) ||
bytes.Contains(in, []byte("W\x00o\x00r\x00k\x00b\x00o\x00o\x00k"))
}
// Pub matches a Microsoft Publisher file.
func Pub(in []byte) bool {
return matchOleClsid(in, []byte{
0x01, 0x12, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
})
}
// Helper to match by a specific CLSID of a compound file
//
// http://fileformats.archiveteam.org/wiki/Microsoft_Compound_File
func matchOleClsid(in []byte, clsid []byte) bool {
if len(in) <= 512 {
return false
}
// SecID of first sector of the directory stream
firstSecID := int(binary.LittleEndian.Uint32(in[48:52]))
// Expected offset of CLSID for root storage object
clsidOffset := 512*(1+firstSecID) + 80
if len(in) <= clsidOffset+16 {
return false
}
return bytes.HasPrefix(in[clsidOffset:], clsid)
}

View file

@ -0,0 +1,42 @@
package matchers
import (
"bytes"
)
/*
NOTE:
In May 2003, two Internet RFCs were published relating to the format.
The Ogg bitstream was defined in RFC 3533 (which is classified as
'informative') and its Internet content type (application/ogg) in RFC
3534 (which is, as of 2006, a proposed standard protocol). In
September 2008, RFC 3534 was obsoleted by RFC 5334, which added
content types video/ogg, audio/ogg and filename extensions .ogx, .ogv,
.oga, .spx.
See:
https://tools.ietf.org/html/rfc3533
https://developer.mozilla.org/en-US/docs/Web/HTTP/Configuring_servers_for_Ogg_media#Serve_media_with_the_correct_MIME_type
https://github.com/file/file/blob/master/magic/Magdir/vorbis
*/
// Ogg matches an Ogg file.
func Ogg(in []byte) bool {
return bytes.HasPrefix(in, []byte("\x4F\x67\x67\x53\x00"))
}
// OggAudio matches an audio ogg file.
func OggAudio(in []byte) bool {
return len(in) >= 37 && (bytes.HasPrefix(in[28:], []byte("\x7fFLAC")) ||
bytes.HasPrefix(in[28:], []byte("\x01vorbis")) ||
bytes.HasPrefix(in[28:], []byte("OpusHead")) ||
bytes.HasPrefix(in[28:], []byte("Speex\x20\x20\x20")))
}
// OggVideo matches a video ogg file.
func OggVideo(in []byte) bool {
return len(in) >= 37 && (bytes.HasPrefix(in[28:], []byte("\x80theora")) ||
bytes.HasPrefix(in[28:], []byte("fishead\x00")) ||
bytes.HasPrefix(in[28:], []byte("\x01video\x00\x00\x00"))) // OGM video
}

View file

@ -99,6 +99,7 @@ func (fSig ftypSig) detect(in []byte) bool {
bytes.Equal(in[8:12], fSig)
}
// Implement sig interface.
func (xSig xmlSig) detect(in []byte) bool {
l := 512
if len(in) < l {
@ -109,11 +110,15 @@ func (xSig xmlSig) detect(in []byte) bool {
if len(xSig.localName) == 0 {
return bytes.Index(in, xSig.xmlns) > 0
}
if len(xSig.xmlns) == 0 {
return bytes.Index(in, xSig.localName) > 0
}
localNameIndex := bytes.Index(in, xSig.localName)
return localNameIndex != -1 && localNameIndex < bytes.Index(in, xSig.xmlns)
}
// detect returns true if any of the provided signatures pass for in input.
func detect(in []byte, sigs []sig) bool {
for _, sig := range sigs {
if sig.detect(in) {

View file

@ -29,16 +29,26 @@ var (
xmlSigs = []sig{
markupSig("<?XML"),
}
rssSigs = []sig{
newXmlSig("rss", ""),
}
atomSigs = []sig{
newXmlSig("feed", `xmlns="http://www.w3.org/2005/Atom"`),
}
kmlSigs = []sig{
newXmlSig("kml", `xmlns="http://www.opengis.net/kml/2.2"`),
newXmlSig("kml", `xmlns="http://earth.google.com/kml/2.0"`),
newXmlSig("kml", `xmlns="http://earth.google.com/kml/2.1"`),
newXmlSig("kml", `xmlns="http://earth.google.com/kml/2.2"`),
}
xliffSigs = []sig{
newXmlSig("xliff", `xmlns="urn:oasis:names:tc:xliff:document:1.2"`),
}
colladaSigs = []sig{
newXmlSig("COLLADA", `xmlns="http://www.collada.org/2005/11/COLLADASchema"`),
}
gmlSigs = []sig{
newXmlSig("", `xmlns:gml="http://www.opengis.net/gml"`),
newXmlSig("", `xmlns:gml="http://www.opengis.net/gml/3.2"`),
newXmlSig("", `xmlns:gml="http://www.opengis.net/gml/3.3/exr"`),
}
@ -51,8 +61,19 @@ var (
x3dSigs = []sig{
newXmlSig("X3D", `xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance"`),
}
amfSigs = []sig{
newXmlSig("amf", ""),
}
threemfSigs = []sig{
newXmlSig("model", `xmlns="http://schemas.microsoft.com/3dmanufacturing/core/2015/02"`),
}
vCardSigs = []sig{
ciSig("BEGIN:VCARD\n"),
ciSig("BEGIN:VCARD\r\n"),
}
iCalSigs = []sig{
ciSig("BEGIN:VCALENDAR\n"),
ciSig("BEGIN:VCALENDAR\r\n"),
}
phpSigs = []sig{
ciSig("<?PHP"),
@ -98,8 +119,32 @@ var (
}
)
// Txt matches a text file.
func Txt(in []byte) bool {
// Utf32be matches a text file encoded with UTF-32 and with the characters
// represented in big endian.
func Utf32be(in []byte) bool {
return bytes.HasPrefix(in, []byte{0x00, 0x00, 0xFE, 0xFF})
}
// Utf32le matches a text file encoded with UTF-32 and with the characters
// represented in little endian.
func Utf32le(in []byte) bool {
return bytes.HasPrefix(in, []byte{0xFF, 0xFE, 0x00, 0x00})
}
// Utf16be matches a text file encoded with UTF-16 and with the characters
// represented in big endian.
func Utf16be(in []byte) bool {
return bytes.HasPrefix(in, []byte{0xFE, 0xFF})
}
// Utf16le matches a text file encoded with UTF-16 and with the characters
// represented in little endian.
func Utf16le(in []byte) bool {
return bytes.HasPrefix(in, []byte{0xFF, 0xFE})
}
// Utf8 matches a UTF-8 text file.
func Utf8(in []byte) bool {
in = trimLWS(in)
for _, b := range in {
if b <= 0x08 ||
@ -115,11 +160,19 @@ func Txt(in []byte) bool {
// Html matches a Hypertext Markup Language file.
func Html(in []byte) bool {
in = trimLWS(in)
if len(in) == 0 {
return false
}
return detect(in, htmlSigs)
}
// Xml matches an Extensible Markup Language file.
func Xml(in []byte) bool {
in = trimLWS(in)
if len(in) == 0 {
return false
}
return detect(in, xmlSigs)
}
@ -143,6 +196,9 @@ func Json(in []byte) bool {
// BUG(gabriel-vasile): The "type" key should be searched for in the root object.
func GeoJson(in []byte) bool {
in = trimLWS(in)
if len(in) == 0 {
return false
}
// geojson is always an object
if in[0] != '{' {
return false
@ -156,6 +212,11 @@ func GeoJson(in []byte) bool {
return false
}
// if the "type" string is the suffix of the input
// there is no need to search for the value of the key
if si+sl == len(in) {
return false
}
// skip the "type" part
in = in[si+sl:]
// skip any whitespace before the colon
@ -184,6 +245,49 @@ func GeoJson(in []byte) bool {
return false
}
// NdJson matches a Newline delimited JSON file.
func NdJson(in []byte) bool {
// Separator with carriage return and new line `\r\n`
srn := []byte{0x0D, 0x0A}
// Separator with only new line `\n`
sn := []byte{0x0A}
// total bytes scanned
parsed := 0
// Split by `srn`
for rni, insrn := range bytes.Split(in, srn) {
// separator byte count should be added only after the first split
if rni != 0 {
// Add two as `\r\n` is used for split
parsed += 2
}
// Return false if there is a carriage return `\r`
if bytes.Contains(insrn, []byte{0x0D}) {
return false
}
// Split again by `sn`
for ni, insn := range bytes.Split(insrn, sn) {
// separator byte count should be added only after the first split
if ni != 0 {
// Add one as `\n` is used for split
parsed++
}
// Empty line is valid
if len(insn) == 0 {
continue
}
p, err := json.Scan(insn)
parsed += p
if parsed < ReadLimit && err != nil {
return false
}
}
}
return parsed == len(in)
}
// Js matches a Javascript file.
func Js(in []byte) bool {
return detect(in, jsSigs)
@ -211,7 +315,7 @@ func Tcl(in []byte) bool {
// Rtf matches a Rich Text Format file.
func Rtf(in []byte) bool {
return len(in) > 6 && bytes.Equal(in[:6], []byte("{\\rtf1"))
return bytes.HasPrefix(in, []byte("{\\rtf1"))
}
// Svg matches a SVG file.
@ -219,11 +323,26 @@ func Svg(in []byte) bool {
return bytes.Contains(in, []byte("<svg"))
}
// Rss matches a Rich Site Summary file.
func Rss(in []byte) bool {
return detect(in, rssSigs)
}
// Atom matches an Atom Syndication Format file.
func Atom(in []byte) bool {
return detect(in, atomSigs)
}
// Kml matches a Keyhole Markup Language file.
func Kml(in []byte) bool {
return detect(in, kmlSigs)
}
// Xliff matches a XML Localization Interchange File Format file.
func Xliff(in []byte) bool {
return detect(in, xliffSigs)
}
// Collada matches a COLLAborative Design Activity file.
func Collada(in []byte) bool {
return detect(in, colladaSigs)
@ -244,6 +363,16 @@ func Tcx(in []byte) bool {
return detect(in, tcxSigs)
}
// Amf matches an Additive Manufacturing XML file.
func Amf(in []byte) bool {
return detect(in, amfSigs)
}
// Threemf matches a 3D Manufacturing Format file.
func Threemf(in []byte) bool {
return detect(in, threemfSigs)
}
// X3d matches an Extensible 3D Graphics file.
func X3d(in []byte) bool {
return detect(in, x3dSigs)
@ -253,3 +382,8 @@ func X3d(in []byte) bool {
func VCard(in []byte) bool {
return detect(in, vCardSigs)
}
// ICalendar matches a iCalendar file.
func ICalendar(in []byte) bool {
return detect(in, iCalSigs)
}

View file

@ -21,6 +21,7 @@ func sv(in []byte, comma rune) bool {
r.Comma = comma
r.TrimLeadingSpace = true
r.LazyQuotes = true
r.Comment = '#'
lines, err := r.ReadAll()
return err == nil && r.FieldsPerRecord > 1 && len(lines) > 1

View file

@ -31,13 +31,12 @@ func isMatroskaFileTypeMatched(in []byte, flType string) bool {
// The logic of search is: find first instance of \x42\x82 and then
// search for given string after one byte of above instance.
func isFileTypeNamePresent(in []byte, flType string) bool {
var ind int
if len(in) >= 4096 { // restricting length to 4096
ind = bytes.Index(in[0:4096], []byte("\x42\x82"))
} else {
ind = bytes.Index(in, []byte("\x42\x82"))
ind, maxInd, lenIn := 0, 4096, len(in)
if lenIn < maxInd { // restricting length to 4096
maxInd = lenIn
}
if ind > 0 {
ind = bytes.Index(in[:maxInd], []byte("\x42\x82"))
if ind > 0 && lenIn > ind+3 {
// filetype name will be present exactly
// one byte after the match of the two bytes "\x42\x82"
return bytes.HasPrefix(in[ind+3:], []byte(flType))
@ -52,7 +51,7 @@ func Flv(in []byte) bool {
// Mpeg matches a Moving Picture Experts Group file.
func Mpeg(in []byte) bool {
return len(in) > 3 && bytes.Equal(in[:3], []byte("\x00\x00\x01")) &&
return len(in) > 3 && bytes.HasPrefix(in, []byte{0x00, 0x00, 0x01}) &&
in[3] >= 0xB0 && in[3] <= 0xBF
}
@ -65,6 +64,8 @@ func Avi(in []byte) bool {
// Asf matches an Advanced Systems Format file.
func Asf(in []byte) bool {
return len(in) > 16 && bytes.Equal(in[:16], []byte{0x30, 0x26, 0xB2, 0x75,
0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C})
return bytes.HasPrefix(in, []byte{
0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11,
0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C,
})
}

View file

@ -12,11 +12,12 @@ var (
}
threeGPSigs = []sig{
ftypSig("3gp1"), ftypSig("3gp2"), ftypSig("3gp3"), ftypSig("3gp4"),
ftypSig("3gp5"), ftypSig("3gp6"), ftypSig("3gs7"), ftypSig("3ge6"),
ftypSig("3ge7"), ftypSig("3gg6"),
ftypSig("3gp5"), ftypSig("3gp6"), ftypSig("3gp7"), ftypSig("3gs7"),
ftypSig("3ge6"), ftypSig("3ge7"), ftypSig("3gg6"),
}
threeG2Sigs = []sig{
ftypSig("3g2a"), ftypSig("3g2b"), ftypSig("3g2c"), ftypSig("KDDI"),
ftypSig("3g24"), ftypSig("3g25"), ftypSig("3g26"), ftypSig("3g2a"),
ftypSig("3g2b"), ftypSig("3g2c"), ftypSig("KDDI"),
}
amp4Sigs = []sig{
// audio for Adobe Flash Player 9+

View file

@ -1,55 +1,94 @@
// Package mimetype uses magic number signatures
// to detect the MIME type and extension of a file.
package mimetype
import (
"io"
"os"
import "mime"
"github.com/gabriel-vasile/mimetype/internal/matchers"
)
// Detect returns the MIME type and extension of the provided byte slice.
//
// mime is always a valid MIME type, with application/octet-stream as fallback.
// extension is empty string if detected file format does not have an extension.
func Detect(in []byte) (mime, extension string) {
if len(in) == 0 {
return "inode/x-empty", ""
}
n := root.match(in, root)
return n.mime, n.extension
// MIME represents a file format in the tree structure of formats.
type MIME struct {
mime string
aliases []string
extension string
matchFunc func([]byte) bool
children []*MIME
parent *MIME
}
// DetectReader returns the MIME type and extension
// of the byte slice read from the provided reader.
//
// mime is always a valid MIME type, with application/octet-stream as fallback.
// extension is empty string if detection failed with an error or
// detected file format does not have an extension.
func DetectReader(r io.Reader) (mime, extension string, err error) {
in := make([]byte, matchers.ReadLimit)
n, err := r.Read(in)
if err != nil && err != io.EOF {
return root.mime, root.extension, err
}
in = in[:n]
mime, extension = Detect(in)
return mime, extension, nil
// String returns the string representation of the MIME type, e.g., "application/zip".
func (n *MIME) String() string {
return n.mime
}
// DetectFile returns the MIME type and extension of the provided file.
//
// mime is always a valid MIME type, with application/octet-stream as fallback.
// extension is empty string if detection failed with an error or
// detected file format does not have an extension.
func DetectFile(file string) (mime, extension string, err error) {
f, err := os.Open(file)
if err != nil {
return root.mime, root.extension, err
}
defer f.Close()
return DetectReader(f)
// 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 (n *MIME) Extension() string {
return n.extension
}
// Parent returns the parent MIME type from the tree structure.
// Each MIME type has a non-nil parent, except for the root MIME type.
func (n *MIME) Parent() *MIME {
return n.parent
}
// 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.
func (n *MIME) Is(expectedMIME string) bool {
// Parsing is needed because some detected MIME types contain parameters
// that need to be stripped for the comparison.
expectedMIME, _, _ = mime.ParseMediaType(expectedMIME)
found, _, _ := mime.ParseMediaType(n.mime)
if expectedMIME == found {
return true
}
for _, alias := range n.aliases {
if alias == expectedMIME {
return true
}
}
return false
}
func newMIME(mime, extension string, matchFunc func([]byte) bool, children ...*MIME) *MIME {
n := &MIME{
mime: mime,
extension: extension,
matchFunc: matchFunc,
children: children,
}
for _, c := range children {
c.parent = n
}
return n
}
func (n *MIME) alias(aliases ...string) *MIME {
n.aliases = aliases
return n
}
// match does a depth-first search on the matchers tree.
// it returns the deepest successful matcher for which all the children fail.
func (n *MIME) match(in []byte, deepestMatch *MIME) *MIME {
for _, c := range n.children {
if c.matchFunc(in) {
return c.match(in, c)
}
}
return deepestMatch
}
func (n *MIME) flatten() []*MIME {
out := []*MIME{n}
for _, c := range n.children {
out = append(out, c.flatten()...)
}
return out
}

View file

@ -1,232 +0,0 @@
package mimetype
import (
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"testing"
"github.com/gabriel-vasile/mimetype/internal/matchers"
)
const testDataDir = "testdata"
var files = map[string]*node{
// archives
"pdf.pdf": pdf,
"zip.zip": zip,
"tar.tar": tar,
"xls.xls": xls,
"xlsx.xlsx": xlsx,
"doc.doc": doc,
"docx.docx": docx,
"docx.1.docx": docx,
"ppt.ppt": ppt,
"pptx.pptx": pptx,
"odt.odt": odt,
"ott.ott": ott,
"ods.ods": ods,
"ots.ots": ots,
"odp.odp": odp,
"otp.otp": otp,
"odg.odg": odg,
"otg.otg": otg,
"odf.odf": odf,
"epub.epub": epub,
"7z.7z": sevenZ,
"jar.jar": jar,
"gz.gz": gzip,
"fits.fits": fits,
"xar.xar": xar,
"bz2.bz2": bz2,
"a.a": ar,
"deb.deb": deb,
// images
"png.png": png,
"jpg.jpg": jpg,
"psd.psd": psd,
"webp.webp": webp,
"tif.tif": tiff,
"ico.ico": ico,
"bmp.bmp": bmp,
// video
"mp4.mp4": mp4,
"mp4.1.mp4": mp4,
"webm.webm": webM,
"3gp.3gp": threeGP,
"3g2.3g2": threeG2,
"flv.flv": flv,
"avi.avi": avi,
"mov.mov": quickTime,
"mqv.mqv": mqv,
"mpeg.mpeg": mpeg,
"mkv.mkv": mkv,
"asf.asf": asf,
// audio
"mp3.mp3": mp3,
"wav.wav": wav,
"flac.flac": flac,
"midi.midi": midi,
"ape.ape": ape,
"aiff.aiff": aiff,
"au.au": au,
"ogg.ogg": ogg,
"amr.amr": amr,
"mpc.mpc": musePack,
"m4a.m4a": m4a,
"m4b.m4b": aMp4,
// source code
"html.html": html,
"svg.svg": svg,
"svg.1.svg": svg,
"txt.txt": txt,
"php.php": php,
"ps.ps": ps,
"json.json": json,
"geojson.geojson": geoJson,
"geojson.1.geojson": geoJson,
"csv.csv": csv,
"tsv.tsv": tsv,
"rtf.rtf": rtf,
"js.js": js,
"lua.lua": lua,
"pl.pl": perl,
"py.py": python,
"tcl.tcl": tcl,
"vCard.vCard": vCard,
// binary
"class.class": class,
"swf.swf": swf,
"crx.crx": crx,
"wasm.wasm": wasm,
"exe.exe": exe,
"ln": elfExe,
"so.so": elfLib,
"o.o": elfObj,
"dcm.dcm": dcm,
// fonts
"woff.woff": woff,
"woff2.woff2": woff2,
// XML and subtypes of XML
"xml.xml": xml,
"kml.kml": kml,
"dae.dae": collada,
"gml.gml": gml,
"gpx.gpx": gpx,
"tcx.tcx": tcx,
"x3d.x3d": x3d,
"shp.shp": shp,
"shx.shx": shx,
"dbf.dbf": dbf,
}
func TestMatching(t *testing.T) {
errStr := "File: %s; Mime: %s != DetectedMime: %s; err: %v"
for fName, node := range files {
fileName := filepath.Join(testDataDir, fName)
f, err := os.Open(fileName)
if err != nil {
t.Fatal(err)
}
data, err := ioutil.ReadAll(f)
if err != nil {
t.Fatal(err)
}
if dMime, _ := Detect(data); dMime != node.mime {
t.Errorf(errStr, fName, node.mime, dMime, nil)
}
if _, err := f.Seek(0, io.SeekStart); err != nil {
t.Errorf(errStr, fName, node.mime, root.mime, err)
}
if dMime, _, err := DetectReader(f); dMime != node.mime {
t.Errorf(errStr, fName, node.mime, dMime, err)
}
f.Close()
if dMime, _, err := DetectFile(fileName); dMime != node.mime {
t.Errorf(errStr, fName, node.mime, dMime, err)
}
}
}
func TestFaultyInput(t *testing.T) {
inexistent := "inexistent.file"
if _, _, err := DetectFile(inexistent); err == nil {
t.Errorf("%s should not match successfully", inexistent)
}
f, _ := os.Open(inexistent)
if _, _, err := DetectReader(f); err == nil {
t.Errorf("%s reader should not match successfully", inexistent)
}
}
func TestEmptyInput(t *testing.T) {
if m, _ := Detect([]byte{}); m != "inode/x-empty" {
t.Errorf("failed to detect empty file")
}
}
func TestGenerateSupportedMimesFile(t *testing.T) {
f, err := os.OpenFile("supported_mimes.md", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
t.Fatal(err)
}
defer f.Close()
nodes := root.flatten()
header := fmt.Sprintf(`## %d Supported MIME types
This file is automatically generated when running tests. Do not edit manually.
Extension | MIME type
--------- | --------
`, len(nodes))
if _, err := f.WriteString(header); err != nil {
t.Fatal(err)
}
for _, n := range nodes {
ext := n.extension
if ext == "" {
ext = "n/a"
}
str := fmt.Sprintf("**%s** | %s\n", ext, n.mime)
if _, err := f.WriteString(str); err != nil {
t.Fatal(err)
}
}
}
func BenchmarkMatchDetect(b *testing.B) {
files := []string{"a.png", "a.jpg", "a.pdf", "a.zip", "a.docx", "a.doc"}
data, fLen := [][matchers.ReadLimit]byte{}, len(files)
for _, f := range files {
d := [matchers.ReadLimit]byte{}
file, err := os.Open(filepath.Join(testDataDir, f))
if err != nil {
b.Fatal(err)
}
io.ReadFull(file, d[:])
data = append(data, d)
}
b.ResetTimer()
for n := 0; n < b.N; n++ {
Detect(data[n%fLen][:])
}
}

BIN
vendor/github.com/gabriel-vasile/mimetype/mimetype.gif generated vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 744 KiB

68
vendor/github.com/gabriel-vasile/mimetype/mimetype.go generated vendored Normal file
View file

@ -0,0 +1,68 @@
// 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.
package mimetype
import (
"io"
"os"
"github.com/gabriel-vasile/mimetype/internal/matchers"
)
// 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.
func Detect(in []byte) (mime *MIME) {
if len(in) == 0 {
return newMIME("inode/x-empty", "", matchers.True)
}
return root.match(in, root)
}
// 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.
func DetectReader(r io.Reader) (mime *MIME, err error) {
in := make([]byte, matchers.ReadLimit)
n, err := r.Read(in)
if err != nil && err != io.EOF {
return root, err
}
in = in[:n]
return Detect(in), nil
}
// 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.
func DetectFile(file string) (mime *MIME, err error) {
f, err := os.Open(file)
if err != nil {
return root, err
}
defer f.Close()
return DetectReader(f)
}

View file

@ -1,43 +0,0 @@
package mimetype
type (
// node represents a vertex in the matchers tree structure.
// It holds the mime type, the extension and the function
// to check whether a byte slice has the mime type.
node struct {
mime string
extension string
matchFunc func([]byte) bool
children []*node
}
)
func newNode(mime, extension string, matchFunc func([]byte) bool, children ...*node) *node {
return &node{
mime: mime,
extension: extension,
matchFunc: matchFunc,
children: children,
}
}
// match does a depth-first search on the matchers tree.
// it returns the deepest successful matcher for which all the children fail.
func (n *node) match(in []byte, deepestMatch *node) *node {
for _, c := range n.children {
if c.matchFunc(in) {
return c.match(in, c)
}
}
return deepestMatch
}
func (n *node) flatten() []*node {
out := []*node{n}
for _, c := range n.children {
out = append(out, c.flatten()...)
}
return out
}

View file

@ -1,103 +1,146 @@
## 98 Supported MIME types
## 141 Supported MIME types
This file is automatically generated when running tests. Do not edit manually.
Extension | MIME type
--------- | --------
**n/a** | application/octet-stream
**7z** | application/x-7z-compressed
**zip** | application/zip
**xlsx** | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
**docx** | application/vnd.openxmlformats-officedocument.wordprocessingml.document
**pptx** | application/vnd.openxmlformats-officedocument.presentationml.presentation
**epub** | application/epub+zip
**jar** | application/jar
**odt** | application/vnd.oasis.opendocument.text
**ott** | application/vnd.oasis.opendocument.text-template
**ods** | application/vnd.oasis.opendocument.spreadsheet
**ots** | application/vnd.oasis.opendocument.spreadsheet-template
**odp** | application/vnd.oasis.opendocument.presentation
**otp** | application/vnd.oasis.opendocument.presentation-template
**odg** | application/vnd.oasis.opendocument.graphics
**otg** | application/vnd.oasis.opendocument.graphics-template
**odf** | application/vnd.oasis.opendocument.formula
**pdf** | application/pdf
**doc** | application/msword
**xls** | application/vnd.ms-excel
**ppt** | application/vnd.ms-powerpoint
**ps** | application/postscript
**psd** | application/x-photoshop
**ogg** | application/ogg
**png** | image/png
**jpg** | image/jpeg
**gif** | image/gif
**webp** | image/webp
**exe** | application/vnd.microsoft.portable-executable
**n/a** | application/x-elf
**n/a** | application/x-object
**n/a** | application/x-executable
**so** | application/x-sharedlib
**n/a** | application/x-coredump
**a** | application/x-archive
**deb** | application/vnd.debian.binary-package
**tar** | application/x-tar
**xar** | application/x-xar
**bz2** | application/x-bzip2
**fits** | application/fits
**tiff** | image/tiff
**bmp** | image/bmp
**ico** | image/x-icon
**mp3** | audio/mpeg
**flac** | audio/flac
**midi** | audio/midi
**ape** | audio/ape
**mpc** | audio/musepack
**amr** | audio/amr
**wav** | audio/wav
**aiff** | audio/aiff
**au** | audio/basic
**mpeg** | video/mpeg
**mov** | video/quicktime
**mqv** | video/quicktime
**mp4** | video/mp4
**webm** | video/webm
**3gp** | video/3gpp
**3g2** | video/3gpp2
**avi** | video/x-msvideo
**flv** | video/x-flv
**mkv** | video/x-matroska
**asf** | video/x-ms-asf
**mp4** | audio/mp4
**m4a** | audio/x-m4a
**txt** | text/plain
**html** | text/html; charset=utf-8
**svg** | image/svg+xml
**xml** | text/xml; charset=utf-8
**x3d** | model/x3d+xml
**kml** | application/vnd.google-earth.kml+xml
**dae** | model/vnd.collada+xml
**gml** | application/gml+xml
**gpx** | application/gpx+xml
**tcx** | application/vnd.garmin.tcx+xml
**php** | text/x-php; charset=utf-8
**js** | application/javascript
**lua** | text/x-lua
**pl** | text/x-perl
**py** | application/x-python
**json** | application/json
**geojson** | application/geo+json
**rtf** | text/rtf
**tcl** | text/x-tcl
**csv** | text/csv
**tsv** | text/tab-separated-values
**vcf** | text/vcard
**gz** | application/gzip
**class** | application/x-java-applet; charset=binary
**swf** | application/x-shockwave-flash
**crx** | application/x-chrome-extension
**woff** | font/woff
**woff2** | font/woff2
**wasm** | application/wasm
**shx** | application/octet-stream
**shp** | application/octet-stream
**dbf** | application/x-dbf
**dcm** | application/dicom
Extension | MIME type | Aliases
--------- | --------- | -------
**n/a** | application/octet-stream | -
**.7z** | application/x-7z-compressed | -
**.zip** | application/zip | application/x-zip, application/x-zip-compressed
**.xlsx** | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet | -
**.docx** | application/vnd.openxmlformats-officedocument.wordprocessingml.document | -
**.pptx** | application/vnd.openxmlformats-officedocument.presentationml.presentation | -
**.epub** | application/epub+zip | -
**.jar** | application/jar | -
**.odt** | application/vnd.oasis.opendocument.text | application/x-vnd.oasis.opendocument.text
**.ott** | application/vnd.oasis.opendocument.text-template | application/x-vnd.oasis.opendocument.text-template
**.ods** | application/vnd.oasis.opendocument.spreadsheet | application/x-vnd.oasis.opendocument.spreadsheet
**.ots** | application/vnd.oasis.opendocument.spreadsheet-template | application/x-vnd.oasis.opendocument.spreadsheet-template
**.odp** | application/vnd.oasis.opendocument.presentation | application/x-vnd.oasis.opendocument.presentation
**.otp** | application/vnd.oasis.opendocument.presentation-template | application/x-vnd.oasis.opendocument.presentation-template
**.odg** | application/vnd.oasis.opendocument.graphics | application/x-vnd.oasis.opendocument.graphics
**.otg** | application/vnd.oasis.opendocument.graphics-template | application/x-vnd.oasis.opendocument.graphics-template
**.odf** | application/vnd.oasis.opendocument.formula | application/x-vnd.oasis.opendocument.formula
**.pdf** | application/pdf | application/x-pdf
**n/a** | application/x-ole-storage | -
**.xls** | application/vnd.ms-excel | application/msexcel
**.pub** | application/vnd.ms-publisher | -
**.ppt** | application/vnd.ms-powerpoint | application/mspowerpoint
**.doc** | application/msword | application/vnd.ms-word
**.ps** | application/postscript | -
**.psd** | image/vnd.adobe.photoshop | image/x-psd, application/photoshop
**.ogg** | application/ogg | application/x-ogg
**.oga** | audio/ogg | -
**.ogv** | video/ogg | -
**.png** | image/png | -
**.jpg** | image/jpeg | -
**.jp2** | image/jp2 | -
**.jpf** | image/jpx | -
**.jpm** | image/jpm | video/jpm
**.gif** | image/gif | -
**.webp** | image/webp | -
**.exe** | application/vnd.microsoft.portable-executable | -
**n/a** | application/x-elf | -
**n/a** | application/x-object | -
**n/a** | application/x-executable | -
**.so** | application/x-sharedlib | -
**n/a** | application/x-coredump | -
**.a** | application/x-archive | application/x-unix-archive
**.deb** | application/vnd.debian.binary-package | -
**.tar** | application/x-tar | -
**.xar** | application/x-xar | -
**.bz2** | application/x-bzip2 | -
**.fits** | application/fits | -
**.tiff** | image/tiff | -
**.bmp** | image/bmp | image/x-bmp, image/x-ms-bmp
**.ico** | image/x-icon | -
**.mp3** | audio/mpeg | audio/x-mpeg, audio/mp3
**.flac** | audio/flac | -
**.midi** | audio/midi | audio/mid, audio/sp-midi, audio/x-mid, audio/x-midi
**.ape** | audio/ape | -
**.mpc** | audio/musepack | -
**.amr** | audio/amr | audio/amr-nb
**.wav** | audio/wav | audio/x-wav, audio/vnd.wave, audio/wave
**.aiff** | audio/aiff | -
**.au** | audio/basic | -
**.mpeg** | video/mpeg | -
**.mov** | video/quicktime | -
**.mqv** | video/quicktime | -
**.mp4** | video/mp4 | -
**.webm** | video/webm | audio/webm
**.3gp** | video/3gpp | video/3gp, audio/3gpp
**.3g2** | video/3gpp2 | video/3g2, audio/3gpp2
**.avi** | video/x-msvideo | video/avi, video/msvideo
**.flv** | video/x-flv | -
**.mkv** | video/x-matroska | -
**.asf** | video/x-ms-asf | video/asf, video/x-ms-wmv
**.aac** | audio/aac | -
**.voc** | audio/x-unknown | -
**.mp4** | audio/mp4 | audio/x-m4a, audio/x-mp4a
**.m4a** | audio/x-m4a | -
**.txt** | text/plain; charset=utf-32le | -
**.txt** | text/plain; charset=utf-32be | -
**.txt** | text/plain; charset=utf-16le | -
**.txt** | text/plain; charset=utf-16be | -
**.gz** | application/gzip | application/x-gzip, application/x-gunzip, application/gzipped, application/gzip-compressed, application/x-gzip-compressed, gzip/document
**.class** | application/x-java-applet; charset=binary | -
**.swf** | application/x-shockwave-flash | -
**.crx** | application/x-chrome-extension | -
**.woff** | font/woff | -
**.woff2** | font/woff2 | -
**.otf** | font/otf | -
**.eot** | application/vnd.ms-fontobject | -
**.wasm** | application/wasm | -
**.shx** | application/octet-stream | -
**.shp** | application/octet-stream | -
**.dbf** | application/x-dbf | -
**.dcm** | application/dicom | -
**.rar** | application/x-rar-compressed | application/x-rar
**.djvu** | image/vnd.djvu | -
**.mobi** | application/x-mobipocket-ebook | -
**.lit** | application/x-ms-reader | -
**.bpg** | image/bpg | -
**.sqlite** | application/x-sqlite3 | -
**.dwg** | image/vnd.dwg | image/x-dwg, application/acad, application/x-acad, application/autocad_dwg, application/dwg, application/x-dwg, application/x-autocad, drawing/dwg
**.nes** | application/vnd.nintendo.snes.rom | -
**.macho** | application/x-mach-binary | -
**.qcp** | audio/qcelp | -
**.icns** | image/x-icns | -
**.heic** | image/heic | -
**.heic** | image/heic-sequence | -
**.heif** | image/heif | -
**.heif** | image/heif-sequence | -
**.mrc** | application/marc | -
**.mdb** | application/x-msaccess | -
**.accdb** | application/x-msaccess | -
**.zst** | application/zstd | -
**.cab** | application/vnd.ms-cab-compressed | -
**.txt** | text/plain; charset=utf-8 | -
**.html** | text/html; charset=utf-8 | -
**.svg** | image/svg+xml | -
**.xml** | text/xml; charset=utf-8 | -
**.rss** | application/rss+xml | text/rss
**.atom** | application/atom+xml | -
**.x3d** | model/x3d+xml | -
**.kml** | application/vnd.google-earth.kml+xml | -
**.xlf** | application/x-xliff+xml | -
**.dae** | model/vnd.collada+xml | -
**.gml** | application/gml+xml | -
**.gpx** | application/gpx+xml | -
**.tcx** | application/vnd.garmin.tcx+xml | -
**.amf** | application/x-amf | -
**.3mf** | application/vnd.ms-package.3dmanufacturing-3dmodel+xml | -
**.php** | text/x-php; charset=utf-8 | -
**.js** | application/javascript | application/x-javascript, text/javascript
**.lua** | text/x-lua | -
**.pl** | text/x-perl | -
**.py** | application/x-python | -
**.json** | application/json | -
**.geojson** | application/geo+json | -
**.ndjson** | application/x-ndjson | -
**.rtf** | text/rtf | -
**.tcl** | text/x-tcl | application/x-tcl
**.csv** | text/csv | -
**.tsv** | text/tab-separated-values | -
**.vcf** | text/vcard | -
**.ics** | text/calendar | -
**.warc** | application/warc | -

View file

@ -4,115 +4,192 @@ import "github.com/gabriel-vasile/mimetype/internal/matchers"
// root is a matcher which passes for any slice of bytes.
// When a matcher passes the check, the children matchers
// are tried in order to find a more accurate mime type.
var root = newNode("application/octet-stream", "", matchers.True,
sevenZ, zip, pdf, doc, xls, ppt, ps, psd, ogg, png, jpg, gif, webp, exe, elf,
ar, tar, xar, bz2, fits, tiff, bmp, ico, mp3, flac, midi, ape, musePack, amr,
wav, aiff, au, mpeg, quickTime, mqv, mp4, webM, threeGP, threeG2, avi, flv,
mkv, asf, aMp4, m4a, txt, gzip, class, swf, crx, woff, woff2, wasm, shx, dbf,
dcm,
// are tried in order to find a more accurate MIME type.
var root = newMIME("application/octet-stream", "", matchers.True,
sevenZ, zip, pdf, ole, ps, psd, ogg, png, jpg, jp2, jpx, jpm, gif, webp,
exe, elf, ar, tar, xar, bz2, fits, tiff, bmp, ico, mp3, flac, midi, ape,
musePack, amr, wav, aiff, au, mpeg, quickTime, mqv, mp4, webM, threeGP,
threeG2, avi, flv, mkv, asf, aac, voc, aMp4, m4a, utf32le, utf32be, utf16le,
utf16be, gzip, class, swf, crx, woff, woff2, otf, eot, wasm, shx, dbf, dcm,
rar, djvu, mobi, lit, bpg, sqlite3, dwg, nes, macho, qcp, icns, heic,
heicSeq, heif, heifSeq, mrc, mdb, accdb, zstd, cab, utf8,
)
// The list of nodes appended to the root node
var (
gzip = newNode("application/gzip", "gz", matchers.Gzip)
sevenZ = newNode("application/x-7z-compressed", "7z", matchers.SevenZ)
zip = newNode("application/zip", "zip", matchers.Zip,
xlsx, docx, pptx, epub, jar, odt, ods, odp, odg, odf)
tar = newNode("application/x-tar", "tar", matchers.Tar)
xar = newNode("application/x-xar", "xar", matchers.Xar)
bz2 = newNode("application/x-bzip2", "bz2", matchers.Bz2)
pdf = newNode("application/pdf", "pdf", matchers.Pdf)
xlsx = newNode("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "xlsx", matchers.Xlsx)
docx = newNode("application/vnd.openxmlformats-officedocument.wordprocessingml.document", "docx", matchers.Docx)
pptx = newNode("application/vnd.openxmlformats-officedocument.presentationml.presentation", "pptx", matchers.Pptx)
epub = newNode("application/epub+zip", "epub", matchers.Epub)
jar = newNode("application/jar", "jar", matchers.Jar)
doc = newNode("application/msword", "doc", matchers.Doc)
ppt = newNode("application/vnd.ms-powerpoint", "ppt", matchers.Ppt)
xls = newNode("application/vnd.ms-excel", "xls", matchers.Xls)
ps = newNode("application/postscript", "ps", matchers.Ps)
psd = newNode("application/x-photoshop", "psd", matchers.Psd)
fits = newNode("application/fits", "fits", matchers.Fits)
ogg = newNode("application/ogg", "ogg", matchers.Ogg)
txt = newNode("text/plain", "txt", matchers.Txt,
html, svg, xml, php, js, lua, perl, python, json, rtf, tcl, csv, tsv, vCard)
xml = newNode("text/xml; charset=utf-8", "xml", matchers.Xml,
x3d, kml, collada, gml, gpx, tcx)
json = newNode("application/json", "json", matchers.Json, geoJson)
csv = newNode("text/csv", "csv", matchers.Csv)
tsv = newNode("text/tab-separated-values", "tsv", matchers.Tsv)
geoJson = newNode("application/geo+json", "geojson", matchers.GeoJson)
html = newNode("text/html; charset=utf-8", "html", matchers.Html)
php = newNode("text/x-php; charset=utf-8", "php", matchers.Php)
rtf = newNode("text/rtf", "rtf", matchers.Rtf)
js = newNode("application/javascript", "js", matchers.Js)
lua = newNode("text/x-lua", "lua", matchers.Lua)
perl = newNode("text/x-perl", "pl", matchers.Perl)
python = newNode("application/x-python", "py", matchers.Python)
tcl = newNode("text/x-tcl", "tcl", matchers.Tcl)
vCard = newNode("text/vcard", "vcf", matchers.VCard)
svg = newNode("image/svg+xml", "svg", matchers.Svg)
x3d = newNode("model/x3d+xml", "x3d", matchers.X3d)
kml = newNode("application/vnd.google-earth.kml+xml", "kml", matchers.Kml)
collada = newNode("model/vnd.collada+xml", "dae", matchers.Collada)
gml = newNode("application/gml+xml", "gml", matchers.Gml)
gpx = newNode("application/gpx+xml", "gpx", matchers.Gpx)
tcx = newNode("application/vnd.garmin.tcx+xml", "tcx", matchers.Tcx)
png = newNode("image/png", "png", matchers.Png)
jpg = newNode("image/jpeg", "jpg", matchers.Jpg)
gif = newNode("image/gif", "gif", matchers.Gif)
webp = newNode("image/webp", "webp", matchers.Webp)
tiff = newNode("image/tiff", "tiff", matchers.Tiff)
bmp = newNode("image/bmp", "bmp", matchers.Bmp)
ico = newNode("image/x-icon", "ico", matchers.Ico)
mp3 = newNode("audio/mpeg", "mp3", matchers.Mp3)
flac = newNode("audio/flac", "flac", matchers.Flac)
midi = newNode("audio/midi", "midi", matchers.Midi)
ape = newNode("audio/ape", "ape", matchers.Ape)
musePack = newNode("audio/musepack", "mpc", matchers.MusePack)
wav = newNode("audio/wav", "wav", matchers.Wav)
aiff = newNode("audio/aiff", "aiff", matchers.Aiff)
au = newNode("audio/basic", "au", matchers.Au)
amr = newNode("audio/amr", "amr", matchers.Amr)
aMp4 = newNode("audio/mp4", "mp4", matchers.AMp4)
m4a = newNode("audio/x-m4a", "m4a", matchers.M4a)
mp4 = newNode("video/mp4", "mp4", matchers.Mp4)
webM = newNode("video/webm", "webm", matchers.WebM)
mpeg = newNode("video/mpeg", "mpeg", matchers.Mpeg)
quickTime = newNode("video/quicktime", "mov", matchers.QuickTime)
mqv = newNode("video/quicktime", "mqv", matchers.Mqv)
threeGP = newNode("video/3gpp", "3gp", matchers.ThreeGP)
threeG2 = newNode("video/3gpp2", "3g2", matchers.ThreeG2)
avi = newNode("video/x-msvideo", "avi", matchers.Avi)
flv = newNode("video/x-flv", "flv", matchers.Flv)
mkv = newNode("video/x-matroska", "mkv", matchers.Mkv)
asf = newNode("video/x-ms-asf", "asf", matchers.Asf)
class = newNode("application/x-java-applet; charset=binary", "class", matchers.Class)
swf = newNode("application/x-shockwave-flash", "swf", matchers.Swf)
crx = newNode("application/x-chrome-extension", "crx", matchers.Crx)
woff = newNode("font/woff", "woff", matchers.Woff)
woff2 = newNode("font/woff2", "woff2", matchers.Woff2)
wasm = newNode("application/wasm", "wasm", matchers.Wasm)
shp = newNode("application/octet-stream", "shp", matchers.Shp)
shx = newNode("application/octet-stream", "shx", matchers.Shx, shp)
dbf = newNode("application/x-dbf", "dbf", matchers.Dbf)
exe = newNode("application/vnd.microsoft.portable-executable", "exe", matchers.Exe)
elf = newNode("application/x-elf", "", matchers.Elf, elfObj, elfExe, elfLib, elfDump)
elfObj = newNode("application/x-object", "", matchers.ElfObj)
elfExe = newNode("application/x-executable", "", matchers.ElfExe)
elfLib = newNode("application/x-sharedlib", "so", matchers.ElfLib)
elfDump = newNode("application/x-coredump", "", matchers.ElfDump)
ar = newNode("application/x-archive", "a", matchers.Ar, deb)
deb = newNode("application/vnd.debian.binary-package", "deb", matchers.Deb)
dcm = newNode("application/dicom", "dcm", matchers.Dcm)
odt = newNode("application/vnd.oasis.opendocument.text", "odt", matchers.Odt, ott)
ott = newNode("application/vnd.oasis.opendocument.text-template", "ott", matchers.Ott)
ods = newNode("application/vnd.oasis.opendocument.spreadsheet", "ods", matchers.Ods, ots)
ots = newNode("application/vnd.oasis.opendocument.spreadsheet-template", "ots", matchers.Ots)
odp = newNode("application/vnd.oasis.opendocument.presentation", "odp", matchers.Odp, otp)
otp = newNode("application/vnd.oasis.opendocument.presentation-template", "otp", matchers.Otp)
odg = newNode("application/vnd.oasis.opendocument.graphics", "odg", matchers.Odg, otg)
otg = newNode("application/vnd.oasis.opendocument.graphics-template", "otg", matchers.Otg)
odf = newNode("application/vnd.oasis.opendocument.formula", "odf", matchers.Odf)
gzip = newMIME("application/gzip", ".gz", matchers.Gzip).
alias("application/x-gzip", "application/x-gunzip", "application/gzipped", "application/gzip-compressed", "application/x-gzip-compressed", "gzip/document")
sevenZ = newMIME("application/x-7z-compressed", ".7z", matchers.SevenZ)
zip = newMIME("application/zip", ".zip", matchers.Zip, xlsx, docx, pptx, epub, jar, odt, ods, odp, odg, odf).
alias("application/x-zip", "application/x-zip-compressed")
tar = newMIME("application/x-tar", ".tar", matchers.Tar)
xar = newMIME("application/x-xar", ".xar", matchers.Xar)
bz2 = newMIME("application/x-bzip2", ".bz2", matchers.Bz2)
pdf = newMIME("application/pdf", ".pdf", matchers.Pdf).
alias("application/x-pdf")
xlsx = newMIME("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", ".xlsx", matchers.Xlsx)
docx = newMIME("application/vnd.openxmlformats-officedocument.wordprocessingml.document", ".docx", matchers.Docx)
pptx = newMIME("application/vnd.openxmlformats-officedocument.presentationml.presentation", ".pptx", matchers.Pptx)
epub = newMIME("application/epub+zip", ".epub", matchers.Epub)
jar = newMIME("application/jar", ".jar", matchers.Jar)
ole = newMIME("application/x-ole-storage", "", matchers.Ole, xls, pub, ppt, doc)
doc = newMIME("application/msword", ".doc", matchers.Doc).
alias("application/vnd.ms-word")
ppt = newMIME("application/vnd.ms-powerpoint", ".ppt", matchers.Ppt).
alias("application/mspowerpoint")
pub = newMIME("application/vnd.ms-publisher", ".pub", matchers.Pub)
xls = newMIME("application/vnd.ms-excel", ".xls", matchers.Xls).
alias("application/msexcel")
ps = newMIME("application/postscript", ".ps", matchers.Ps)
fits = newMIME("application/fits", ".fits", matchers.Fits)
ogg = newMIME("application/ogg", ".ogg", matchers.Ogg, oggAudio, oggVideo).
alias("application/x-ogg")
oggAudio = newMIME("audio/ogg", ".oga", matchers.OggAudio)
oggVideo = newMIME("video/ogg", ".ogv", matchers.OggVideo)
utf32le = newMIME("text/plain; charset=utf-32le", ".txt", matchers.Utf32le)
utf32be = newMIME("text/plain; charset=utf-32be", ".txt", matchers.Utf32be)
utf16le = newMIME("text/plain; charset=utf-16le", ".txt", matchers.Utf16le)
utf16be = newMIME("text/plain; charset=utf-16be", ".txt", matchers.Utf16be)
utf8 = newMIME("text/plain; charset=utf-8", ".txt", matchers.Utf8, html, svg, xml, php, js, lua, perl, python, json, ndJson, rtf, tcl, csv, tsv, vCard, iCalendar, warc)
xml = newMIME("text/xml; charset=utf-8", ".xml", matchers.Xml, rss, atom, x3d, kml, xliff, collada, gml, gpx, tcx, amf, threemf)
json = newMIME("application/json", ".json", matchers.Json, geoJson)
csv = newMIME("text/csv", ".csv", matchers.Csv)
tsv = newMIME("text/tab-separated-values", ".tsv", matchers.Tsv)
geoJson = newMIME("application/geo+json", ".geojson", matchers.GeoJson)
ndJson = newMIME("application/x-ndjson", ".ndjson", matchers.NdJson)
html = newMIME("text/html; charset=utf-8", ".html", matchers.Html)
php = newMIME("text/x-php; charset=utf-8", ".php", matchers.Php)
rtf = newMIME("text/rtf", ".rtf", matchers.Rtf)
js = newMIME("application/javascript", ".js", matchers.Js).
alias("application/x-javascript", "text/javascript")
lua = newMIME("text/x-lua", ".lua", matchers.Lua)
perl = newMIME("text/x-perl", ".pl", matchers.Perl)
python = newMIME("application/x-python", ".py", matchers.Python)
tcl = newMIME("text/x-tcl", ".tcl", matchers.Tcl).
alias("application/x-tcl")
vCard = newMIME("text/vcard", ".vcf", matchers.VCard)
iCalendar = newMIME("text/calendar", ".ics", matchers.ICalendar)
svg = newMIME("image/svg+xml", ".svg", matchers.Svg)
rss = newMIME("application/rss+xml", ".rss", matchers.Rss).
alias("text/rss")
atom = newMIME("application/atom+xml", ".atom", matchers.Atom)
x3d = newMIME("model/x3d+xml", ".x3d", matchers.X3d)
kml = newMIME("application/vnd.google-earth.kml+xml", ".kml", matchers.Kml)
xliff = newMIME("application/x-xliff+xml", ".xlf", matchers.Xliff)
collada = newMIME("model/vnd.collada+xml", ".dae", matchers.Collada)
gml = newMIME("application/gml+xml", ".gml", matchers.Gml)
gpx = newMIME("application/gpx+xml", ".gpx", matchers.Gpx)
tcx = newMIME("application/vnd.garmin.tcx+xml", ".tcx", matchers.Tcx)
amf = newMIME("application/x-amf", ".amf", matchers.Amf)
threemf = newMIME("application/vnd.ms-package.3dmanufacturing-3dmodel+xml", ".3mf", matchers.Threemf)
png = newMIME("image/png", ".png", matchers.Png)
jpg = newMIME("image/jpeg", ".jpg", matchers.Jpg)
jp2 = newMIME("image/jp2", ".jp2", matchers.Jp2)
jpx = newMIME("image/jpx", ".jpf", matchers.Jpx)
jpm = newMIME("image/jpm", ".jpm", matchers.Jpm).
alias("video/jpm")
bpg = newMIME("image/bpg", ".bpg", matchers.Bpg)
gif = newMIME("image/gif", ".gif", matchers.Gif)
webp = newMIME("image/webp", ".webp", matchers.Webp)
tiff = newMIME("image/tiff", ".tiff", matchers.Tiff)
bmp = newMIME("image/bmp", ".bmp", matchers.Bmp).
alias("image/x-bmp", "image/x-ms-bmp")
ico = newMIME("image/x-icon", ".ico", matchers.Ico)
icns = newMIME("image/x-icns", ".icns", matchers.Icns)
psd = newMIME("image/vnd.adobe.photoshop", ".psd", matchers.Psd).
alias("image/x-psd", "application/photoshop")
heic = newMIME("image/heic", ".heic", matchers.Heic)
heicSeq = newMIME("image/heic-sequence", ".heic", matchers.HeicSequence)
heif = newMIME("image/heif", ".heif", matchers.Heif)
heifSeq = newMIME("image/heif-sequence", ".heif", matchers.HeifSequence)
mp3 = newMIME("audio/mpeg", ".mp3", matchers.Mp3).
alias("audio/x-mpeg", "audio/mp3")
flac = newMIME("audio/flac", ".flac", matchers.Flac)
midi = newMIME("audio/midi", ".midi", matchers.Midi).
alias("audio/mid", "audio/sp-midi", "audio/x-mid", "audio/x-midi")
ape = newMIME("audio/ape", ".ape", matchers.Ape)
musePack = newMIME("audio/musepack", ".mpc", matchers.MusePack)
wav = newMIME("audio/wav", ".wav", matchers.Wav).
alias("audio/x-wav", "audio/vnd.wave", "audio/wave")
aiff = newMIME("audio/aiff", ".aiff", matchers.Aiff)
au = newMIME("audio/basic", ".au", matchers.Au)
amr = newMIME("audio/amr", ".amr", matchers.Amr).
alias("audio/amr-nb")
aac = newMIME("audio/aac", ".aac", matchers.Aac)
voc = newMIME("audio/x-unknown", ".voc", matchers.Voc)
aMp4 = newMIME("audio/mp4", ".mp4", matchers.AMp4).
alias("audio/x-m4a", "audio/x-mp4a")
m4a = newMIME("audio/x-m4a", ".m4a", matchers.M4a)
mp4 = newMIME("video/mp4", ".mp4", matchers.Mp4)
webM = newMIME("video/webm", ".webm", matchers.WebM).
alias("audio/webm")
mpeg = newMIME("video/mpeg", ".mpeg", matchers.Mpeg)
quickTime = newMIME("video/quicktime", ".mov", matchers.QuickTime)
mqv = newMIME("video/quicktime", ".mqv", matchers.Mqv)
threeGP = newMIME("video/3gpp", ".3gp", matchers.ThreeGP).
alias("video/3gp", "audio/3gpp")
threeG2 = newMIME("video/3gpp2", ".3g2", matchers.ThreeG2).
alias("video/3g2", "audio/3gpp2")
avi = newMIME("video/x-msvideo", ".avi", matchers.Avi).
alias("video/avi", "video/msvideo")
flv = newMIME("video/x-flv", ".flv", matchers.Flv)
mkv = newMIME("video/x-matroska", ".mkv", matchers.Mkv)
asf = newMIME("video/x-ms-asf", ".asf", matchers.Asf).
alias("video/asf", "video/x-ms-wmv")
class = newMIME("application/x-java-applet; charset=binary", ".class", matchers.Class)
swf = newMIME("application/x-shockwave-flash", ".swf", matchers.Swf)
crx = newMIME("application/x-chrome-extension", ".crx", matchers.Crx)
woff = newMIME("font/woff", ".woff", matchers.Woff)
woff2 = newMIME("font/woff2", ".woff2", matchers.Woff2)
otf = newMIME("font/otf", ".otf", matchers.Otf)
eot = newMIME("application/vnd.ms-fontobject", ".eot", matchers.Eot)
wasm = newMIME("application/wasm", ".wasm", matchers.Wasm)
shp = newMIME("application/octet-stream", ".shp", matchers.Shp)
shx = newMIME("application/octet-stream", ".shx", matchers.Shx, shp)
dbf = newMIME("application/x-dbf", ".dbf", matchers.Dbf)
exe = newMIME("application/vnd.microsoft.portable-executable", ".exe", matchers.Exe)
elf = newMIME("application/x-elf", "", matchers.Elf, elfObj, elfExe, elfLib, elfDump)
elfObj = newMIME("application/x-object", "", matchers.ElfObj)
elfExe = newMIME("application/x-executable", "", matchers.ElfExe)
elfLib = newMIME("application/x-sharedlib", ".so", matchers.ElfLib)
elfDump = newMIME("application/x-coredump", "", matchers.ElfDump)
ar = newMIME("application/x-archive", ".a", matchers.Ar, deb).
alias("application/x-unix-archive")
deb = newMIME("application/vnd.debian.binary-package", ".deb", matchers.Deb)
dcm = newMIME("application/dicom", ".dcm", matchers.Dcm)
odt = newMIME("application/vnd.oasis.opendocument.text", ".odt", matchers.Odt, ott).
alias("application/x-vnd.oasis.opendocument.text")
ott = newMIME("application/vnd.oasis.opendocument.text-template", ".ott", matchers.Ott).
alias("application/x-vnd.oasis.opendocument.text-template")
ods = newMIME("application/vnd.oasis.opendocument.spreadsheet", ".ods", matchers.Ods, ots).
alias("application/x-vnd.oasis.opendocument.spreadsheet")
ots = newMIME("application/vnd.oasis.opendocument.spreadsheet-template", ".ots", matchers.Ots).
alias("application/x-vnd.oasis.opendocument.spreadsheet-template")
odp = newMIME("application/vnd.oasis.opendocument.presentation", ".odp", matchers.Odp, otp).
alias("application/x-vnd.oasis.opendocument.presentation")
otp = newMIME("application/vnd.oasis.opendocument.presentation-template", ".otp", matchers.Otp).
alias("application/x-vnd.oasis.opendocument.presentation-template")
odg = newMIME("application/vnd.oasis.opendocument.graphics", ".odg", matchers.Odg, otg).
alias("application/x-vnd.oasis.opendocument.graphics")
otg = newMIME("application/vnd.oasis.opendocument.graphics-template", ".otg", matchers.Otg).
alias("application/x-vnd.oasis.opendocument.graphics-template")
odf = newMIME("application/vnd.oasis.opendocument.formula", ".odf", matchers.Odf).
alias("application/x-vnd.oasis.opendocument.formula")
rar = newMIME("application/x-rar-compressed", ".rar", matchers.Rar).
alias("application/x-rar")
djvu = newMIME("image/vnd.djvu", ".djvu", matchers.DjVu)
mobi = newMIME("application/x-mobipocket-ebook", ".mobi", matchers.Mobi)
lit = newMIME("application/x-ms-reader", ".lit", matchers.Lit)
sqlite3 = newMIME("application/x-sqlite3", ".sqlite", matchers.Sqlite)
dwg = newMIME("image/vnd.dwg", ".dwg", matchers.Dwg).
alias("image/x-dwg", "application/acad", "application/x-acad", "application/autocad_dwg", "application/dwg", "application/x-dwg", "application/x-autocad", "drawing/dwg")
warc = newMIME("application/warc", ".warc", matchers.Warc)
nes = newMIME("application/vnd.nintendo.snes.rom", ".nes", matchers.Nes)
macho = newMIME("application/x-mach-binary", ".macho", matchers.MachO)
qcp = newMIME("audio/qcelp", ".qcp", matchers.Qcp)
mrc = newMIME("application/marc", ".mrc", matchers.Marc)
mdb = newMIME("application/x-msaccess", ".mdb", matchers.MsAccessMdb)
accdb = newMIME("application/x-msaccess", ".accdb", matchers.MsAccessAce)
zstd = newMIME("application/zstd", ".zst", matchers.Zstd)
cab = newMIME("application/vnd.ms-cab-compressed", ".cab", matchers.Cab)
)

10
vendor/modules.txt vendored
View file

@ -9,6 +9,8 @@ github.com/Azure/azure-pipeline-go/pipeline
# github.com/Azure/azure-storage-blob-go v0.8.0
github.com/Azure/azure-storage-blob-go/azblob
# github.com/Unknwon/goconfig v0.0.0-20191126170842-860a72fb44fd
# github.com/OneOfOne/xxhash v1.2.7
github.com/OneOfOne/xxhash
github.com/Unknwon/goconfig
# github.com/a8m/tree v0.0.0-20181222104329-6a0b80129de4
github.com/a8m/tree
@ -91,6 +93,12 @@ github.com/dropbox/dropbox-sdk-go-unofficial/dropbox/team_policies
github.com/dropbox/dropbox-sdk-go-unofficial/dropbox/users
github.com/dropbox/dropbox-sdk-go-unofficial/dropbox/users_common
# github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e
# github.com/etcd-io/bbolt v1.3.3
github.com/etcd-io/bbolt
# github.com/gabriel-vasile/mimetype v1.0.2
github.com/gabriel-vasile/mimetype
github.com/gabriel-vasile/mimetype/internal/json
github.com/gabriel-vasile/mimetype/internal/matchers
github.com/golang/groupcache/lru
# github.com/golang/protobuf v1.3.3
github.com/golang/protobuf/proto
@ -110,6 +118,8 @@ github.com/hanwen/go-fuse/v2/fuse
github.com/hanwen/go-fuse/v2/internal
github.com/hanwen/go-fuse/v2/internal/utimens
github.com/hanwen/go-fuse/v2/splice
# github.com/id01/go-lz4 v1.0.3
github.com/id01/go-lz4
# github.com/inconshreveable/mousetrap v1.0.0
github.com/inconshreveable/mousetrap
# github.com/jlaffaye/ftp v0.0.0-20191218041957-e1b8fdd0dcc3