├── .Rbuildignore
├── .github
├── .gitignore
└── workflows
│ ├── R-CMD-check.yaml
│ ├── github-pages.yml
│ ├── test-coverage.yaml
│ └── update-mimemap.yml
├── .gitignore
├── DESCRIPTION
├── NAMESPACE
├── NEWS.md
├── R
├── mime.R
├── mimeextra.R
├── mimemap.R
└── parse.R
├── README.md
├── inst
└── NEWS.Rd
├── man
├── guess_type.Rd
├── mimemap.Rd
└── parse_multipart.Rd
├── mime.Rproj
├── src
├── init.c
└── rawmatch.c
├── tests
└── mime.R
└── tools
└── update.R
/.Rbuildignore:
--------------------------------------------------------------------------------
1 | ^.*\.Rproj$
2 | ^\.Rproj\.user$
3 | ^\.travis\.yml$
4 | ^\.github$
5 | ^NEWS\.md$
6 | ^tools$
7 |
--------------------------------------------------------------------------------
/.github/.gitignore:
--------------------------------------------------------------------------------
1 | *.html
2 |
--------------------------------------------------------------------------------
/.github/workflows/R-CMD-check.yaml:
--------------------------------------------------------------------------------
1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
3 | on:
4 | push:
5 | branches: [main]
6 | pull_request:
7 | branches: [main]
8 |
9 | name: R-CMD-check
10 |
11 | jobs:
12 | R-CMD-check:
13 | runs-on: ${{ matrix.config.os }}
14 |
15 | name: ${{ matrix.config.os }} (${{ matrix.config.r }})
16 |
17 | strategy:
18 | fail-fast: false
19 | matrix:
20 | config:
21 | - {os: macOS-latest, r: 'release'}
22 | - {os: windows-latest, r: 'release'}
23 | - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'}
24 | - {os: ubuntu-latest, r: 'release'}
25 | - {os: ubuntu-latest, r: 'oldrel'}
26 |
27 | env:
28 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
29 | R_KEEP_PKG_SOURCE: yes
30 |
31 | steps:
32 | - uses: actions/checkout@HEAD
33 |
34 | - uses: r-lib/actions/setup-r@HEAD
35 | with:
36 | r-version: ${{ matrix.config.r }}
37 | http-user-agent: ${{ matrix.config.http-user-agent }}
38 | use-public-rspm: true
39 |
40 | - uses: r-lib/actions/setup-r-dependencies@HEAD
41 | with:
42 | extra-packages: any::rcmdcheck
43 | needs: check
44 |
45 | - uses: r-lib/actions/check-r-package@HEAD
46 | with:
47 | upload-snapshots: true
48 |
--------------------------------------------------------------------------------
/.github/workflows/github-pages.yml:
--------------------------------------------------------------------------------
1 | name: Build and deploy package site
2 |
3 | on:
4 | push:
5 | branches: ["main"]
6 |
7 | permissions:
8 | contents: read
9 | pages: write
10 | id-token: write
11 |
12 | jobs:
13 | deploy:
14 | environment:
15 | name: github-pages
16 | url: ${{ steps.deployment.outputs.page_url }}
17 | runs-on: ubuntu-latest
18 | steps:
19 | - uses: actions/checkout@v4
20 | - uses: actions/configure-pages@v5
21 | with:
22 | enablement: true
23 | - uses: r-lib/actions/setup-r@HEAD
24 | with:
25 | use-public-rspm: true
26 | - uses: r-lib/actions/setup-r-dependencies@HEAD
27 | - uses: yihui/litedown/site@HEAD
28 | with:
29 | site-dir: 'site'
30 | - uses: actions/upload-pages-artifact@v3
31 | with:
32 | path: 'site'
33 | - id: deployment
34 | uses: actions/deploy-pages@v4
35 |
--------------------------------------------------------------------------------
/.github/workflows/test-coverage.yaml:
--------------------------------------------------------------------------------
1 | on:
2 | push:
3 | branches: [main]
4 | pull_request:
5 | branches: [main]
6 |
7 | name: test-coverage
8 |
9 | jobs:
10 | test-coverage:
11 | runs-on: macOS-latest
12 | env:
13 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
14 | steps:
15 | - uses: actions/checkout@HEAD
16 |
17 | - uses: r-lib/actions/setup-r@HEAD
18 |
19 | - uses: r-lib/actions/setup-r-dependencies@HEAD
20 | with:
21 | extra-packages: any::covr
22 |
23 | - name: Test coverage
24 | run: covr::codecov()
25 | shell: Rscript {0}
26 |
--------------------------------------------------------------------------------
/.github/workflows/update-mimemap.yml:
--------------------------------------------------------------------------------
1 | on:
2 | push:
3 | branches: [main]
4 | pull_request:
5 | branches: [main]
6 | workflow_dispatch:
7 | schedule:
8 | - cron: '5 3 1 * *'
9 |
10 | name: Update mimemap
11 |
12 | jobs:
13 | update-mimemap:
14 | runs-on: ubuntu-latest
15 |
16 | steps:
17 | - uses: actions/checkout@HEAD
18 |
19 | - uses: r-lib/actions/setup-r@HEAD
20 | with:
21 | use-public-rspm: true
22 |
23 | - uses: r-lib/actions/setup-r-dependencies@HEAD
24 |
25 | - run: |
26 | Rscript tools/update.R
27 | echo "OS_INFO=$(uname -sr)" >> $GITHUB_ENV
28 |
29 | - name: Create Pull Request
30 | uses: peter-evans/create-pull-request@v5
31 | with:
32 | title: Update mimemap
33 | body: Update mimemap by running `tools/update.R`.
34 | commit-message: Update mimemap from ${{ env.OS_INFO }}
35 | add-paths: |
36 | R/mimemap.R
37 | R/mimeextra.R
38 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .Rproj.user
2 | .Rhistory
3 | .RData
4 | src/*.o
5 | src/*.so
6 |
--------------------------------------------------------------------------------
/DESCRIPTION:
--------------------------------------------------------------------------------
1 | Package: mime
2 | Type: Package
3 | Title: Map Filenames to MIME Types
4 | Version: 0.13.1
5 | Authors@R: c(
6 | person("Yihui", "Xie", role = c("aut", "cre"), email = "xie@yihui.name", comment = c(ORCID = "0000-0003-0645-5666", URL = "https://yihui.org")),
7 | person("Jeffrey", "Horner", role = "ctb"),
8 | person("Beilei", "Bian", role = "ctb")
9 | )
10 | Description: Guesses the MIME type from a filename extension using the data
11 | derived from /etc/mime.types in UNIX-type systems.
12 | Imports:
13 | tools
14 | License: GPL
15 | URL: https://github.com/yihui/mime
16 | BugReports: https://github.com/yihui/mime/issues
17 | Roxygen: list(markdown = TRUE)
18 | RoxygenNote: 7.3.2
19 | Encoding: UTF-8
20 |
--------------------------------------------------------------------------------
/NAMESPACE:
--------------------------------------------------------------------------------
1 | # Generated by roxygen2: do not edit by hand
2 |
3 | export(guess_type)
4 | export(mimemap)
5 | export(parse_multipart)
6 | import(utils)
7 | useDynLib(mime, .registration = TRUE)
8 |
--------------------------------------------------------------------------------
/NEWS.md:
--------------------------------------------------------------------------------
1 | # CHANGES IN mime VERSION 0.14
2 |
3 |
4 | # CHANGES IN mime VERSION 0.13
5 |
6 | - Synced the MIME types from the latest version of Ubuntu, so that `.wasm` files can be recognized (thanks, @wch, #22).
7 |
8 | # CHANGES IN mime VERSION 0.12
9 |
10 | - Fixed bugs #15 and #16 in `parse_multipart()` (thanks, @michalkouril).
11 |
12 | # CHANGES IN mime VERSION 0.11
13 |
14 | - Removed the unused `LazyData` field in `DESCRIPTION`.
15 |
16 | # CHANGES IN mime VERSION 0.10
17 |
18 | - Add mimetype for OGC GeoPackage (.gpkg extension) (thanks, @eblondel, #14).
19 |
20 | # CHANGES IN mime VERSION 0.9
21 |
22 | - Added the MIME type for .jsonp files (thanks, @clabornd, #11).
23 |
24 | # CHANGES IN mime VERSION 0.8
25 |
26 | - Added the MIME type for .scss files (thanks, @cpsievert, #10).
27 |
28 | # CHANGES IN mime VERSION 0.7
29 |
30 | - Added more types for .Rnw, .Rproj, and .yml files (thanks, @beanumber, #9).
31 |
32 | # CHANGES IN mime VERSION 0.6
33 |
34 | - Updated the MIME types from Ubuntu 18.04.
35 |
36 | # CHANGES IN mime VERSION 0.5
37 |
38 | - the package license was changed from GPL-2 to GPL
39 |
40 | # CHANGES IN mime VERSION 0.4
41 |
42 | - added a new content type: .geojson -> application/vnd.geo+json (thanks, @dmpe, #3)
43 |
44 | - guess_type() may fail on Windows when the file paths are too long (#2)
45 |
46 | # CHANGES IN mime VERSION 0.3
47 |
48 | - added a few more content types
49 |
50 | # CHANGES IN mime VERSION 0.2
51 |
52 | - added a function parse_multipart() to parse multipart form data submitted via HTTP POST
53 |
54 | # CHANGES IN mime VERSION 0.1.2
55 |
56 | - guess_type() returned wrong values for filenames without extensions: it should have used the 'empty' argument.
57 |
58 | # CHANGES IN mime VERSION 0.1.1
59 |
60 | - mime::guess_type() may not work when mime is loaded but not attached, because R does not load the mimemap data in this case. Now mimemap is exported in the package namespace.
61 |
62 | # CHANGES IN mime VERSION 0.1
63 |
64 | - The initial version of mime. The main function is mime::guess_type().
65 |
66 |
--------------------------------------------------------------------------------
/R/mime.R:
--------------------------------------------------------------------------------
1 | #' @import utils
2 | NULL
3 |
4 | #' Tables for mapping filename extensions to MIME types
5 | #'
6 | #' The data `mimemap` is a named character vector that stores the filename
7 | #' extensions and the corresponding MIME types, e.g. `c(html = 'text/html', pdf
8 | #' = 'application/pdf', ...)`. The character vector `mime:::mimeextra` stores
9 | #' some additional types that we know, such as Markdown files (`.md`), or R
10 | #' scripts (`.R`).
11 | #' @docType data
12 | #' @usage NULL
13 | #' @format NULL
14 | #' @source The file `/etc/mime.types` on Debian.
15 | #' @export
16 | #' @examples str(as.list(mimemap))
17 | #' mimemap['pdf']
18 | #' mimemap[c('html', 'js', 'css')]
19 | #' # additional MIME types (not exported)
20 | #' mime:::mimeextra
21 | 'mimemap'
22 |
23 | #' Guess the MIME types from filenames
24 | #'
25 | #' Look up in the [`mimemap`] table for the MIME types based on the extensions of
26 | #' the given filenames.
27 | #' @param file a character vector of filenames, or filename extensions
28 | #' @param unknown the MIME type to return when the file extension was not found
29 | #' in the table
30 | #' @param empty the MIME type for files that do not have extensions
31 | #' @param mime_extra a named character vector of the form `c(extension = type)`
32 | #' providing extra MIME types (by default, `mime:::mimeextra`); note this MIME
33 | #' table takes precedence over the standard table [`mimemap`]
34 | #' @param subtype a character vector of MIME subtypes, which should be of the
35 | #' same length as `file` if provided (use an empty character string for a file
36 | #' if we do not want a subtype for it)
37 | #' @examples
38 | #' library(mime)
39 | #' # well-known file types
40 | #' guess_type(c('a/b/c.html', 'd.pdf', 'e.odt', 'foo.docx', 'tex'))
41 | #' # not in the standard table, but in mimeextra
42 | #' guess_type(c('a.md', 'b.R'), mime_extra = NULL)
43 | #' guess_type(c('a.md', 'b.R'))
44 | #'
45 | #' # override the standard MIME table (tex is text/x-tex by default)
46 | #' guess_type('tex', mime_extra = c(tex = 'text/plain'))
47 | #' # unknown extension 'zzz'
48 | #' guess_type('foo.zzz')
49 | #' # force unknown types to be plain text
50 | #' guess_type('foo.zzz', unknown = 'text/plain')
51 | #'
52 | #' # empty file extension
53 | #' guess_type('Makefile')
54 | #' # we know it is a plain text file
55 | #' guess_type('Makefile', empty = 'text/plain')
56 | #'
57 | #' # subtypes
58 | #' guess_type(c('abc.html', 'def.htm'), subtype = c('charset=UTF-8', ''))
59 | #' @export
60 | guess_type = function(file, unknown = 'application/octet-stream',
61 | empty = 'text/plain', mime_extra = mimeextra, subtype = '') {
62 | # TODO: remove this workaround
63 | if ('RestRserve' %in% loadedNamespaces() && packageVersion('RestRserve') <= '1.2.4')
64 | mimemap['js'] = 'application/javascript'
65 | file = basename(file)
66 | # only need 'bar' from 'foo.bar'
67 | file = tools::file_ext(file)
68 | type = unname(c(mime_extra, mimemap)[tolower(file)])
69 | type[file == ''] = empty
70 | type[is.na(type)] = unknown # unknown file extensions
71 | if (any(i <- subtype != '')) {
72 | if (length(type) != length(file))
73 | stop("'subtype' must be of the same length as 'file'")
74 | type[i] = paste(type[i], subtype[i], sep = '; ')
75 | }
76 | type
77 | }
78 |
79 | if (.Platform$OS.type == 'windows') basename = function(path) {
80 | if (length(path) == 0) return(path)
81 | tryCatch(base::basename(path), error = function(e) {
82 | vapply(strsplit(path, '[\\/]+'), tail, character(1), 1, USE.NAMES = FALSE)
83 | })
84 | }
85 |
--------------------------------------------------------------------------------
/R/mimeextra.R:
--------------------------------------------------------------------------------
1 | mimeextra = c(
2 | jsonp = "application/javascript",
3 | r = "text/plain",
4 | rd = "text/plain",
5 | rmd = "text/x-markdown",
6 | rnw = "text/x-sweave",
7 | rproj = "text/rstudio",
8 | scss = "text/css"
9 | )
10 |
--------------------------------------------------------------------------------
/R/mimemap.R:
--------------------------------------------------------------------------------
1 | mimemap = c(
2 | `%` = "application/x-trash",
3 | `~` = "application/x-trash",
4 | `123` = "application/vnd.lotus-1-2-3",
5 | `1905.1` = "application/vnd.ieee.1905",
6 | `1clr` = "application/clr",
7 | `1km` = "application/vnd.1000minds.decision-model+xml",
8 | `210` = "application/p21",
9 | `3dm` = "text/vnd.in3d.3dml",
10 | `3dml` = "text/vnd.in3d.3dml",
11 | `3mf` = "application/vnd.ms-3mfdocument",
12 | `3tz` = "application/vnd.maxar.archive.3tz+zip",
13 | `726` = "audio/32kadpcm",
14 | `7z` = "application/x-7z-compressed",
15 | a = "text/vnd.a",
16 | a2l = "application/A2L",
17 | aa3 = "audio/ATRAC3",
18 | aac = "audio/aac",
19 | aal = "audio/ATRAC-ADVANCED-LOSSLESS",
20 | abc = "text/vnd.abc",
21 | abw = "application/x-abiword",
22 | ac = "application/pkix-attr-cert",
23 | ac2 = "application/vnd.banana-accounting",
24 | ac3 = "audio/ac3",
25 | acc = "application/vnd.americandynamics.acc",
26 | acn = "audio/asc",
27 | acu = "application/vnd.acucobol",
28 | acutc = "application/vnd.acucorp",
29 | adts = "audio/aac",
30 | aep = "application/vnd.audiograph",
31 | afp = "application/vnd.afpc.modca",
32 | age = "application/vnd.age",
33 | ahead = "application/vnd.ahead.space",
34 | ai = "application/postscript",
35 | aif = "audio/x-aiff",
36 | aifc = "audio/x-aiff",
37 | aiff = "audio/x-aiff",
38 | aion = "application/vnd.veritone.aion+json",
39 | ait = "application/vnd.dvb.ait",
40 | alc = "chemical/x-alchemy",
41 | ami = "application/vnd.amiga.ami",
42 | aml = "application/AML",
43 | amlx = "application/automationml-amlx+zip",
44 | amr = "audio/AMR",
45 | AMR = "audio/AMR",
46 | anx = "application/annodex",
47 | apex = "application/vnd.apexlang",
48 | apexlang = "application/vnd.apexlang",
49 | apk = "application/vnd.android.package-archive",
50 | apkg = "application/vnd.anki",
51 | apng = "image/apng",
52 | appcache = "text/cache-manifest",
53 | apr = "application/vnd.lotus-approach",
54 | apxml = "application/auth-policy+xml",
55 | arrow = "application/vnd.apache.arrow.file",
56 | arrows = "application/vnd.apache.arrow.stream",
57 | art = "image/x-jg",
58 | artisan = "application/vnd.artisan+json",
59 | asc = "application/pgp-keys",
60 | ascii = "text/vnd.ascii-art",
61 | asf = "application/vnd.ms-asf",
62 | asice = "application/vnd.etsi.asic-e+zip",
63 | asics = "application/vnd.etsi.asic-s+zip",
64 | asn = "chemical/x-ncbi-asn1",
65 | aso = "application/vnd.accpac.simply.aso",
66 | ass = "audio/aac",
67 | at3 = "audio/ATRAC3",
68 | atc = "application/vnd.acucorp",
69 | atf = "application/ATF",
70 | atfx = "application/ATFX",
71 | atom = "application/atom+xml",
72 | atomcat = "application/atomcat+xml",
73 | atomdeleted = "application/atomdeleted+xml",
74 | atomsrv = "application/atomserv+xml",
75 | atomsvc = "application/atomsvc+xml",
76 | atx = "audio/ATRAC-X",
77 | atxml = "application/ATXML",
78 | au = "audio/basic",
79 | auc = "application/tamp-apex-update-confirm",
80 | avci = "image/avci",
81 | avcs = "image/avcs",
82 | avi = "video/x-msvideo",
83 | avif = "image/avif",
84 | awb = "audio/AMR-WB",
85 | AWB = "audio/AMR-WB",
86 | axa = "audio/annodex",
87 | axv = "video/annodex",
88 | azf = "application/vnd.airzip.filesecure.azf",
89 | azs = "application/vnd.airzip.filesecure.azs",
90 | azv = "image/vnd.airzip.accelerator.azv",
91 | azw3 = "application/vnd.amazon.mobi8-ebook",
92 | b = "chemical/x-molconn-Z",
93 | b16 = "image/vnd.pco.b16",
94 | bak = "application/x-trash",
95 | bar = "application/vnd.qualcomm.brew-app-res",
96 | bary = "model/vnd.bary",
97 | bat = "application/x-msdos-program",
98 | bcpio = "application/x-bcpio",
99 | bdm = "application/vnd.syncml.dm+wbxml",
100 | bed = "application/vnd.realvnc.bed",
101 | bh2 = "application/vnd.fujitsu.oasysprs",
102 | bib = "text/x-bibtex",
103 | bik = "video/vnd.radgamettools.bink",
104 | bin = "application/octet-stream",
105 | bk2 = "video/vnd.radgamettools.bink",
106 | bkm = "application/vnd.nervana",
107 | bmed = "multipart/vnd.bint.med-plus",
108 | bmi = "application/vnd.bmi",
109 | bmml = "application/vnd.balsamiq.bmml+xml",
110 | bmp = "image/bmp",
111 | bmpr = "application/vnd.balsamiq.bmpr",
112 | boo = "text/x-boo",
113 | book = "application/x-maker",
114 | box = "application/vnd.previewsystems.box",
115 | bpd = "application/vnd.hbci",
116 | brf = "text/plain",
117 | bsd = "chemical/x-crossfire",
118 | bsp = "model/vnd.valve.source.compiled-map",
119 | btf = "image/prs.btif",
120 | btif = "image/prs.btif",
121 | c = "text/x-csrc",
122 | `c++` = "text/x-c++src",
123 | c11amc = "application/vnd.cluetrust.cartomobile-config",
124 | c11amz = "application/vnd.cluetrust.cartomobile-config-pkg",
125 | c3d = "chemical/x-chem3d",
126 | c3ex = "application/cccex",
127 | c4d = "application/vnd.clonk.c4group",
128 | c4f = "application/vnd.clonk.c4group",
129 | c4g = "application/vnd.clonk.c4group",
130 | c4p = "application/vnd.clonk.c4group",
131 | c4u = "application/vnd.clonk.c4group",
132 | c9r = "application/vnd.cryptomator.encrypted",
133 | c9s = "application/vnd.cryptomator.encrypted",
134 | cab = "application/vnd.ms-cab-compressed",
135 | cac = "chemical/x-cache",
136 | cache = "chemical/x-cache",
137 | cap = "application/vnd.tcpdump.pcap",
138 | car = "application/vnd.ipld.car",
139 | carjson = "application/vnd.eu.kasparian.car+json",
140 | cascii = "chemical/x-cactvs-binary",
141 | cat = "application/vnd.ms-pki.seccat",
142 | cbin = "chemical/x-cactvs-binary",
143 | cbor = "application/cbor",
144 | cbr = "application/vnd.comicbook-rar",
145 | cbz = "application/vnd.comicbook+zip",
146 | cc = "text/x-c++src",
147 | ccc = "text/vnd.net2phone.commcenter.command",
148 | ccmp = "application/ccmp+xml",
149 | ccxml = "application/ccxml+xml",
150 | cda = "application/x-cdf",
151 | cdbcmsg = "application/vnd.contact.cmsg",
152 | cdf = "application/x-cdf",
153 | cdfx = "application/CDFX+XML",
154 | cdkey = "application/vnd.mediastation.cdkey",
155 | cdmia = "application/cdmi-capability",
156 | cdmic = "application/cdmi-container",
157 | cdmid = "application/cdmi-domain",
158 | cdmio = "application/cdmi-object",
159 | cdmiq = "application/cdmi-queue",
160 | cdr = "image/x-coreldraw",
161 | cdt = "image/x-coreldrawtemplate",
162 | cdx = "chemical/x-cdx",
163 | cdxml = "application/vnd.chemdraw+xml",
164 | cdy = "application/vnd.cinderella",
165 | cea = "application/CEA",
166 | cef = "chemical/x-cxf",
167 | cellml = "application/cellml+xml",
168 | cer = "application/pkix-cert",
169 | cgm = "image/cgm",
170 | chm = "application/vnd.ms-htmlhelp",
171 | chrt = "application/vnd.kde.kchart",
172 | cif = "application/vnd.multiad.creator.cif",
173 | cii = "application/vnd.anser-web-certificate-issue-initiation",
174 | cil = "application/vnd.ms-artgalry",
175 | cl = "application/simple-filter+xml",
176 | cla = "application/vnd.claymore",
177 | class = "application/java-vm",
178 | cld = "model/vnd.cld",
179 | clkk = "application/vnd.crick.clicker.keyboard",
180 | clkp = "application/vnd.crick.clicker.palette",
181 | clkt = "application/vnd.crick.clicker.template",
182 | clkw = "application/vnd.crick.clicker.wordbank",
183 | clkx = "application/vnd.crick.clicker",
184 | cls = "text/x-tex",
185 | clue = "application/clue_info+xml",
186 | cmc = "application/vnd.cosmocaller",
187 | cmdf = "chemical/x-cmdf",
188 | cml = "application/cellml+xml",
189 | cmp = "application/vnd.yellowriver-custom-menu",
190 | cmsc = "application/cms",
191 | cnd = "text/jcr-cnd",
192 | cod = "application/vnd.rim.cod",
193 | coffee = "application/vnd.coffeescript",
194 | com = "application/x-msdos-program",
195 | copyright = "text/vnd.debian.copyright",
196 | coswid = "application/swid+cbor",
197 | cpa = "chemical/x-compass",
198 | cpio = "application/x-cpio",
199 | cpkg = "application/vnd.xmpie.cpkg",
200 | cpl = "application/cpl+xml",
201 | cpp = "text/x-c++src",
202 | cpt = "application/mac-compactpro",
203 | CQL = "text/cql",
204 | cr2 = "image/x-canon-cr2",
205 | crl = "application/pkix-crl",
206 | crt = "application/x-x509-ca-cert",
207 | crtr = "application/vnd.multiad.creator",
208 | crw = "image/x-canon-crw",
209 | cryptomator = "application/vnd.cryptomator.vault",
210 | cryptonote = "application/vnd.rig.cryptonote",
211 | csd = "audio/csound",
212 | csf = "chemical/x-cache-csf",
213 | csh = "application/x-csh",
214 | csl = "application/vnd.citationstyles.style+xml",
215 | csm = "chemical/x-csml",
216 | csml = "chemical/x-csml",
217 | csp = "application/vnd.commonspace",
218 | csrattrs = "application/csrattrs",
219 | css = "text/css",
220 | cst = "application/vnd.commonspace",
221 | csv = "text/csv",
222 | csvs = "text/csv-schema",
223 | ctab = "chemical/x-cactvs-binary",
224 | ctx = "chemical/x-ctx",
225 | cu = "application/cu-seeme",
226 | cub = "chemical/x-gaussian-cube",
227 | cuc = "application/tamp-community-update-confirm",
228 | curl = "text/vnd.curl",
229 | cw = "application/prs.cww",
230 | cwl = "application/cwl",
231 | cwl.json = "application/cwl+json",
232 | cww = "application/prs.cww",
233 | cxf = "chemical/x-cxf",
234 | cxx = "text/x-c++src",
235 | d = "text/x-dsrc",
236 | dae = "model/vnd.collada+xml",
237 | daf = "application/vnd.Mobius.DAF",
238 | dart = "application/vnd.dart",
239 | dataless = "application/vnd.fdsn.seed",
240 | davmount = "application/davmount+xml",
241 | dbf = "application/vnd.dbf",
242 | dcd = "application/DCD",
243 | dcm = "application/dicom",
244 | dcr = "application/x-director",
245 | dd2 = "application/vnd.oma.dd2+xml",
246 | ddd = "application/vnd.fujixerox.ddd",
247 | ddeb = "application/vnd.debian.binary-package",
248 | ddf = "application/vnd.syncml.dmddf+xml",
249 | deb = "application/vnd.debian.binary-package",
250 | deploy = "application/octet-stream",
251 | dfac = "application/vnd.dreamfactory",
252 | dif = "video/dv",
253 | diff = "text/x-diff",
254 | dii = "application/DII",
255 | dim = "application/vnd.fastcopy-disk-image",
256 | dir = "application/x-director",
257 | dis = "application/vnd.Mobius.DIS",
258 | dist = "application/vnd.apple.installer+xml",
259 | distz = "application/vnd.apple.installer+xml",
260 | dit = "application/DIT",
261 | dive = "application/vnd.patentdive",
262 | djv = "image/vnd.djvu",
263 | djvu = "image/vnd.djvu",
264 | dl = "application/vnd.datalog",
265 | dll = "application/x-msdos-program",
266 | dls = "audio/dls",
267 | dmg = "application/x-apple-diskimage",
268 | dmp = "application/vnd.tcpdump.pcap",
269 | dms = "text/vnd.DMClientScript",
270 | dna = "application/vnd.dna",
271 | doc = "application/msword",
272 | docjson = "application/vnd.document+json",
273 | docm = "application/vnd.ms-word.document.macroEnabled.12",
274 | docx = "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
275 | dor = "model/vnd.gdl",
276 | dot = "text/vnd.graphviz",
277 | dotm = "application/vnd.ms-word.template.macroEnabled.12",
278 | dotx = "application/vnd.openxmlformats-officedocument.wordprocessingml.template",
279 | dp = "application/vnd.osgi.dp",
280 | dpg = "application/vnd.dpgraph",
281 | dpgraph = "application/vnd.dpgraph",
282 | dpkg = "application/vnd.xmpie.dpkg",
283 | dpx = "image/dpx",
284 | drle = "image/dicom-rle",
285 | dsc = "text/prs.lines.tag",
286 | dsm = "application/vnd.desmume.movie",
287 | dssc = "application/dssc+der",
288 | dtd = "application/xml-dtd",
289 | dts = "audio/vnd.dts",
290 | dtshd = "audio/vnd.dts.hd",
291 | dv = "video/dv",
292 | dvb = "video/vnd.dvb.file",
293 | dvc = "application/dvcs",
294 | dvi = "application/x-dvi",
295 | dwd = "application/atsc-dwd+xml",
296 | dwf = "model/vnd.dwf",
297 | dwg = "image/vnd.dwg",
298 | dx = "chemical/x-jcamp-dx",
299 | dxf = "image/vnd.dxf",
300 | dxp = "application/vnd.spotfire.dxp",
301 | dxr = "application/x-director",
302 | dzr = "application/vnd.dzr",
303 | ebuild = "application/vnd.gentoo.ebuild",
304 | ecelp4800 = "audio/vnd.nuera.ecelp4800",
305 | ecelp7470 = "audio/vnd.nuera.ecelp7470",
306 | ecelp9600 = "audio/vnd.nuera.ecelp9600",
307 | ecig = "application/vnd.evolv.ecig.settings",
308 | ecigprofile = "application/vnd.evolv.ecig.profile",
309 | ecigtheme = "application/vnd.evolv.ecig.theme",
310 | eclass = "application/vnd.gentoo.eclass",
311 | edm = "application/vnd.novadigm.EDM",
312 | edx = "application/vnd.novadigm.EDX",
313 | efi = "application/efi",
314 | efif = "application/vnd.picsel",
315 | ei6 = "application/vnd.pg.osasli",
316 | ELN = "application/vnd.eln+zip",
317 | emb = "chemical/x-embl-dl-nucleotide",
318 | embl = "chemical/x-embl-dl-nucleotide",
319 | emf = "image/emf",
320 | eml = "message/rfc822",
321 | emm = "application/vnd.ibm.electronic-media",
322 | emma = "application/emma+xml",
323 | emotionml = "application/emotionml+xml",
324 | ent = "application/xml-external-parsed-entity",
325 | entity = "application/vnd.nervana",
326 | enw = "audio/EVRCNW",
327 | eol = "audio/vnd.digital-winds",
328 | eot = "application/vnd.ms-fontobject",
329 | ep = "application/vnd.bluetooth.ep.oob",
330 | eps = "application/postscript",
331 | eps2 = "application/postscript",
332 | eps3 = "application/postscript",
333 | epsf = "application/postscript",
334 | epsi = "application/postscript",
335 | epub = "application/epub+zip",
336 | erf = "image/x-epson-erf",
337 | es = "text/javascript",
338 | es3 = "application/vnd.eszigno3+xml",
339 | esa = "application/vnd.osgi.subsystem",
340 | esf = "application/vnd.epson.esf",
341 | espass = "application/vnd.espass-espass+zip",
342 | et3 = "application/vnd.eszigno3+xml",
343 | etx = "text/x-setext",
344 | evb = "audio/EVRCB",
345 | evc = "audio/EVRC",
346 | evw = "audio/EVRCWB",
347 | exe = "application/x-msdos-program",
348 | exi = "application/exi",
349 | exp = "application/express",
350 | exr = "image/aces",
351 | ext = "application/vnd.novadigm.EXT",
352 | ez = "application/andrew-inset",
353 | ez2 = "application/vnd.ezpix-album",
354 | ez3 = "application/vnd.ezpix-package",
355 | fb = "application/x-maker",
356 | fbdoc = "application/x-maker",
357 | fbs = "image/vnd.fastbidsheet",
358 | fcdt = "application/vnd.adobe.formscentral.fcdt",
359 | fch = "chemical/x-gaussian-checkpoint",
360 | fchk = "chemical/x-gaussian-checkpoint",
361 | fcs = "application/vnd.isac.fcs",
362 | fdf = "application/fdf",
363 | fdt = "application/fdt+xml",
364 | fe_launch = "application/vnd.denovo.fcselayout-link",
365 | fg5 = "application/vnd.fujitsu.oasysgp",
366 | fig = "application/x-xfig",
367 | finf = "application/fastinfoset",
368 | fit = "image/fits",
369 | fits = "image/fits",
370 | fla = "application/vnd.dtg.local.flash",
371 | flac = "audio/flac",
372 | flb = "application/vnd.ficlab.flb+zip",
373 | fli = "video/fli",
374 | flo = "application/vnd.micrografx.flo",
375 | flt = "text/vnd.ficlab.flt",
376 | flv = "video/x-flv",
377 | flw = "application/vnd.kde.kivio",
378 | flx = "text/vnd.fmi.flexstor",
379 | fly = "text/vnd.fly",
380 | fm = "application/vnd.framemaker",
381 | fo = "application/vnd.software602.filler.form+xml",
382 | fpx = "image/vnd.fpx",
383 | frame = "application/x-maker",
384 | frm = "application/vnd.ufdl",
385 | fsc = "application/vnd.fsc.weblaunch",
386 | fst = "image/vnd.fst",
387 | ftc = "application/vnd.fluxtime.clip",
388 | fti = "application/vnd.anser-web-funds-transfer-initiation",
389 | fts = "image/fits",
390 | fvt = "video/vnd.fvt",
391 | fxp = "application/vnd.adobe.fxp",
392 | fxpl = "application/vnd.adobe.fxp",
393 | fzs = "application/vnd.fuzzysheet",
394 | g2w = "application/vnd.geoplan",
395 | g3w = "application/vnd.geospace",
396 | gac = "application/vnd.groove-account",
397 | gal = "chemical/x-gaussian-log",
398 | gam = "chemical/x-gamess-input",
399 | gamin = "chemical/x-gamess-input",
400 | gan = "application/x-ganttproject",
401 | gau = "chemical/x-gaussian-input",
402 | gbr = "application/rpki-ghostbusters",
403 | gcd = "text/x-pcs-gcd",
404 | gcf = "application/x-graphing-calculator",
405 | gcg = "chemical/x-gcg8-sequence",
406 | gdl = "model/vnd.gdl",
407 | gdz = "application/vnd.familysearch.gedcom+zip",
408 | ged = "text/vnd.familysearch.gedcom",
409 | gen = "chemical/x-genbank",
410 | genozip = "application/vnd.genozip",
411 | geo = "application/vnd.dynageo",
412 | geojson = "application/geo+json",
413 | gex = "application/vnd.geometry-explorer",
414 | gf = "application/x-tex-gf",
415 | gff3 = "text/gff3",
416 | ggb = "application/vnd.geogebra.file",
417 | ggs = "application/vnd.geogebra.slides",
418 | ggt = "application/vnd.geogebra.tool",
419 | ghf = "application/vnd.groove-help",
420 | gif = "image/gif",
421 | gim = "application/vnd.groove-identity-message",
422 | gjc = "chemical/x-gaussian-input",
423 | gjf = "chemical/x-gaussian-input",
424 | gl = "video/gl",
425 | glb = "model/gltf-binary",
426 | glbin = "application/gltf-buffer",
427 | glbuf = "application/gltf-buffer",
428 | gltf = "model/gltf+json",
429 | gml = "application/gml+xml",
430 | gnumeric = "application/x-gnumeric",
431 | gph = "application/vnd.FloGraphIt",
432 | gpkg = "application/geopackage+sqlite3",
433 | gpkg.tar = "application/vnd.gentoo.gpkg",
434 | gpt = "chemical/x-mopac-graph",
435 | gqf = "application/vnd.grafeq",
436 | gqs = "application/vnd.grafeq",
437 | gram = "application/srgs",
438 | grd = "application/vnd.gentics.grd+json",
439 | gre = "application/vnd.geometry-explorer",
440 | grv = "application/vnd.groove-injector",
441 | grxml = "application/srgs+xml",
442 | gsf = "application/x-font",
443 | gsheet = "application/urc-grpsheet+xml",
444 | gsm = "audio/x-gsm",
445 | gtar = "application/x-gtar",
446 | gtm = "application/vnd.groove-tool-message",
447 | gtw = "model/vnd.gtw",
448 | gv = "text/vnd.graphviz",
449 | gxt = "application/vnd.geonext",
450 | gz = "application/gzip",
451 | h = "text/x-chdr",
452 | `h++` = "text/x-c++hdr",
453 | hal = "application/vnd.hal+xml",
454 | hans = "text/vnd.hans",
455 | hbc = "application/vnd.hbci",
456 | hbci = "application/vnd.hbci",
457 | hdf = "application/x-hdf",
458 | hdr = "image/vnd.radiance",
459 | hdt = "application/vnd.hdt",
460 | heic = "image/heic",
461 | heics = "image/heic-sequence",
462 | heif = "image/heif",
463 | heifs = "image/heif-sequence",
464 | hej2 = "image/hej2k",
465 | held = "application/atsc-held+xml",
466 | hgl = "text/vnd.hgl",
467 | hh = "text/x-c++hdr",
468 | hif = "image/avif",
469 | hin = "chemical/x-hin",
470 | hpgl = "application/vnd.hp-HPGL",
471 | hpi = "application/vnd.hp-hpid",
472 | hpid = "application/vnd.hp-hpid",
473 | hpp = "text/x-c++hdr",
474 | hps = "application/vnd.hp-hps",
475 | hpub = "application/prs.hpub+zip",
476 | hqx = "application/mac-binhex40",
477 | hs = "text/x-haskell",
478 | hsj2 = "image/hsj2",
479 | hsl = "application/vnd.hsl",
480 | hta = "application/hta",
481 | htc = "text/x-component",
482 | htke = "application/vnd.kenameaapp",
483 | htm = "text/html",
484 | html = "text/html",
485 | hvd = "application/vnd.yamaha.hv-dic",
486 | hvp = "application/vnd.yamaha.hv-voice",
487 | hvs = "application/vnd.yamaha.hv-script",
488 | hwp = "application/x-hwp",
489 | hxx = "text/x-c++hdr",
490 | i2g = "application/vnd.intergeo",
491 | ic0 = "application/vnd.commerce-battelle",
492 | ic1 = "application/vnd.commerce-battelle",
493 | ic2 = "application/vnd.commerce-battelle",
494 | ic3 = "application/vnd.commerce-battelle",
495 | ic4 = "application/vnd.commerce-battelle",
496 | ic5 = "application/vnd.commerce-battelle",
497 | ic6 = "application/vnd.commerce-battelle",
498 | ic7 = "application/vnd.commerce-battelle",
499 | ic8 = "application/vnd.commerce-battelle",
500 | ica = "application/x-ica",
501 | icc = "application/vnd.iccprofile",
502 | icd = "application/vnd.commerce-battelle",
503 | icf = "application/vnd.commerce-battelle",
504 | icm = "application/vnd.iccprofile",
505 | ico = "image/vnd.microsoft.icon",
506 | ics = "text/calendar",
507 | ief = "image/ief",
508 | ifb = "text/calendar",
509 | ifc = "application/p21",
510 | ifm = "application/vnd.shana.informed.formdata",
511 | iges = "model/iges",
512 | igl = "application/vnd.igloader",
513 | igm = "application/vnd.insors.igm",
514 | ign = "application/vnd.coreos.ignition+json",
515 | ignition = "application/vnd.coreos.ignition+json",
516 | igs = "model/iges",
517 | igx = "application/vnd.micrografx.igx",
518 | iif = "application/vnd.shana.informed.interchange",
519 | iii = "application/x-iphone",
520 | imf = "application/vnd.imagemeter.folder+zip",
521 | imgcal = "application/vnd.3lightssoftware.imagescal",
522 | imi = "application/vnd.imagemeter.image+zip",
523 | imp = "application/vnd.accpac.simply.imp",
524 | ims = "application/vnd.ms-ims",
525 | imscc = "application/vnd.ims.imsccv1p1",
526 | info = "application/x-info",
527 | ink = "application/inkml+xml",
528 | inkml = "application/inkml+xml",
529 | inp = "chemical/x-gamess-input",
530 | ins = "application/x-internet-signup",
531 | iota = "application/vnd.astraea-software.iota",
532 | ipfix = "application/ipfix",
533 | ipk = "application/vnd.shana.informed.package",
534 | `ipns-record` = "application/vnd.ipfs.ipns-record",
535 | irm = "application/vnd.ibm.rights-management",
536 | irp = "application/vnd.irepository.package+xml",
537 | ism = "model/vnd.gdl",
538 | iso = "application/x-iso9660-image",
539 | isp = "application/x-internet-signup",
540 | ist = "chemical/x-isostar",
541 | istc = "application/vnd.veryant.thin",
542 | istr = "chemical/x-isostar",
543 | isws = "application/vnd.veryant.thin",
544 | itp = "application/vnd.shana.informed.formtemplate",
545 | its = "application/its+xml",
546 | ivp = "application/vnd.immervision-ivp",
547 | ivu = "application/vnd.immervision-ivu",
548 | j2c = "image/j2c",
549 | J2C = "image/j2c",
550 | j2k = "image/j2c",
551 | J2K = "image/j2c",
552 | jad = "text/vnd.sun.j2me.app-descriptor",
553 | jam = "application/vnd.jam",
554 | jar = "application/java-archive",
555 | java = "text/x-java",
556 | jdx = "chemical/x-jcamp-dx",
557 | jpeg = "image/jpeg",
558 | jhc = "image/jphc",
559 | jisp = "application/vnd.jisp",
560 | jls = "image/jls",
561 | jlt = "application/vnd.hp-jlyt",
562 | jmz = "application/x-jmol",
563 | jng = "image/x-jng",
564 | jnlp = "application/x-java-jnlp-file",
565 | joda = "application/vnd.joost.joda-archive",
566 | jp2 = "image/jp2",
567 | jpg = "image/jpeg",
568 | jpe = "image/jpeg",
569 | jpf = "image/jpx",
570 | jfif = "image/jpeg",
571 | jpg2 = "image/jp2",
572 | jpgm = "image/jpm",
573 | jph = "image/jph",
574 | jphc = "image/jphc",
575 | jpm = "image/jpm",
576 | jpx = "image/jpx",
577 | jrd = "application/jrd+json",
578 | js = "text/javascript",
579 | json = "application/json",
580 | `json-patch` = "application/json-patch+json",
581 | jsonld = "application/ld+json",
582 | jsontd = "application/td+json",
583 | jsontm = "application/tm+json",
584 | jt = "model/JT",
585 | jtd = "text/vnd.esmertec.theme-descriptor",
586 | jxl = "image/jxl",
587 | jxr = "image/jxr",
588 | jxra = "image/jxrA",
589 | jxrs = "image/jxrS",
590 | jxs = "image/jxs",
591 | jxsc = "image/jxsc",
592 | jxsi = "image/jxsi",
593 | jxss = "image/jxss",
594 | karbon = "application/vnd.kde.karbon",
595 | kcm = "application/vnd.nervana",
596 | key = "application/pgp-keys",
597 | keynote = "application/vnd.apple.keynote",
598 | kfo = "application/vnd.kde.kformula",
599 | kia = "application/vnd.kidspiration",
600 | kil = "application/x-killustrator",
601 | kin = "chemical/x-kinemage",
602 | kml = "application/vnd.google-earth.kml+xml",
603 | kmz = "application/vnd.google-earth.kmz",
604 | kne = "application/vnd.Kinar",
605 | knp = "application/vnd.Kinar",
606 | kom = "application/vnd.hbci",
607 | kon = "application/vnd.kde.kontour",
608 | koz = "audio/vnd.audiokoz",
609 | kpr = "application/vnd.kde.kpresenter",
610 | kpt = "application/vnd.kde.kpresenter",
611 | ksp = "application/vnd.kde.kspread",
612 | ktr = "application/vnd.kahootz",
613 | ktx = "image/ktx",
614 | ktx2 = "image/ktx2",
615 | ktz = "application/vnd.kahootz",
616 | kwd = "application/vnd.kde.kword",
617 | kwt = "application/vnd.kde.kword",
618 | l16 = "audio/L16",
619 | las = "application/vnd.las",
620 | lasjson = "application/vnd.las.las+json",
621 | lasxml = "application/vnd.las.las+xml",
622 | latex = "application/x-latex",
623 | lbc = "audio/iLBC",
624 | lbd = "application/vnd.llamagraphics.life-balance.desktop",
625 | lbe = "application/vnd.llamagraphics.life-balance.exchange+xml",
626 | lca = "application/vnd.logipipe.circuit+zip",
627 | lcs = "application/vnd.logipipe.circuit+zip",
628 | le = "application/vnd.bluetooth.le.oob",
629 | les = "application/vnd.hhe.lesson-player",
630 | lgr = "application/lgr+xml",
631 | lha = "application/x-lha",
632 | lhs = "text/x-literate-haskell",
633 | lhzd = "application/vnd.belightsoft.lhzd+zip",
634 | lhzl = "application/vnd.belightsoft.lhzl+zip",
635 | lin = "application/bbolin",
636 | line = "application/vnd.nebumind.line",
637 | link66 = "application/vnd.route66.link66+xml",
638 | list3820 = "application/vnd.afpc.modca",
639 | listafp = "application/vnd.afpc.modca",
640 | lmp = "model/vnd.gdl",
641 | loas = "audio/usac",
642 | loom = "application/vnd.loom",
643 | lostsyncxml = "application/lostsync+xml",
644 | lostxml = "application/lost+xml",
645 | lpf = "application/lpf+zip",
646 | lrm = "application/vnd.ms-lrm",
647 | lsf = "video/x-la-asf",
648 | lsx = "video/x-la-asf",
649 | ltx = "text/x-tex",
650 | lvp = "audio/vnd.lucent.voice",
651 | lwp = "application/vnd.lotus-wordpro",
652 | lxf = "application/LXF",
653 | ly = "text/x-lilypond",
654 | lyx = "application/x-lyx",
655 | lzh = "application/x-lzh",
656 | lzx = "application/x-lzx",
657 | m = "application/vnd.wolfram.mathematica.package",
658 | m1v = "video/mpeg",
659 | m21 = "application/mp21",
660 | m2v = "video/mpeg",
661 | m3g = "application/m3g",
662 | m3u = "audio/mpegurl",
663 | m3u8 = "application/vnd.apple.mpegurl",
664 | m4a = "audio/mp4",
665 | m4s = "video/iso.segment",
666 | m4u = "video/vnd.mpegurl",
667 | m4v = "video/mp4",
668 | ma = "application/mathematica",
669 | mads = "application/mads+xml",
670 | maei = "application/mmt-aei+xml",
671 | mag = "application/vnd.ecowin.chart",
672 | mail = "message/rfc822",
673 | maker = "application/x-maker",
674 | man = "application/x-troff-man",
675 | manifest = "text/cache-manifest",
676 | markdown = "text/markdown",
677 | mb = "application/mathematica",
678 | mbk = "application/vnd.Mobius.MBK",
679 | mbox = "application/mbox",
680 | mbsdf = "application/vnd.mdl-mbsdf",
681 | mc1 = "application/vnd.medcalcdata",
682 | mc2 = "text/vnd.senx.warpscript",
683 | mcd = "application/vnd.mcd",
684 | mcif = "chemical/x-mmcif",
685 | mcm = "chemical/x-macmolecule",
686 | md = "text/markdown",
687 | mdb = "application/msaccess",
688 | mdc = "application/vnd.marlin.drm.mdcf",
689 | mdi = "image/vnd.ms-modi",
690 | mdl = "application/vnd.mdl",
691 | me = "application/x-troff-me",
692 | mesh = "model/mesh",
693 | meta4 = "application/metalink4+xml",
694 | mets = "application/mets+xml",
695 | mf4 = "application/MF4",
696 | mfm = "application/vnd.mfmp",
697 | mft = "application/rpki-manifest",
698 | mgp = "application/vnd.osgeo.mapguide.package",
699 | mgz = "application/vnd.proteus.magazine",
700 | mhas = "audio/mhas",
701 | mid = "audio/sp-midi",
702 | mif = "application/vnd.mif",
703 | miz = "text/mizar",
704 | mj2 = "video/mj2",
705 | mjp2 = "video/mj2",
706 | mjs = "text/javascript",
707 | mkv = "video/x-matroska",
708 | ml2 = "application/vnd.sybyl.mol2",
709 | mlp = "audio/vnd.dolby.mlp",
710 | mm = "application/x-freemind",
711 | mmd = "application/vnd.chipnuts.karaoke-mmd",
712 | mmdb = "application/vnd.maxmind.maxmind-db",
713 | mmf = "application/vnd.smaf",
714 | mml = "application/mathml+xml",
715 | mmod = "chemical/x-macromodel-input",
716 | mmr = "image/vnd.fujixerox.edmics-mmr",
717 | mng = "video/x-mng",
718 | moc = "text/x-moc",
719 | mod = "application/xml-dtd",
720 | `model-inter` = "application/vnd.vd-study",
721 | modl = "application/vnd.modl",
722 | mods = "application/mods+xml",
723 | mol = "chemical/x-mdl-molfile",
724 | mol2 = "application/vnd.sybyl.mol2",
725 | moml = "model/vnd.moml+xml",
726 | moo = "chemical/x-mopac-out",
727 | mop = "chemical/x-mopac-input",
728 | mopcrt = "chemical/x-mopac-input",
729 | mov = "video/quicktime",
730 | movie = "video/x-sgi-movie",
731 | mp1 = "audio/mpeg",
732 | mp2 = "audio/mpeg",
733 | mp21 = "application/mp21",
734 | mp3 = "audio/mpeg",
735 | mp4 = "video/mp4",
736 | mpc = "application/vnd.mophun.certificate",
737 | mpd = "application/dash+xml",
738 | mpdd = "application/dashdelta",
739 | mpe = "video/mpeg",
740 | mpeg = "video/mpeg",
741 | mpega = "audio/mpeg",
742 | mpf = "text/vnd.ms-mediapackage",
743 | mpg = "video/mpeg",
744 | mpg4 = "video/mp4",
745 | mpga = "audio/mpeg",
746 | mph = "application/x-comsol",
747 | mpkg = "application/vnd.apple.installer+xml",
748 | mpm = "application/vnd.blueice.multipass",
749 | mpn = "application/vnd.mophun.application",
750 | mpp = "application/vnd.ms-project",
751 | mpt = "application/vnd.ms-project",
752 | mpv = "video/x-matroska",
753 | mpw = "application/vnd.exstream-empower+zip",
754 | mpy = "application/vnd.ibm.MiniPay",
755 | mqy = "application/vnd.Mobius.MQY",
756 | mrc = "application/marc",
757 | mrcx = "application/marcxml+xml",
758 | ms = "application/x-troff-ms",
759 | msa = "application/vnd.msa-disk-image",
760 | msd = "application/vnd.fdsn.mseed",
761 | mseed = "application/vnd.fdsn.mseed",
762 | mseq = "application/vnd.mseq",
763 | msf = "application/vnd.epson.msf",
764 | msh = "model/mesh",
765 | msi = "application/x-msi",
766 | msl = "application/vnd.Mobius.MSL",
767 | msm = "model/vnd.gdl",
768 | msp = "application/octet-stream",
769 | msty = "application/vnd.muvee.style",
770 | msu = "application/octet-stream",
771 | mtl = "model/mtl",
772 | mts = "model/vnd.mts",
773 | multitrack = "audio/vnd.presonus.multitrack",
774 | mus = "application/vnd.musician",
775 | musd = "application/mmt-usd+xml",
776 | mvb = "chemical/x-mopac-vib",
777 | mvt = "application/vnd.mapbox-vector-tile",
778 | mwc = "application/vnd.dpgraph",
779 | mwf = "application/vnd.MFER",
780 | mxf = "application/mxf",
781 | mxi = "application/vnd.vd-study",
782 | mxl = "application/vnd.recordare.musicxml",
783 | mxmf = "audio/mobile-xmf",
784 | mxml = "application/xv+xml",
785 | mxs = "application/vnd.triscape.mxs",
786 | mxu = "video/vnd.mpegurl",
787 | n3 = "text/n3",
788 | nb = "application/vnd.wolfram.mathematica",
789 | nbp = "application/vnd.wolfram.player",
790 | nc = "application/x-netcdf",
791 | ndc = "application/vnd.osa.netdeploy",
792 | ndl = "application/vnd.lotus-notes",
793 | nds = "application/vnd.nintendo.nitro.rom",
794 | nebul = "application/vnd.nebumind.line",
795 | nef = "image/x-nikon-nef",
796 | ngdat = "application/vnd.nokia.n-gage.data",
797 | nim = "video/vnd.nokia.interleaved-multimedia",
798 | nimn = "application/vnd.nimn",
799 | nitf = "application/vnd.nitf",
800 | nlu = "application/vnd.neurolanguage.nlu",
801 | nml = "application/vnd.enliven",
802 | nnd = "application/vnd.noblenet-directory",
803 | nns = "application/vnd.noblenet-sealer",
804 | nnw = "application/vnd.noblenet-web",
805 | notebook = "application/vnd.smart.notebook",
806 | nq = "application/n-quads",
807 | ns2 = "application/vnd.lotus-notes",
808 | ns3 = "application/vnd.lotus-notes",
809 | ns4 = "application/vnd.lotus-notes",
810 | nsf = "application/vnd.lotus-notes",
811 | nsg = "application/vnd.lotus-notes",
812 | nsh = "application/vnd.lotus-notes",
813 | nt = "application/n-triples",
814 | ntf = "application/vnd.lotus-notes",
815 | numbers = "application/vnd.apple.numbers",
816 | nwc = "application/x-nwc",
817 | o = "application/x-object",
818 | oa2 = "application/vnd.fujitsu.oasys2",
819 | oa3 = "application/vnd.fujitsu.oasys3",
820 | oas = "application/vnd.fujitsu.oasys",
821 | ob = "application/vnd.1ob",
822 | obg = "application/vnd.openblox.game-binary",
823 | obgx = "application/vnd.openblox.game+xml",
824 | obj = "model/obj",
825 | oda = "application/ODA",
826 | odb = "application/vnd.oasis.opendocument.base",
827 | odc = "application/vnd.oasis.opendocument.chart",
828 | odd = "application/tei+xml",
829 | odf = "application/vnd.oasis.opendocument.formula",
830 | odg = "application/vnd.oasis.opendocument.graphics",
831 | odi = "application/vnd.oasis.opendocument.image",
832 | odm = "application/vnd.oasis.opendocument.text-master",
833 | odp = "application/vnd.oasis.opendocument.presentation",
834 | ods = "application/vnd.oasis.opendocument.spreadsheet",
835 | odt = "application/vnd.oasis.opendocument.text",
836 | odx = "application/ODX",
837 | oeb = "application/vnd.openeye.oeb",
838 | oga = "audio/ogg",
839 | ogex = "model/vnd.opengex",
840 | ogg = "audio/ogg",
841 | ogv = "video/ogg",
842 | ogx = "application/ogg",
843 | old = "application/x-trash",
844 | omg = "audio/ATRAC3",
845 | one = "application/onenote",
846 | onepkg = "application/onenote",
847 | onetmp = "application/onenote",
848 | onetoc2 = "application/onenote",
849 | opf = "application/oebps-package+xml",
850 | oprc = "application/vnd.palm",
851 | opus = "audio/ogg",
852 | or2 = "application/vnd.lotus-organizer",
853 | or3 = "application/vnd.lotus-organizer",
854 | orc = "audio/csound",
855 | orf = "image/x-olympus-orf",
856 | org = "application/vnd.lotus-organizer",
857 | orq = "application/ocsp-request",
858 | ors = "application/ocsp-response",
859 | osf = "application/vnd.yamaha.openscoreformat",
860 | osm = "application/vnd.openstreetmap.data+xml",
861 | ota = "application/vnd.android.ota",
862 | otc = "application/vnd.oasis.opendocument.chart-template",
863 | otf = "font/otf",
864 | otg = "application/vnd.oasis.opendocument.graphics-template",
865 | oth = "application/vnd.oasis.opendocument.text-web",
866 | oti = "application/vnd.oasis.opendocument.image-template",
867 | otm = "application/vnd.oasis.opendocument.text-master-template",
868 | otp = "application/vnd.oasis.opendocument.presentation-template",
869 | ots = "application/vnd.oasis.opendocument.spreadsheet-template",
870 | ott = "application/vnd.oasis.opendocument.text-template",
871 | ovl = "application/vnd.afpc.modca-overlay",
872 | oxlicg = "application/vnd.oxli.countgraph",
873 | oxps = "application/oxps",
874 | oxt = "application/vnd.openofficeorg.extension",
875 | oza = "application/x-oz-application",
876 | p = "text/x-pascal",
877 | p10 = "application/pkcs10",
878 | p12 = "application/pkcs12",
879 | p21 = "application/p21",
880 | p2p = "application/vnd.wfa.p2p",
881 | p7c = "application/pkcs7-mime",
882 | p7m = "application/pkcs7-mime",
883 | p7r = "application/x-pkcs7-certreqresp",
884 | p7s = "application/pkcs7-signature",
885 | p7z = "application/pkcs7-mime",
886 | p8 = "application/pkcs8",
887 | p8e = "application/pkcs8-encrypted",
888 | pac = "application/x-ns-proxy-autoconfig",
889 | package = "application/vnd.autopackage",
890 | pages = "application/vnd.apple.pages",
891 | pas = "text/x-pascal",
892 | pat = "image/x-coreldrawpattern",
893 | patch = "text/x-diff",
894 | paw = "application/vnd.pawaafile",
895 | pbd = "application/vnd.powerbuilder6",
896 | pbm = "image/x-portable-bitmap",
897 | pcap = "application/vnd.tcpdump.pcap",
898 | pcf = "application/x-font-pcf",
899 | pcf.Z = "application/x-font-pcf",
900 | pcl = "application/vnd.hp-PCL",
901 | pcx = "image/vnd.zbrush.pcx",
902 | pdb = "application/vnd.palm",
903 | pdf = "application/pdf",
904 | pdx = "application/PDX",
905 | pem = "application/pem-certificate-chain",
906 | pfa = "application/x-font",
907 | pfb = "application/x-font",
908 | pfr = "application/font-tdpfr",
909 | pfx = "application/pkcs12",
910 | pgb = "image/vnd.globalgraphics.pgb",
911 | PGB = "image/vnd.globalgraphics.pgb",
912 | pgm = "image/x-portable-graymap",
913 | pgn = "application/vnd.chess-pgn",
914 | pgp = "application/pgp-encrypted",
915 | pil = "application/vnd.piaccess.application-licence",
916 | pk = "application/x-tex-pk",
917 | pkd = "application/vnd.hbci",
918 | pkg = "application/vnd.apple.installer+xml",
919 | pki = "application/pkixcmp",
920 | pkipath = "application/pkix-pkipath",
921 | pl = "text/x-perl",
922 | plb = "application/vnd.3gpp.pic-bw-large",
923 | plc = "application/vnd.Mobius.PLC",
924 | plf = "application/vnd.pocketlearn",
925 | plj = "audio/vnd.everad.plj",
926 | plp = "application/vnd.panoply",
927 | pls = "audio/x-scpls",
928 | pm = "text/x-perl",
929 | pml = "application/vnd.ctc-posml",
930 | png = "image/png",
931 | pnm = "image/x-portable-anymap",
932 | portpkg = "application/vnd.macports.portpkg",
933 | pot = "text/plain",
934 | potm = "application/vnd.ms-powerpoint.template.macroEnabled.12",
935 | potx = "application/vnd.openxmlformats-officedocument.presentationml.template",
936 | ppam = "application/vnd.ms-powerpoint.addin.macroEnabled.12",
937 | ppd = "application/vnd.cups-ppd",
938 | ppkg = "application/vnd.xmpie.ppkg",
939 | ppm = "image/x-portable-pixmap",
940 | pps = "application/vnd.ms-powerpoint",
941 | ppsm = "application/vnd.ms-powerpoint.slideshow.macroEnabled.12",
942 | ppsx = "application/vnd.openxmlformats-officedocument.presentationml.slideshow",
943 | ppt = "application/vnd.ms-powerpoint",
944 | pptm = "application/vnd.ms-powerpoint.presentation.macroEnabled.12",
945 | ppttc = "application/vnd.think-cell.ppttc+json",
946 | pptx = "application/vnd.openxmlformats-officedocument.presentationml.presentation",
947 | pqa = "application/vnd.palm",
948 | prc = "model/prc",
949 | pre = "application/vnd.lotus-freelance",
950 | preminet = "application/vnd.preminet",
951 | prf = "application/pics-rules",
952 | provn = "text/provenance-notation",
953 | provx = "application/provenance+xml",
954 | prt = "chemical/x-ncbi-asn1-ascii",
955 | prz = "application/vnd.lotus-freelance",
956 | ps = "application/postscript",
957 | psb = "application/vnd.3gpp.pic-bw-small",
958 | psd = "image/vnd.adobe.photoshop",
959 | pseg3820 = "application/vnd.afpc.modca",
960 | psfs = "application/vnd.psfs",
961 | psg = "application/vnd.afpc.modca-pagesegment",
962 | psid = "audio/prs.sid",
963 | pskcxml = "application/pskc+xml",
964 | pt = "application/vnd.snesdev-page-table",
965 | pti = "image/prs.pti",
966 | ptid = "application/vnd.pvi.ptid1",
967 | ptrom = "application/vnd.snesdev-page-table",
968 | pub = "application/vnd.exstream-package",
969 | pvb = "application/vnd.3gpp.pic-bw-var",
970 | pwn = "application/vnd.3M.Post-it-Notes",
971 | py = "text/x-python",
972 | pya = "audio/vnd.ms-playready.media.pya",
973 | pyc = "application/x-python-code",
974 | pyo = "application/x-python-code",
975 | pyox = "model/vnd.pytha.pyox",
976 | pyv = "video/vnd.ms-playready.media.pyv",
977 | qam = "application/vnd.epson.quickanime",
978 | qbo = "application/vnd.intu.qbo",
979 | qca = "application/vnd.ericsson.quickcall",
980 | qcall = "application/vnd.ericsson.quickcall",
981 | qcp = "audio/EVRC-QCP",
982 | QCP = "audio/EVRC-QCP",
983 | qfx = "application/vnd.intu.qfx",
984 | qgs = "application/x-qgis",
985 | qps = "application/vnd.publishare-delta-tree",
986 | qt = "video/quicktime",
987 | qtl = "application/x-quicktimeplayer",
988 | quiz = "application/vnd.quobject-quoxdocument",
989 | quox = "application/vnd.quobject-quoxdocument",
990 | qvd = "application/vnd.theqvd",
991 | qwd = "application/vnd.Quark.QuarkXPress",
992 | qwt = "application/vnd.Quark.QuarkXPress",
993 | qxb = "application/vnd.Quark.QuarkXPress",
994 | qxd = "application/vnd.Quark.QuarkXPress",
995 | qxl = "application/vnd.Quark.QuarkXPress",
996 | qxt = "application/vnd.Quark.QuarkXPress",
997 | ra = "audio/x-pn-realaudio",
998 | ram = "audio/x-pn-realaudio",
999 | rapd = "application/route-apd+xml",
1000 | rar = "application/vnd.rar",
1001 | ras = "image/x-cmu-raster",
1002 | rb = "application/x-ruby",
1003 | rcprofile = "application/vnd.ipunplugged.rcprofile",
1004 | rct = "application/prs.nprend",
1005 | rd = "chemical/x-mdl-rdfile",
1006 | rdf = "application/rdf+xml",
1007 | `rdf-crypt` = "application/prs.rdf-xml-crypt",
1008 | rdp = "application/x-rdp",
1009 | rdz = "application/vnd.data-vision.rdz",
1010 | relo = "application/p2p-overlay+xml",
1011 | reload = "application/vnd.resilient.logic",
1012 | rep = "application/vnd.businessobjects",
1013 | request = "application/vnd.nervana",
1014 | rfcxml = "application/rfc+xml",
1015 | rgb = "image/x-rgb",
1016 | rgbe = "image/vnd.radiance",
1017 | rif = "application/reginfo+xml",
1018 | rip = "audio/vnd.rip",
1019 | rl = "application/resource-lists+xml",
1020 | rlc = "image/vnd.fujixerox.edmics-rlc",
1021 | rld = "application/resource-lists-diff+xml",
1022 | rlm = "application/vnd.resilient.logic",
1023 | rm = "audio/x-pn-realaudio",
1024 | rms = "application/vnd.jcp.javame.midlet-rms",
1025 | rnc = "application/relax-ng-compact-syntax",
1026 | rnd = "application/prs.nprend",
1027 | roa = "application/rpki-roa",
1028 | roff = "text/troff",
1029 | ros = "chemical/x-rosdal",
1030 | rp9 = "application/vnd.cloanto.rp9",
1031 | rpm = "application/x-redhat-package-manager",
1032 | rpss = "application/vnd.nokia.radio-presets",
1033 | rpst = "application/vnd.nokia.radio-preset",
1034 | rq = "application/sparql-query",
1035 | rs = "application/rls-services+xml",
1036 | rsat = "application/atsc-rsat+xml",
1037 | rsheet = "application/urc-ressheet+xml",
1038 | rsm = "model/vnd.gdl",
1039 | rss = "application/x-rss+xml",
1040 | rst = "text/prs.fallenstein.rst",
1041 | rtf = "application/rtf",
1042 | rusd = "application/route-usd+xml",
1043 | rxn = "chemical/x-mdl-rxnfile",
1044 | rxt = "application/vnd.medicalholodeck.recordxr",
1045 | s11 = "video/vnd.sealed.mpeg1",
1046 | s14 = "video/vnd.sealed.mpeg4",
1047 | s1a = "application/vnd.sealedmedia.softseal.pdf",
1048 | s1e = "application/vnd.sealed.xls",
1049 | s1g = "image/vnd.sealedmedia.softseal.gif",
1050 | s1h = "application/vnd.sealedmedia.softseal.html",
1051 | s1j = "image/vnd.sealedmedia.softseal.jpg",
1052 | s1m = "audio/vnd.sealedmedia.softseal.mpeg",
1053 | s1n = "image/vnd.sealed.png",
1054 | s1p = "application/vnd.sealed.ppt",
1055 | s1q = "video/vnd.sealedmedia.softseal.mov",
1056 | s1w = "application/vnd.sealed.doc",
1057 | s3df = "application/vnd.sealed.3df",
1058 | sac = "application/tamp-sequence-adjust-confirm",
1059 | saf = "application/vnd.yamaha.smaf-audio",
1060 | sam = "application/vnd.lotus-wordpro",
1061 | SAR = "application/vnd.sar",
1062 | sarif = "application/sarif+json",
1063 | `sarif-external-properties` = "application/sarif-external-properties+json",
1064 | `sarif-external-properties.json` = "application/sarif-external-properties+json",
1065 | sarif.json = "application/sarif+json",
1066 | sc = "application/vnd.ibm.secure-container",
1067 | scala = "text/x-scala",
1068 | scd = "application/vnd.scribus",
1069 | sce = "application/vnd.etsi.asic-e+zip",
1070 | sci = "application/x-scilab",
1071 | scim = "application/scim+json",
1072 | scl = "application/vnd.sycle+xml",
1073 | scld = "application/vnd.doremir.scorecloud-binary-document",
1074 | scm = "application/vnd.lotus-screencam",
1075 | sco = "audio/csound",
1076 | scq = "application/scvp-cv-request",
1077 | scr = "application/x-silverlight",
1078 | scs = "application/scvp-cv-response",
1079 | scsf = "application/vnd.sealed.csf",
1080 | sd = "chemical/x-mdl-sdfile",
1081 | sd2 = "audio/x-sd2",
1082 | sda = "application/vnd.stardivision.draw",
1083 | sdc = "application/vnd.stardivision.calc",
1084 | sdd = "application/vnd.stardivision.impress",
1085 | sdf = "application/vnd.Kinar",
1086 | sdkd = "application/vnd.solent.sdkm+xml",
1087 | sdkm = "application/vnd.solent.sdkm+xml",
1088 | sdo = "application/vnd.sealed.doc",
1089 | sdoc = "application/vnd.sealed.doc",
1090 | sdp = "application/sdp",
1091 | sds = "application/vnd.stardivision.chart",
1092 | sdw = "application/vnd.stardivision.writer",
1093 | see = "application/vnd.seemail",
1094 | seed = "application/vnd.fdsn.seed",
1095 | sem = "application/vnd.sealed.eml",
1096 | sema = "application/vnd.sema",
1097 | semd = "application/vnd.semd",
1098 | semf = "application/vnd.semf",
1099 | seml = "application/vnd.sealed.eml",
1100 | senml = "application/senml+json",
1101 | `senml-etchc` = "application/senml-etch+cbor",
1102 | `senml-etchj` = "application/senml-etch+json",
1103 | senmlc = "application/senml+cbor",
1104 | senmle = "application/senml-exi",
1105 | senmlx = "application/senml+xml",
1106 | sensml = "application/sensml+json",
1107 | sensmlc = "application/sensml+cbor",
1108 | sensmle = "application/sensml-exi",
1109 | sensmlx = "application/sensml+xml",
1110 | ser = "application/java-serialized-object",
1111 | sfc = "application/vnd.nintendo.snes.rom",
1112 | sfd = "application/vnd.font-fontforge-sfd",
1113 | `sfd-hdstx` = "application/vnd.hydrostatix.sof-data",
1114 | sfs = "application/vnd.spotfire.sfs",
1115 | sfv = "text/x-sfv",
1116 | sgf = "application/x-go-sgf",
1117 | sgi = "image/vnd.sealedmedia.softseal.gif",
1118 | sgif = "image/vnd.sealedmedia.softseal.gif",
1119 | sgl = "application/vnd.stardivision.writer-global",
1120 | sgm = "text/SGML",
1121 | sgml = "text/SGML",
1122 | sh = "application/x-sh",
1123 | shaclc = "text/shaclc",
1124 | shar = "application/x-shar",
1125 | shc = "text/shaclc",
1126 | shex = "text/shex",
1127 | shf = "application/shf+xml",
1128 | shp = "application/vnd.shp",
1129 | shtml = "text/html",
1130 | shx = "application/vnd.shx",
1131 | si = "text/vnd.wap.si",
1132 | sic = "application/vnd.wap.sic",
1133 | sid = "audio/prs.sid",
1134 | sieve = "application/sieve",
1135 | sig = "application/pgp-signature",
1136 | sik = "application/x-trash",
1137 | silo = "model/mesh",
1138 | sipa = "application/vnd.smintio.portals.archive",
1139 | sis = "application/vnd.symbian.install",
1140 | sit = "application/x-stuffit",
1141 | sitx = "application/x-stuffit",
1142 | siv = "application/sieve",
1143 | sjp = "image/vnd.sealedmedia.softseal.jpg",
1144 | sjpg = "image/vnd.sealedmedia.softseal.jpg",
1145 | skd = "application/vnd.koan",
1146 | skm = "application/vnd.koan",
1147 | skp = "application/vnd.koan",
1148 | skt = "application/vnd.koan",
1149 | sl = "text/vnd.wap.sl",
1150 | sla = "application/vnd.scribus",
1151 | slaz = "application/vnd.scribus",
1152 | slc = "application/vnd.wap.slc",
1153 | sldm = "application/vnd.ms-powerpoint.slide.macroEnabled.12",
1154 | sldx = "application/vnd.openxmlformats-officedocument.presentationml.slide",
1155 | sls = "application/route-s-tsid+xml",
1156 | slt = "application/vnd.epson.salt",
1157 | sm = "application/vnd.stepmania.stepchart",
1158 | smc = "application/vnd.nintendo.snes.rom",
1159 | smf = "application/vnd.stardivision.math",
1160 | smh = "application/vnd.sealed.mht",
1161 | smht = "application/vnd.sealed.mht",
1162 | smi = "application/smil+xml",
1163 | smil = "application/smil+xml",
1164 | smk = "video/vnd.radgamettools.smacker",
1165 | sml = "application/smil+xml",
1166 | smo = "video/vnd.sealedmedia.softseal.mov",
1167 | smov = "video/vnd.sealedmedia.softseal.mov",
1168 | smp = "audio/vnd.sealedmedia.softseal.mpeg",
1169 | smp3 = "audio/vnd.sealedmedia.softseal.mpeg",
1170 | smpg = "video/vnd.sealed.mpeg1",
1171 | sms = "application/vnd.3gpp2.sms",
1172 | smv = "audio/SMV",
1173 | smzip = "application/vnd.stepmania.package",
1174 | snd = "audio/basic",
1175 | soa = "text/dns",
1176 | soc = "application/sgml-open-catalog",
1177 | sofa = "audio/sofa",
1178 | sos = "text/vnd.sosi",
1179 | spc = "chemical/x-galactic-spc",
1180 | spd = "application/vnd.sealedmedia.softseal.pdf",
1181 | spdf = "application/vnd.sealedmedia.softseal.pdf",
1182 | spdx = "text/spdx",
1183 | spdx.json = "application/spdx+json",
1184 | spf = "application/vnd.yamaha.smaf-phrase",
1185 | spl = "application/futuresplash",
1186 | spn = "image/vnd.sealed.png",
1187 | spng = "image/vnd.sealed.png",
1188 | spo = "text/vnd.in3d.spot",
1189 | spot = "text/vnd.in3d.spot",
1190 | spp = "application/scvp-vp-response",
1191 | sppt = "application/vnd.sealed.ppt",
1192 | spq = "application/scvp-vp-request",
1193 | spx = "audio/ogg",
1194 | sql = "application/sql",
1195 | sqlite = "application/vnd.sqlite3",
1196 | sqlite3 = "application/vnd.sqlite3",
1197 | sr = "application/vnd.sigrok.session",
1198 | src = "application/x-wais-source",
1199 | srt = "text/plain",
1200 | sru = "application/sru+xml",
1201 | srx = "application/sparql-results+xml",
1202 | sse = "application/vnd.kodak-descriptor",
1203 | ssf = "application/vnd.epson.ssf",
1204 | ssml = "application/ssml+xml",
1205 | ssv = "application/vnd.shade-save-file",
1206 | ssvc = "application/vnd.crypto-shade-file",
1207 | ssw = "video/vnd.sealed.swf",
1208 | sswf = "video/vnd.sealed.swf",
1209 | st = "application/vnd.sailingtracker.track",
1210 | stc = "application/vnd.sun.xml.calc.template",
1211 | std = "application/vnd.sun.xml.draw.template",
1212 | step = "model/step",
1213 | stf = "application/vnd.wt.stf",
1214 | sti = "application/vnd.sun.xml.impress.template",
1215 | stif = "application/vnd.sealed.tiff",
1216 | stix = "application/stix+json",
1217 | stk = "application/hyperstudio",
1218 | stl = "model/stl",
1219 | stml = "application/vnd.sealedmedia.softseal.html",
1220 | stp = "model/step",
1221 | stpnc = "application/p21",
1222 | stpx = "model/step+xml",
1223 | stpxz = "model/step-xml+zip",
1224 | stpz = "model/step+zip",
1225 | str = "application/vnd.pg.format",
1226 | `study-inter` = "application/vnd.vd-study",
1227 | stw = "application/vnd.sun.xml.writer.template",
1228 | sty = "text/x-tex",
1229 | sus = "application/vnd.sus-calendar",
1230 | susp = "application/vnd.sus-calendar",
1231 | sv4cpio = "application/x-sv4cpio",
1232 | sv4crc = "application/x-sv4crc",
1233 | svc = "application/vnd.dvb.service",
1234 | svg = "image/svg+xml",
1235 | svgz = "image/svg+xml",
1236 | sw = "chemical/x-swissprot",
1237 | swf = "application/vnd.adobe.flash.movie",
1238 | swi = "application/vnd.aristanetworks.swi",
1239 | swidtag = "application/swid+xml",
1240 | sxc = "application/vnd.sun.xml.calc",
1241 | sxd = "application/vnd.sun.xml.draw",
1242 | sxg = "application/vnd.sun.xml.writer.global",
1243 | sxi = "application/vnd.sun.xml.impress",
1244 | sxl = "application/vnd.sealed.xls",
1245 | sxls = "application/vnd.sealed.xls",
1246 | sxm = "application/vnd.sun.xml.math",
1247 | sxw = "application/vnd.sun.xml.writer",
1248 | sy2 = "application/vnd.sybyl.mol2",
1249 | syft.json = "application/vnd.syft+json",
1250 | t = "text/troff",
1251 | tag = "text/prs.lines.tag",
1252 | taglet = "application/vnd.mynfc",
1253 | tam = "application/vnd.onepager",
1254 | tamp = "application/vnd.onepagertamp",
1255 | tamx = "application/vnd.onepagertamx",
1256 | tao = "application/vnd.tao.intent-module-archive",
1257 | tap = "image/vnd.tencent.tap",
1258 | tar = "application/x-tar",
1259 | tat = "application/vnd.onepagertat",
1260 | tatp = "application/vnd.onepagertatp",
1261 | tatx = "application/vnd.onepagertatx",
1262 | tau = "application/tamp-apex-update",
1263 | taz = "application/x-gtar-compressed",
1264 | tcap = "application/vnd.3gpp2.tcap",
1265 | tcl = "application/x-tcl",
1266 | tcu = "application/tamp-community-update",
1267 | td = "application/urc-targetdesc+xml",
1268 | teacher = "application/vnd.smart.teacher",
1269 | tei = "application/tei+xml",
1270 | teiCorpus = "application/tei+xml",
1271 | ter = "application/tamp-error",
1272 | tex = "text/x-tex",
1273 | texi = "application/x-texinfo",
1274 | texinfo = "application/x-texinfo",
1275 | text = "text/plain",
1276 | tfi = "application/thraud+xml",
1277 | tfx = "image/tiff-fx",
1278 | tgf = "chemical/x-mdl-tgf",
1279 | tgz = "application/x-gtar-compressed",
1280 | thmx = "application/vnd.ms-officetheme",
1281 | tif = "image/tiff",
1282 | tiff = "image/tiff",
1283 | tk = "text/x-tcl",
1284 | tlclient = "application/vnd.cendio.thinlinc.clientconf",
1285 | tm = "text/texmacs",
1286 | tm.json = "application/tm+json",
1287 | tm.jsonld = "application/tm+json",
1288 | tmo = "application/vnd.tmobile-livetv",
1289 | tnef = "application/vnd.ms-tnef",
1290 | tnf = "application/vnd.ms-tnef",
1291 | torrent = "application/x-bittorrent",
1292 | tpl = "application/vnd.groove-tool-template",
1293 | tpt = "application/vnd.trid.tpt",
1294 | tr = "text/troff",
1295 | tra = "application/vnd.trueapp",
1296 | tree = "application/vnd.rainstor.data",
1297 | trig = "application/trig",
1298 | ts = "text/vnd.trolltech.linguist",
1299 | tsa = "application/tamp-sequence-adjust",
1300 | tsd = "application/timestamped-data",
1301 | tsp = "application/dsptype",
1302 | tsq = "application/timestamp-query",
1303 | tsr = "application/timestamp-reply",
1304 | tst = "application/vnd.etsi.timestamp-token",
1305 | tsv = "text/tab-separated-values",
1306 | ttc = "font/collection",
1307 | ttf = "font/ttf",
1308 | ttl = "text/turtle",
1309 | ttml = "application/ttml+xml",
1310 | tuc = "application/tamp-update-confirm",
1311 | tur = "application/tamp-update",
1312 | twd = "application/vnd.SimTech-MindMapper",
1313 | twds = "application/vnd.SimTech-MindMapper",
1314 | txd = "application/vnd.genomatix.tuxedo",
1315 | txf = "application/vnd.Mobius.TXF",
1316 | txt = "text/plain",
1317 | u3d = "model/u3d",
1318 | u8dsn = "message/global-delivery-status",
1319 | u8hdr = "message/global-headers",
1320 | u8mdn = "message/global-disposition-notification",
1321 | u8msg = "message/global",
1322 | udeb = "application/vnd.debian.binary-package",
1323 | ufd = "application/vnd.ufdl",
1324 | ufdl = "application/vnd.ufdl",
1325 | uis = "application/urc-uisocketdesc+xml",
1326 | umj = "application/vnd.umajin",
1327 | unityweb = "application/vnd.unity",
1328 | uo = "application/vnd.uoml+xml",
1329 | uoml = "application/vnd.uoml+xml",
1330 | upa = "application/vnd.hbci",
1331 | uri = "text/uri-list",
1332 | urim = "application/vnd.uri-map",
1333 | urimap = "application/vnd.uri-map",
1334 | uris = "text/uri-list",
1335 | usda = "model/vnd.usda",
1336 | usdz = "model/vnd.usdz+zip",
1337 | ustar = "application/x-ustar",
1338 | utz = "application/vnd.uiq.theme",
1339 | uva = "audio/vnd.dece.audio",
1340 | uvd = "application/vnd.dece.data",
1341 | uvf = "application/vnd.dece.data",
1342 | uvg = "image/vnd.dece.graphic",
1343 | uvh = "video/vnd.dece.hd",
1344 | uvi = "image/vnd.dece.graphic",
1345 | uvm = "video/vnd.dece.mobile",
1346 | uvp = "video/vnd.dece.pd",
1347 | uvs = "video/vnd.dece.sd",
1348 | uvt = "application/vnd.dece.ttml+xml",
1349 | uvu = "video/vnd.dece.mp4",
1350 | uvv = "video/vnd.dece.video",
1351 | uvva = "audio/vnd.dece.audio",
1352 | uvvd = "application/vnd.dece.data",
1353 | uvvf = "application/vnd.dece.data",
1354 | uvvg = "image/vnd.dece.graphic",
1355 | uvvh = "video/vnd.dece.hd",
1356 | uvvi = "image/vnd.dece.graphic",
1357 | uvvm = "video/vnd.dece.mobile",
1358 | uvvp = "video/vnd.dece.pd",
1359 | uvvs = "video/vnd.dece.sd",
1360 | uvvt = "application/vnd.dece.ttml+xml",
1361 | uvvu = "video/vnd.dece.mp4",
1362 | uvvv = "video/vnd.dece.video",
1363 | uvvx = "application/vnd.dece.unspecified",
1364 | uvvz = "application/vnd.dece.zip",
1365 | uvx = "application/vnd.dece.unspecified",
1366 | uvz = "application/vnd.dece.zip",
1367 | val = "chemical/x-ncbi-asn1-binary",
1368 | vbk = "audio/vnd.nortel.vbk",
1369 | vbox = "application/vnd.previewsystems.box",
1370 | vcard = "text/vcard",
1371 | vcd = "application/x-cdlink",
1372 | vcf = "text/vcard",
1373 | vcg = "application/vnd.groove-vcard",
1374 | vcj = "application/voucher-cms+json",
1375 | vcs = "text/x-vcalendar",
1376 | vcx = "application/vnd.vcx",
1377 | vds = "model/vnd.sap.vds",
1378 | VES = "application/vnd.ves.encrypted",
1379 | vew = "application/vnd.lotus-approach",
1380 | VFK = "text/vnd.exchangeable",
1381 | vfr = "application/vnd.tml",
1382 | viaframe = "application/vnd.tml",
1383 | vis = "application/vnd.visionary",
1384 | viv = "video/vnd.vivo",
1385 | vmd = "chemical/x-vmd",
1386 | vms = "chemical/x-vamas-iso14976",
1387 | vmt = "application/vnd.valve.source.material",
1388 | vpm = "multipart/voice-message",
1389 | vrm = "model/vrml",
1390 | vrml = "model/vrml",
1391 | vsc = "application/vnd.vidsoft.vidconference",
1392 | vsd = "application/vnd.visio",
1393 | vsf = "application/vnd.vsf",
1394 | vss = "application/vnd.visio",
1395 | vst = "application/vnd.visio",
1396 | vsw = "application/vnd.visio",
1397 | vtf = "image/vnd.valve.source.texture",
1398 | vtnstd = "application/vnd.veritone.aion+json",
1399 | vtt = "text/vtt",
1400 | vtu = "model/vnd.vtu",
1401 | vwx = "application/vnd.vectorworks",
1402 | vxml = "application/voicexml+xml",
1403 | wad = "application/x-doom",
1404 | wadl = "application/vnd.sun.wadl+xml",
1405 | wafl = "application/vnd.wasmflow.wafl",
1406 | wasm = "application/wasm",
1407 | wav = "audio/x-wav",
1408 | wax = "audio/x-ms-wax",
1409 | wbmp = "image/vnd.wap.wbmp",
1410 | wbs = "application/vnd.criticaltools.wbs+xml",
1411 | wbxml = "application/vnd.wap.wbxml",
1412 | wcm = "application/vnd.ms-works",
1413 | wdb = "application/vnd.ms-works",
1414 | webm = "video/webm",
1415 | webmanifest = "application/manifest+json",
1416 | webp = "image/webp",
1417 | wg = "application/vnd.pmi.widget",
1418 | wgsl = "text/wgsl",
1419 | wgt = "application/widget",
1420 | wif = "application/watcherinfo+xml",
1421 | win = "model/vnd.gdl",
1422 | wk = "application/x-123",
1423 | wk1 = "application/vnd.lotus-1-2-3",
1424 | wk3 = "application/vnd.lotus-1-2-3",
1425 | wk4 = "application/vnd.lotus-1-2-3",
1426 | wks = "application/vnd.ms-works",
1427 | wlnk = "application/link-format",
1428 | wm = "video/x-ms-wm",
1429 | wma = "audio/x-ms-wma",
1430 | wmc = "application/vnd.wmc",
1431 | wmd = "application/x-ms-wmd",
1432 | wmf = "image/wmf",
1433 | wml = "text/vnd.wap.wml",
1434 | wmlc = "application/vnd.wap.wmlc",
1435 | wmls = "text/vnd.wap.wmlscript",
1436 | wmlsc = "application/vnd.wap.wmlscriptc",
1437 | wmv = "video/x-ms-wmv",
1438 | wmx = "video/x-ms-wmx",
1439 | wmz = "application/x-ms-wmz",
1440 | woff = "font/woff",
1441 | woff2 = "font/woff2",
1442 | wpd = "application/vnd.wordperfect",
1443 | wpl = "application/vnd.ms-wpl",
1444 | wps = "application/vnd.ms-works",
1445 | wqd = "application/vnd.wqd",
1446 | wrl = "model/vrml",
1447 | wsc = "application/vnd.wfa.wsc",
1448 | wsdl = "application/wsdl+xml",
1449 | wspolicy = "application/wspolicy+xml",
1450 | wtb = "application/vnd.webturbo",
1451 | wv = "application/vnd.wv.csp+wbxml",
1452 | wvx = "video/x-ms-wvx",
1453 | wz = "application/x-wingz",
1454 | x_b = "model/vnd.parasolid.transmit.binary",
1455 | x_t = "model/vnd.parasolid.transmit.text",
1456 | x3d = "model/x3d+xml",
1457 | x3db = "model/x3d+fastinfoset",
1458 | x3dv = "model/x3d-vrml",
1459 | x3dvz = "model/x3d-vrml",
1460 | x3dz = "model/x3d+xml",
1461 | xar = "application/vnd.xara",
1462 | xav = "application/xcap-att+xml",
1463 | xbd = "application/vnd.fujixerox.docuworks.binder",
1464 | xbm = "image/x-xbitmap",
1465 | xca = "application/xcap-caps+xml",
1466 | xcf = "image/x-xcf",
1467 | xcos = "application/x-scilab-xcos",
1468 | xcs = "application/calendar+xml",
1469 | xct = "application/vnd.fujixerox.docuworks.container",
1470 | xdd = "application/bacnet-xdd+zip",
1471 | xdf = "application/xcap-diff+xml",
1472 | xdm = "application/vnd.syncml.dm+xml",
1473 | xdp = "application/vnd.adobe.xdp+xml",
1474 | xdssc = "application/dssc+xml",
1475 | xdw = "application/vnd.fujixerox.docuworks",
1476 | xel = "application/xcap-el+xml",
1477 | xer = "application/xcap-error+xml",
1478 | xfd = "application/vnd.xfdl",
1479 | xfdf = "application/xfdf",
1480 | xfdl = "application/vnd.xfdl",
1481 | xhe = "audio/usac",
1482 | xht = "application/xhtml+xml",
1483 | xhtm = "application/xhtml+xml",
1484 | xhtml = "application/xhtml+xml",
1485 | xhvml = "application/xv+xml",
1486 | xif = "image/vnd.xiff",
1487 | xla = "application/vnd.ms-excel",
1488 | xlam = "application/vnd.ms-excel.addin.macroEnabled.12",
1489 | xlc = "application/vnd.ms-excel",
1490 | xlf = "application/xliff+xml",
1491 | xlim = "application/vnd.xmpie.xlim",
1492 | xlm = "application/vnd.ms-excel",
1493 | xls = "application/vnd.ms-excel",
1494 | xlsb = "application/vnd.ms-excel.sheet.binary.macroEnabled.12",
1495 | xlsm = "application/vnd.ms-excel.sheet.macroEnabled.12",
1496 | xlsx = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
1497 | xlt = "application/vnd.ms-excel",
1498 | xltm = "application/vnd.ms-excel.template.macroEnabled.12",
1499 | xltx = "application/vnd.openxmlformats-officedocument.spreadsheetml.template",
1500 | xlw = "application/vnd.ms-excel",
1501 | xml = "application/xml",
1502 | xmls = "application/dskpp+xml",
1503 | xmt_bin = "model/vnd.parasolid.transmit.binary",
1504 | xmt_txt = "model/vnd.parasolid.transmit.text",
1505 | xns = "application/xcap-ns+xml",
1506 | xo = "application/vnd.olpc-sugar",
1507 | xodp = "application/vnd.collabio.xodocuments.presentation",
1508 | xods = "application/vnd.collabio.xodocuments.spreadsheet",
1509 | xodt = "application/vnd.collabio.xodocuments.document",
1510 | xop = "application/xop+xml",
1511 | xotp = "application/vnd.collabio.xodocuments.presentation-template",
1512 | xots = "application/vnd.collabio.xodocuments.spreadsheet-template",
1513 | xott = "application/vnd.collabio.xodocuments.document-template",
1514 | xpak = "application/vnd.gentoo.xpak",
1515 | xpi = "application/x-xpinstall",
1516 | xpm = "image/x-xpixmap",
1517 | xpr = "application/vnd.is-xpr",
1518 | xps = "application/vnd.ms-xpsdocument",
1519 | xpw = "application/vnd.intercon.formnet",
1520 | xpx = "application/vnd.intercon.formnet",
1521 | xsf = "application/prs.xsf+xml",
1522 | xsl = "application/xslt+xml",
1523 | xslt = "application/xslt+xml",
1524 | xsm = "application/vnd.syncml+xml",
1525 | xspf = "application/xspf+xml",
1526 | xtel = "chemical/x-xtel",
1527 | xul = "application/vnd.mozilla.xul+xml",
1528 | xvm = "application/xv+xml",
1529 | xvml = "application/xv+xml",
1530 | xwd = "image/x-xwindowdump",
1531 | xyz = "chemical/x-xyz",
1532 | xyze = "image/vnd.radiance",
1533 | xz = "application/x-xz",
1534 | yaml = "application/yaml",
1535 | yang = "application/yang",
1536 | yin = "application/yin+xml",
1537 | yme = "application/vnd.yaoweme",
1538 | yml = "application/yaml",
1539 | yt = "video/vnd.youtube.yt",
1540 | zaz = "application/vnd.zzazz.deck+xml",
1541 | zfc = "application/vnd.filmit.zfc",
1542 | zfo = "application/vnd.software602.filler.form-xml-zip",
1543 | zip = "application/zip",
1544 | zir = "application/vnd.zul",
1545 | zirz = "application/vnd.zul",
1546 | zmm = "application/vnd.HandHeld-Entertainment+xml",
1547 | zmt = "chemical/x-mopac-input",
1548 | zone = "text/dns",
1549 | zst = "application/zstd"
1550 | )
1551 |
--------------------------------------------------------------------------------
/R/parse.R:
--------------------------------------------------------------------------------
1 | ## Rook::Utils$parse() has a few problems: 1. it adds an extra \r\n to the file
2 | ## uploaded; 2. if there are multiple files uploaded, only the info about the
3 | ## last file is recorded. Besides, I did not escape non-file data, nor did I
4 | ## unescape the filenames. The former is not important to me at the moment,
5 | ## since the primary purpose of this function is for shiny IE8/9 file uploading;
6 | ## the latter is probably not important, either, since the users normally only
7 | ## want the content of the file(s) instead of the name(s).
8 |
9 | #' Parse multipart form data
10 | #'
11 | #' This function parses the HTML form data from a Rook environment (an HTTP POST
12 | #' request).
13 | #' @param env the HTTP request environment
14 | #' @return A named list containing the values of the form data, and the files
15 | #' uploaded are saved to temporary files (the temporary filenames are
16 | #' returned). It may also be `NULL` if there is anything unexpected in the
17 | #' form data, or the form is empty.
18 | #' @references This function was borrowed from
19 | #' with slight modifications.
20 | #' @export
21 | #' @useDynLib mime, .registration = TRUE
22 | parse_multipart = function(env) {
23 | ctype = env$CONTENT_TYPE
24 | if (length(grep('^multipart', ctype)) == 0L) return()
25 |
26 | EOL = '\r\n'
27 | params = list()
28 | input = env$rook.input; input$rewind()
29 | content_length = as.integer(env$CONTENT_LENGTH)
30 | # some constants regarding boundaries
31 | boundary = gsub('^multipart/.*boundary="?([^";,]+)"?', '--\\1', ctype)
32 |
33 | bytesize = function(x) nchar(x, type = 'bytes')
34 | EOL_size = bytesize(EOL)
35 | EOL_raw = charToRaw(EOL)
36 | boundary_size = bytesize(boundary)
37 | boundaryEOL = paste(boundary, EOL, sep = '')
38 | boundaryEOL_size = boundary_size + bytesize(EOL)
39 | boundaryEOL_raw = charToRaw(boundaryEOL)
40 | EOLEOL = paste(EOL, EOL, sep = '')
41 | EOLEOL_size = bytesize(EOLEOL)
42 | EOLEOL_raw = charToRaw(EOLEOL)
43 |
44 | buf = new.env(parent = emptyenv())
45 | buf$bufsize = 16384L # never read more than bufsize bytes (16K)
46 | buf$read_buffer = input$read(boundaryEOL_size)
47 | buf$read_buffer_len = length(buf$read_buffer)
48 | buf$unread = content_length - boundary_size
49 | if (!identical(boundaryEOL_raw, buf$read_buffer)) {
50 | warning('bad content body')
51 | input$rewind()
52 | return()
53 | }
54 |
55 | # read the smaller one of the unread content and the next chunk
56 | fill_buffer = function() {
57 | x = input$read(min(buf$bufsize, buf$unread))
58 | n = length(x)
59 | if (n == 0L) return()
60 | buf$read_buffer = c(buf$read_buffer, x)
61 | buf$read_buffer_len = length(buf$read_buffer)
62 | buf$unread = buf$unread - n
63 | }
64 | # slices off the beginning part of read_buffer, e.g. i is the position of
65 | # EOLEOL, and size is EOLEOL_size, and read_buffer is [......EOLEOL+++], then
66 | # slice_buffer returns the the beginning [......], and turns read_buffer to
67 | # the remaining [+++]
68 | slice_buffer = function(i, size) {
69 | slice = buf$read_buffer[if (i > 1) 1:(i - 1) else 1]
70 | buf$read_buffer = if ((i+size) <= buf$read_buffer_len)
71 | buf$read_buffer[(i + size):buf$read_buffer_len] else raw()
72 | buf$read_buffer_len = length(buf$read_buffer)
73 | slice
74 | }
75 |
76 | # prime the read_buffer
77 | buf$read_buffer = raw()
78 | fill_buffer()
79 |
80 | # find the position of the raw vector x1 in x2
81 | raw_match = function(x1, x2) {
82 | if (is.character(x1)) x1 = charToRaw(x1)
83 | .Call('rawmatch', x1, x2, PACKAGE = 'mime')
84 | }
85 | unescape = function(x) {
86 | unlist(lapply(x, function(s) utils::URLdecode(chartr('+', ' ', s))))
87 | }
88 |
89 | while (TRUE) {
90 | head = value = NULL
91 | filename = content_type = name = NULL
92 | while (is.null(head)) {
93 | i = raw_match(EOLEOL_raw, buf$read_buffer)
94 | if (length(i)) {
95 | head = slice_buffer(i, EOLEOL_size)
96 | break
97 | } else if (buf$unread) {
98 | fill_buffer()
99 | } else {
100 | break # we've read everything and still haven't seen a valid head
101 | }
102 | }
103 | if (is.null(head)) {
104 | warning('Bad post payload: searching for a header')
105 | input$rewind()
106 | return()
107 | }
108 | # cat('Head:',rawToChar(head),'\n') they're 8bit clean
109 | head = rawToChar(head)
110 | token = '[^\\s()<>,;:\\"\\/\\[\\]?=]+'
111 | condisp = sprintf('Content-Disposition:\\s*%s\\s*', token)
112 | dispparm = sprintf(';\\s*(%s)=("(?:\\"|[^"])*"|%s)*', token, token)
113 | rfc2183 = sprintf('(?m)^%s(%s)+$', condisp, dispparm)
114 | broken_quoted = sprintf(
115 | '(?m)^%s.*;\\sfilename="(.*?)"(?:\\s*$|\\s*;\\s*%s=)', condisp, token
116 | )
117 | broken_unquoted = sprintf('(?m)^%s.*;\\sfilename=(%s)', condisp, token)
118 | if (length(grep(rfc2183, head, perl = TRUE))) {
119 | first_line = sub(condisp, '', strsplit(head, EOL)[[1L]][1], perl = TRUE)
120 | pairs = strsplit(first_line, ';', fixed = TRUE)[[1L]]
121 | fnmatch = '\\s*filename=(.*)\\s*'
122 | if (any(grepl(fnmatch, pairs, perl = TRUE))) {
123 | filename = pairs[grepl(fnmatch, pairs, perl = TRUE)][1]
124 | filename = gsub('"', '', sub(fnmatch, '\\1', filename, perl = TRUE))
125 | }
126 | } else if (length(grep(broken_quoted, head, perl = TRUE))) {
127 | filename = sub(
128 | broken_quoted, '\\1', strsplit(head, '\r\n')[[1L]][1], perl = TRUE
129 | )
130 | } else if (length(grep(broken_unquoted, head, perl = TRUE))) {
131 | filename = sub(
132 | broken_unquoted, '\\1', strsplit(head, '\r\n')[[1L]][1], perl = TRUE
133 | )
134 | }
135 | # TODO: decoding filenames seems to be a mess here; skip it for now
136 | # if (!is.null(filename) && filename != '') {
137 | # filename = unescape(filename)
138 | # }
139 | headlines = strsplit(head, EOL, fixed = TRUE)[[1L]]
140 | content_type_re = '(?mi)Content-Type: (.*)'
141 | content_types = grep(content_type_re, headlines, perl = TRUE, value = TRUE)
142 | if (length(content_types)) {
143 | content_type = sub(content_type_re, '\\1', content_types[1], perl = TRUE)
144 | }
145 | name = sub(
146 | '(?si)Content-Disposition:.*\\s+name="?([^\";]*).*"?', '\\1', head,
147 | perl = TRUE
148 | )
149 | while (TRUE) {
150 | i = raw_match(boundary, buf$read_buffer)
151 | if (length(i)) {
152 | value = slice_buffer(i, boundary_size)
153 | # strip off the extra EOL before the boundary
154 | if (identical(tail(value, EOL_size), EOL_raw))
155 | value = head(value, -EOL_size)
156 | if (length(value)) {
157 | # drop EOL only values
158 | if (identical(value, EOL_raw)) break
159 | if (!is.null(filename) || !is.null(content_type)) {
160 | data = list()
161 | data$name = if (is.null(filename)) NA_character_ else filename
162 | data$size = length(value)
163 | data$type = if (is.null(content_type)) NA_character_ else content_type
164 | data$datapath = tempfile()
165 | con = file(data$datapath, open = 'wb')
166 | tryCatch(writeBin(value, con), finally = close(con))
167 | params[[name]] = rbind(params[[name]], as.data.frame(data, stringsAsFactors = FALSE))
168 | } else {
169 | len = length(value)
170 | # trim trailing EOL
171 | if (len > 2 && length(raw_match(EOL, value[(len - 1):len])))
172 | len = len - 2
173 | # handle array parameters (TODO: why Utils$escape?)
174 | paramValue = rawToChar(value[1:len])
175 | paramSet = FALSE
176 | if (grepl('\\[\\]$', name)) {
177 | name = sub('\\[\\]$', '', name)
178 | if (name %in% names(params)) {
179 | params[[name]] = c(params[[name]], paramValue)
180 | paramSet = TRUE
181 | }
182 | }
183 | if (!paramSet) params[[name]] = paramValue
184 | }
185 | }
186 | break
187 | } else if (buf$unread) {
188 | fill_buffer()
189 | } else {
190 | break # we've read everything and still haven't seen a valid value
191 | }
192 | }
193 | if (is.null(value)) {
194 | # bad post payload
195 | input$rewind()
196 | warning('Bad post payload: searching for a body part')
197 | return(NULL)
198 | }
199 | # now search for ending markers or the beginning of another part
200 | while (buf$read_buffer_len < 2 && buf$unread) fill_buffer()
201 | if (buf$read_buffer_len < 2 && buf$unread == 0) {
202 | # bad stuff at the end; just return what we've got and presume everything
203 | # is okay
204 | input$rewind()
205 | return(params)
206 | }
207 | # valid ending
208 | if (length(raw_match('--', buf$read_buffer[1:2]))) {
209 | input$rewind()
210 | return(params)
211 | }
212 | # skip past the EOL.
213 | if (length(raw_match(EOL, buf$read_buffer[1:EOL_size]))) {
214 | slice_buffer(1, EOL_size)
215 | } else {
216 | warning('Bad post body: EOL not present')
217 | input$rewind()
218 | return(params)
219 | }
220 | # another sanity check before we try to parse another part
221 | if ((buf$read_buffer_len + buf$unread) < boundary_size) {
222 | warning('Bad post body: unknown trailing bytes')
223 | input$rewind()
224 | return(params)
225 | }
226 | }
227 | }
228 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## mime
2 |
3 |
4 |
5 | [](https://github.com/yihui/mime/actions)
6 | [](https://cran.r-project.org/package=mime)
8 |
9 |
10 |
11 | This is an R package for mapping filename extensions to [MIME
12 | types](https://en.wikipedia.org/wiki/Internet_media_type), based on the data
13 | [derived](https://github.com/yihui/mime/blob/main/tools/update.R) from
14 | `/etc/mime.types`.
15 |
16 | ``` r
17 | # installation
18 | install.packages('mime')
19 |
20 | library(mime)
21 | guess_type(c('a/b/c.html', 'd.pdf', 'e.odt', 'foo.docx', 'tex'))
22 | # [1] "text/html"
23 | # [2] "application/pdf"
24 | # [3] "application/vnd.oasis.opendocument.text"
25 | # [4] "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
26 | # [5] "text/x-tex"
27 | ```
28 |
--------------------------------------------------------------------------------
/inst/NEWS.Rd:
--------------------------------------------------------------------------------
1 | \name{NEWS}
2 | \title{News for Package 'mime'}
3 |
4 | \section{CHANGES IN mime VERSION 999.999}{
5 | \itemize{
6 | \item This NEWS file is only a placeholder. The version 999.999 does not really
7 | exist. Please read the NEWS on Github: \url{https://github.com/yihui/mime/releases}
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/man/guess_type.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/mime.R
3 | \name{guess_type}
4 | \alias{guess_type}
5 | \title{Guess the MIME types from filenames}
6 | \usage{
7 | guess_type(
8 | file,
9 | unknown = "application/octet-stream",
10 | empty = "text/plain",
11 | mime_extra = mimeextra,
12 | subtype = ""
13 | )
14 | }
15 | \arguments{
16 | \item{file}{a character vector of filenames, or filename extensions}
17 |
18 | \item{unknown}{the MIME type to return when the file extension was not found
19 | in the table}
20 |
21 | \item{empty}{the MIME type for files that do not have extensions}
22 |
23 | \item{mime_extra}{a named character vector of the form \code{c(extension = type)}
24 | providing extra MIME types (by default, \code{mime:::mimeextra}); note this MIME
25 | table takes precedence over the standard table \code{\link{mimemap}}}
26 |
27 | \item{subtype}{a character vector of MIME subtypes, which should be of the
28 | same length as \code{file} if provided (use an empty character string for a file
29 | if we do not want a subtype for it)}
30 | }
31 | \description{
32 | Look up in the \code{\link{mimemap}} table for the MIME types based on the extensions of
33 | the given filenames.
34 | }
35 | \examples{
36 | library(mime)
37 | # well-known file types
38 | guess_type(c("a/b/c.html", "d.pdf", "e.odt", "foo.docx", "tex"))
39 | # not in the standard table, but in mimeextra
40 | guess_type(c("a.md", "b.R"), mime_extra = NULL)
41 | guess_type(c("a.md", "b.R"))
42 |
43 | # override the standard MIME table (tex is text/x-tex by default)
44 | guess_type("tex", mime_extra = c(tex = "text/plain"))
45 | # unknown extension 'zzz'
46 | guess_type("foo.zzz")
47 | # force unknown types to be plain text
48 | guess_type("foo.zzz", unknown = "text/plain")
49 |
50 | # empty file extension
51 | guess_type("Makefile")
52 | # we know it is a plain text file
53 | guess_type("Makefile", empty = "text/plain")
54 |
55 | # subtypes
56 | guess_type(c("abc.html", "def.htm"), subtype = c("charset=UTF-8", ""))
57 | }
58 |
--------------------------------------------------------------------------------
/man/mimemap.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/mime.R
3 | \docType{data}
4 | \name{mimemap}
5 | \alias{mimemap}
6 | \title{Tables for mapping filename extensions to MIME types}
7 | \source{
8 | The file \verb{/etc/mime.types} on Debian.
9 | }
10 | \description{
11 | The data \code{mimemap} is a named character vector that stores the filename
12 | extensions and the corresponding MIME types, e.g. \code{c(html = 'text/html', pdf = 'application/pdf', ...)}. The character vector \code{mime:::mimeextra} stores
13 | some additional types that we know, such as Markdown files (\code{.md}), or R
14 | scripts (\code{.R}).
15 | }
16 | \examples{
17 | str(as.list(mimemap))
18 | mimemap["pdf"]
19 | mimemap[c("html", "js", "css")]
20 | # additional MIME types (not exported)
21 | mime:::mimeextra
22 | }
23 | \keyword{datasets}
24 |
--------------------------------------------------------------------------------
/man/parse_multipart.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/parse.R
3 | \name{parse_multipart}
4 | \alias{parse_multipart}
5 | \title{Parse multipart form data}
6 | \usage{
7 | parse_multipart(env)
8 | }
9 | \arguments{
10 | \item{env}{the HTTP request environment}
11 | }
12 | \value{
13 | A named list containing the values of the form data, and the files
14 | uploaded are saved to temporary files (the temporary filenames are
15 | returned). It may also be \code{NULL} if there is anything unexpected in the
16 | form data, or the form is empty.
17 | }
18 | \description{
19 | This function parses the HTML form data from a Rook environment (an HTTP POST
20 | request).
21 | }
22 | \references{
23 | This function was borrowed from
24 | \url{https://github.com/jeffreyhorner/Rook/} with slight modifications.
25 | }
26 |
--------------------------------------------------------------------------------
/mime.Rproj:
--------------------------------------------------------------------------------
1 | Version: 1.0
2 |
3 | RestoreWorkspace: Default
4 | SaveWorkspace: Default
5 | AlwaysSaveHistory: Default
6 |
7 | EnableCodeIndexing: Yes
8 | UseSpacesForTab: Yes
9 | NumSpacesForTab: 2
10 | Encoding: UTF-8
11 |
12 | RnwWeave: knitr
13 | LaTeX: pdfLaTeX
14 |
15 | AutoAppendNewline: Yes
16 | StripTrailingWhitespace: Yes
17 |
18 | BuildType: Package
19 | PackageInstallArgs: -v && Rscript -e "Rd2roxygen::rab(install=T)"
20 | PackageBuildArgs: -v && Rscript -e "Rd2roxygen::rab(build=T,install=F)"
21 | PackageCheckArgs: --as-cran
22 |
--------------------------------------------------------------------------------
/src/init.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | extern SEXP rawmatch (SEXP needle, SEXP haystack);
7 | static const R_CallMethodDef callMethods[] = {
8 | {"rawmatch", (DL_FUNC) &rawmatch, 2},
9 | {NULL, NULL, 0}
10 | };
11 |
12 | void R_init_mime(DllInfo *dll)
13 | {
14 | R_registerRoutines(dll, NULL, callMethods, NULL, NULL);
15 | R_useDynamicSymbols(dll, FALSE);
16 | }
17 |
--------------------------------------------------------------------------------
/src/rawmatch.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | SEXP rawmatch(SEXP needle, SEXP haystack) {
5 | int i, j, n1, n2;
6 | Rbyte *x1, *x2;
7 | SEXP ans;
8 |
9 | n1 = LENGTH(needle);
10 | x1 = RAW(needle);
11 | n2 = LENGTH(haystack);
12 | x2 = RAW(haystack);
13 | if (n1 * n2 == 0 || n1 > n2) return allocVector(INTSXP, 0);
14 |
15 | ans = allocVector(INTSXP, 1);
16 |
17 | for (i = 0; i <= (n2 - n1); i++) {
18 | if (x2[i] == x1[0]) {
19 | for (j = 0; j < n1; j++) {
20 | if (x2[i + j] != x1[j]) break;
21 | }
22 | if (j == n1) {
23 | INTEGER(ans)[0] = i + 1;
24 | return ans;
25 | }
26 | }
27 | }
28 | return allocVector(INTSXP, 0);
29 | }
30 |
--------------------------------------------------------------------------------
/tests/mime.R:
--------------------------------------------------------------------------------
1 | stopifnot(
2 | mime::guess_type('Makefile', empty = 'text/x-makefile') == 'text/x-makefile'
3 | )
4 |
--------------------------------------------------------------------------------
/tools/update.R:
--------------------------------------------------------------------------------
1 | sys.source('R/mimeextra.R', environment())
2 |
3 | lines = readLines(mimefile <- '/etc/mime.types', warn = FALSE)
4 | # remove comments and blank lines
5 | lines = grep('^[a-z]', lines, value = TRUE)
6 | lines = unlist(lapply(strsplit(lines, '\\s+'), function(x) {
7 | # each line is of the form: type ext [ext2 ext3 ...]
8 | if (length(x) <= 1) return()
9 | # convert to c(html = 'text/html', js = 'application/javascript', ...)
10 | setNames(rep(x[1], length(x) - 1), x[-1])
11 | }), recursive = FALSE)
12 |
13 | # remove duplicated file extensions
14 | lines = lines[!duplicated(names(lines))]
15 | # write R source code to the data directory; "hand-writing" instead dump(), to
16 | # make sure we can easily catch possible future differences in version control
17 | dump_vec = function(name, x) {
18 | nm = sort(names(x))
19 | # TODO: remove special treatment for jpeg https://github.com/posit-dev/connectapi/issues/382
20 | j = names(which(x == 'image/jpeg'))
21 | i = nm %in% j
22 | nm[i] = c(intersect(j, 'jpeg'), setdiff(j, 'jpeg'))
23 | writeLines(c(
24 | sprintf('%s = c(', name),
25 | paste(sprintf(
26 | '%s = "%s"',
27 | # invalid names should be quoted using ``
28 | ifelse(make.names(nm) == nm, nm, sprintf('`%s`', nm)),
29 | x[nm]
30 | ), collapse = ',\n'),
31 | ')'
32 | ), sprintf('R/%s.R', name))
33 | }
34 |
35 | dump_vec('mimemap', lines)
36 | extra = mimeextra[setdiff(names(mimeextra), names(lines))]
37 | extra['rd'] = 'text/plain' # override the rd entry (chemical/x-mdl-rdfile -> text/plain, i.e. R documentation)
38 | dump_vec('mimeextra', extra)
39 |
--------------------------------------------------------------------------------