mime/0000755000176200001440000000000013616332726011212 5ustar liggesusersmime/NAMESPACE0000644000176200001440000000023513576553301012430 0ustar liggesusers# Generated by roxygen2: do not edit by hand export(guess_type) export(mimemap) export(parse_multipart) import(utils) useDynLib(mime, .registration = TRUE) mime/README.md0000644000176200001440000000155313500002566012461 0ustar liggesusers# mime [![Build Status](https://travis-ci.org/yihui/mime.svg)](https://travis-ci.org/yihui/mime) [![Downloads from the RStudio CRAN mirror](https://cranlogs.r-pkg.org/badges/mime)](https://cran.r-project.org/package=mime) This is an R package for mapping filename extensions to [MIME types](http://en.wikipedia.org/wiki/Internet_media_type), based on the data [derived](R/mime.R) from `/etc/mime.types`. ```r # installation install.packages('mime') library(mime) guess_type(c('a/b/c.html', 'd.pdf', 'e.odt', 'foo.docx', 'tex')) # [1] "text/html" # [2] "application/pdf" # [3] "application/vnd.oasis.opendocument.text" # [4] "application/vnd.openxmlformats-officedocument.wordprocessingml.document" # [5] "text/x-tex" ``` mime/man/0000755000176200001440000000000013357673726011777 5ustar liggesusersmime/man/mimemap.Rd0000644000176200001440000000140013576553301013673 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/mime.R \docType{data} \name{mimemap} \alias{mimemap} \alias{mimeextra} \title{Tables for mapping filename extensions to MIME types} \source{ The file \file{/etc/mime.types} on Debian. } \description{ The data \code{mimemap} is a named character vector that stores the filename extensions and the corresponding MIME types, e.g. \code{c(html = 'text/html', pdf = 'application/pdf', ...)}. The character vector \code{mimeextra} stores some additional types that we know, such as Markdown files (\file{.md}), or R scripts (\file{.R}). } \examples{ str(as.list(mimemap)) mimemap["pdf"] mimemap[c("html", "js", "css")] # additional MIME types (not exported) mime:::mimeextra } \keyword{datasets} mime/man/parse_multipart.Rd0000644000176200001440000000134213576553302015467 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/parse.R \name{parse_multipart} \alias{parse_multipart} \title{Parse multipart form data} \usage{ parse_multipart(env) } \arguments{ \item{env}{the HTTP request environment} } \value{ A named list containing the values of the form data, and the files uploaded are saved to temporary files (the temporary filenames are returned). It may also be \code{NULL} if there is anything unexpected in the form data, or the form is empty. } \description{ This function parses the HTML form data from a Rook environment (an HTTP POST request). } \references{ This function was borrowed from \url{https://github.com/jeffreyhorner/Rook/} with slight modifications. } mime/man/guess_type.Rd0000644000176200001440000000341113576553301014441 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/mime.R \name{guess_type} \alias{guess_type} \title{Guess the MIME types from filenames} \usage{ guess_type( file, unknown = "application/octet-stream", empty = "text/plain", mime_extra = mimeextra, subtype = "" ) } \arguments{ \item{file}{a character vector of filenames, or filename extensions} \item{unknown}{the MIME type to return when the file extension was not found in the table} \item{empty}{the MIME type for files that do not have extensions} \item{mime_extra}{a named character vector of the form \code{c(extension = type)} providing extra MIME types (by default, \code{\link{mimeextra}}); note this MIME table takes precedence over the standard table \code{\link{mimemap}}} \item{subtype}{a character vector of MIME subtypes, which should be of the same length as \code{file} if provided (use an empty character string for a file if we do not want a subtype for it)} } \description{ Look up in the \code{\link{mimemap}} table for the MIME types based on the extensions of the given filenames. } \examples{ library(mime) # well-known file types guess_type(c("a/b/c.html", "d.pdf", "e.odt", "foo.docx", "tex")) # not in the standard table, but in mimeextra guess_type(c("a.md", "b.R"), mime_extra = NULL) guess_type(c("a.md", "b.R")) # override the standard MIME table (tex is text/x-tex by default) guess_type("tex", mime_extra = c(tex = "text/plain")) # unknown extension 'bar' guess_type("foo.bar") # force unknown types to be plain text guess_type("foo.bar", unknown = "text/plain") # empty file extension guess_type("Makefile") # we know it is a plain text file guess_type("Makefile", empty = "text/plain") # subtypes guess_type(c("abc.html", "def.htm"), subtype = c("charset=UTF-8", "")) } mime/DESCRIPTION0000644000176200001440000000155613616332726012727 0ustar liggesusersPackage: mime Type: Package Title: Map Filenames to MIME Types Version: 0.9 Authors@R: c( person("Yihui", "Xie", role = c("aut", "cre"), email = "xie@yihui.name", comment = c(ORCID = "0000-0003-0645-5666")), person("Jeffrey", "Horner", role = "ctb"), person("Beilei", "Bian", role = "ctb") ) Description: Guesses the MIME type from a filename extension using the data derived from /etc/mime.types in UNIX-type systems. Imports: tools License: GPL URL: https://github.com/yihui/mime BugReports: https://github.com/yihui/mime/issues LazyData: TRUE RoxygenNote: 7.0.2 Encoding: UTF-8 NeedsCompilation: yes Packaged: 2020-02-04 17:11:45 UTC; yihui Author: Yihui Xie [aut, cre] (), Jeffrey Horner [ctb], Beilei Bian [ctb] Maintainer: Yihui Xie Repository: CRAN Date/Publication: 2020-02-04 18:20:06 UTC mime/tests/0000755000176200001440000000000013357673726012366 5ustar liggesusersmime/tests/mime.R0000644000176200001440000000013412334063567013424 0ustar liggesusersstopifnot( mime::guess_type('Makefile', empty = 'text/x-makefile') == 'text/x-makefile' ) mime/src/0000755000176200001440000000000013576553622012006 5ustar liggesusersmime/src/init.c0000644000176200001440000000057113152007107013076 0ustar liggesusers#include #include #include #include extern SEXP rawmatch (SEXP needle, SEXP haystack); static const R_CallMethodDef callMethods[] = { {"rawmatch", (DL_FUNC) &rawmatch, 2}, {NULL, NULL, 0} }; void R_init_mime(DllInfo *dll) { R_registerRoutines(dll, NULL, callMethods, NULL, NULL); R_useDynamicSymbols(dll, FALSE); } mime/src/rawmatch.c0000644000176200001440000000110712411343125013735 0ustar liggesusers#include #include SEXP rawmatch(SEXP needle, SEXP haystack) { int i, j, n1, n2; Rbyte *x1, *x2; SEXP ans; n1 = LENGTH(needle); x1 = RAW(needle); n2 = LENGTH(haystack); x2 = RAW(haystack); if (n1 * n2 == 0 || n1 > n2) return allocVector(INTSXP, 0); ans = allocVector(INTSXP, 1); for (i = 0; i < n2; i++) { if (x2[i] == x1[0]) { for (j = 0; j < n1; j++) { if (x2[i + j] != x1[j]) break; } if (j == n1) { INTEGER(ans)[0] = i + 1; return ans; } } } return allocVector(INTSXP, 0); } mime/NEWS0000644000176200001440000000275013616322675011717 0ustar liggesusers CHANGES IN mime VERSION 0.9 MINOR CHANGES o Added the MIME type for .jsonp files (thanks, @clabornd, #11). CHANGES IN mime VERSION 0.8 MINOR CHANGES o Added the MIME type for .scss files (thanks, @cpsievert, #10). CHANGES IN mime VERSION 0.7 MINOR CHANGES o Added more types for .Rnw, .Rproj, and .yml files (thanks, @beanumber, #9). CHANGES IN mime VERSION 0.6 MINOR CHANGES o Updated the MIME types from Ubuntu 18.04. CHANGES IN mime VERSION 0.5 MAJOR CHANGES o the package license was changed from GPL-2 to GPL CHANGES IN mime VERSION 0.4 NEW FEATURES o added a new content type: .geojson -> application/vnd.geo+json (thanks, @dmpe, #3) BUG FIXES o guess_type() may fail on Windows when the file paths are too long (#2) CHANGES IN mime VERSION 0.3 NEW FEATURES o added a few more content types CHANGES IN mime VERSION 0.2 NEW FEATURES o added a function parse_multipart() to parse multipart form data submitted via HTTP POST CHANGES IN mime VERSION 0.1.2 BUG FIXES o guess_type() returned wrong values for filenames without extensions: it should have used the 'empty' argument. CHANGES IN mime VERSION 0.1.1 BUG FIXES o 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. CHANGES IN mime VERSION 0.1 NEW FEATURES o The initial version of mime. The main function is mime::guess_type(). mime/R/0000755000176200001440000000000013616322642011407 5ustar liggesusersmime/R/mimemap.R0000644000176200001440000004111213576553507013171 0ustar liggesusersmimemap = c( ez = "application/andrew-inset", anx = "application/annodex", atom = "application/atom+xml", atomcat = "application/atomcat+xml", atomsrv = "application/atomserv+xml", lin = "application/bbolin", cu = "application/cu-seeme", davmount = "application/davmount+xml", dcm = "application/dicom", tsp = "application/dsptype", es = "application/ecmascript", otf = "application/font-sfnt", ttf = "application/font-sfnt", pfr = "application/font-tdpfr", woff = "application/font-woff", spl = "application/futuresplash", gz = "application/gzip", hta = "application/hta", jar = "application/java-archive", ser = "application/java-serialized-object", class = "application/java-vm", js = "application/javascript", json = "application/json", m3g = "application/m3g", hqx = "application/mac-binhex40", cpt = "application/mac-compactpro", nb = "application/mathematica", nbp = "application/mathematica", mbox = "application/mbox", mdb = "application/msaccess", doc = "application/msword", dot = "application/msword", mxf = "application/mxf", bin = "application/octet-stream", deploy = "application/octet-stream", msu = "application/octet-stream", msp = "application/octet-stream", oda = "application/oda", opf = "application/oebps-package+xml", ogx = "application/ogg", one = "application/onenote", onetoc2 = "application/onenote", onetmp = "application/onenote", onepkg = "application/onenote", pdf = "application/pdf", pgp = "application/pgp-encrypted", key = "application/pgp-keys", sig = "application/pgp-signature", prf = "application/pics-rules", ps = "application/postscript", ai = "application/postscript", eps = "application/postscript", epsi = "application/postscript", epsf = "application/postscript", eps2 = "application/postscript", eps3 = "application/postscript", rar = "application/rar", rdf = "application/rdf+xml", rtf = "application/rtf", stl = "application/sla", smi = "application/smil+xml", smil = "application/smil+xml", xhtml = "application/xhtml+xml", xht = "application/xhtml+xml", xml = "application/xml", xsd = "application/xml", xsl = "application/xslt+xml", xslt = "application/xslt+xml", xspf = "application/xspf+xml", zip = "application/zip", apk = "application/vnd.android.package-archive", cdy = "application/vnd.cinderella", deb = "application/vnd.debian.binary-package", ddeb = "application/vnd.debian.binary-package", udeb = "application/vnd.debian.binary-package", sfd = "application/vnd.font-fontforge-sfd", kml = "application/vnd.google-earth.kml+xml", kmz = "application/vnd.google-earth.kmz", xul = "application/vnd.mozilla.xul+xml", xls = "application/vnd.ms-excel", xlb = "application/vnd.ms-excel", xlt = "application/vnd.ms-excel", xlam = "application/vnd.ms-excel.addin.macroEnabled.12", xlsb = "application/vnd.ms-excel.sheet.binary.macroEnabled.12", xlsm = "application/vnd.ms-excel.sheet.macroEnabled.12", xltm = "application/vnd.ms-excel.template.macroEnabled.12", eot = "application/vnd.ms-fontobject", thmx = "application/vnd.ms-officetheme", cat = "application/vnd.ms-pki.seccat", ppt = "application/vnd.ms-powerpoint", pps = "application/vnd.ms-powerpoint", ppam = "application/vnd.ms-powerpoint.addin.macroEnabled.12", pptm = "application/vnd.ms-powerpoint.presentation.macroEnabled.12", sldm = "application/vnd.ms-powerpoint.slide.macroEnabled.12", ppsm = "application/vnd.ms-powerpoint.slideshow.macroEnabled.12", potm = "application/vnd.ms-powerpoint.template.macroEnabled.12", docm = "application/vnd.ms-word.document.macroEnabled.12", dotm = "application/vnd.ms-word.template.macroEnabled.12", odc = "application/vnd.oasis.opendocument.chart", odb = "application/vnd.oasis.opendocument.database", odf = "application/vnd.oasis.opendocument.formula", odg = "application/vnd.oasis.opendocument.graphics", otg = "application/vnd.oasis.opendocument.graphics-template", odi = "application/vnd.oasis.opendocument.image", odp = "application/vnd.oasis.opendocument.presentation", otp = "application/vnd.oasis.opendocument.presentation-template", ods = "application/vnd.oasis.opendocument.spreadsheet", ots = "application/vnd.oasis.opendocument.spreadsheet-template", odt = "application/vnd.oasis.opendocument.text", odm = "application/vnd.oasis.opendocument.text-master", ott = "application/vnd.oasis.opendocument.text-template", oth = "application/vnd.oasis.opendocument.text-web", pptx = "application/vnd.openxmlformats-officedocument.presentationml.presentation", sldx = "application/vnd.openxmlformats-officedocument.presentationml.slide", ppsx = "application/vnd.openxmlformats-officedocument.presentationml.slideshow", potx = "application/vnd.openxmlformats-officedocument.presentationml.template", xlsx = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", xltx = "application/vnd.openxmlformats-officedocument.spreadsheetml.template", docx = "application/vnd.openxmlformats-officedocument.wordprocessingml.document", dotx = "application/vnd.openxmlformats-officedocument.wordprocessingml.template", cod = "application/vnd.rim.cod", mmf = "application/vnd.smaf", sdc = "application/vnd.stardivision.calc", sds = "application/vnd.stardivision.chart", sda = "application/vnd.stardivision.draw", sdd = "application/vnd.stardivision.impress", sdf = "application/vnd.stardivision.math", sdw = "application/vnd.stardivision.writer", sgl = "application/vnd.stardivision.writer-global", sxc = "application/vnd.sun.xml.calc", stc = "application/vnd.sun.xml.calc.template", sxd = "application/vnd.sun.xml.draw", std = "application/vnd.sun.xml.draw.template", sxi = "application/vnd.sun.xml.impress", sti = "application/vnd.sun.xml.impress.template", sxm = "application/vnd.sun.xml.math", sxw = "application/vnd.sun.xml.writer", sxg = "application/vnd.sun.xml.writer.global", stw = "application/vnd.sun.xml.writer.template", sis = "application/vnd.symbian.install", cap = "application/vnd.tcpdump.pcap", pcap = "application/vnd.tcpdump.pcap", vsd = "application/vnd.visio", vst = "application/vnd.visio", vsw = "application/vnd.visio", vss = "application/vnd.visio", wbxml = "application/vnd.wap.wbxml", wmlc = "application/vnd.wap.wmlc", wmlsc = "application/vnd.wap.wmlscriptc", wpd = "application/vnd.wordperfect", wp5 = "application/vnd.wordperfect5.1", wk = "application/x-123", `7z` = "application/x-7z-compressed", abw = "application/x-abiword", dmg = "application/x-apple-diskimage", bcpio = "application/x-bcpio", torrent = "application/x-bittorrent", cab = "application/x-cab", cbr = "application/x-cbr", cbz = "application/x-cbz", cdf = "application/x-cdf", cda = "application/x-cdf", vcd = "application/x-cdlink", pgn = "application/x-chess-pgn", mph = "application/x-comsol", cpio = "application/x-cpio", csh = "application/x-csh", dcr = "application/x-director", dir = "application/x-director", dxr = "application/x-director", dms = "application/x-dms", wad = "application/x-doom", dvi = "application/x-dvi", pfa = "application/x-font", pfb = "application/x-font", gsf = "application/x-font", pcf = "application/x-font-pcf", pcf.Z = "application/x-font-pcf", mm = "application/x-freemind", gan = "application/x-ganttproject", gnumeric = "application/x-gnumeric", sgf = "application/x-go-sgf", gcf = "application/x-graphing-calculator", gtar = "application/x-gtar", tgz = "application/x-gtar-compressed", taz = "application/x-gtar-compressed", hdf = "application/x-hdf", hwp = "application/x-hwp", ica = "application/x-ica", info = "application/x-info", ins = "application/x-internet-signup", isp = "application/x-internet-signup", iii = "application/x-iphone", iso = "application/x-iso9660-image", jam = "application/x-jam", jnlp = "application/x-java-jnlp-file", jmz = "application/x-jmol", chrt = "application/x-kchart", kil = "application/x-killustrator", skp = "application/x-koan", skd = "application/x-koan", skt = "application/x-koan", skm = "application/x-koan", kpr = "application/x-kpresenter", kpt = "application/x-kpresenter", ksp = "application/x-kspread", kwd = "application/x-kword", kwt = "application/x-kword", latex = "application/x-latex", lha = "application/x-lha", lyx = "application/x-lyx", lzh = "application/x-lzh", lzx = "application/x-lzx", frm = "application/x-maker", maker = "application/x-maker", frame = "application/x-maker", fm = "application/x-maker", fb = "application/x-maker", book = "application/x-maker", fbdoc = "application/x-maker", mif = "application/x-mif", m3u8 = "application/x-mpegURL", application = "application/x-ms-application", manifest = "application/x-ms-manifest", wmd = "application/x-ms-wmd", wmz = "application/x-ms-wmz", com = "application/x-msdos-program", exe = "application/x-msdos-program", bat = "application/x-msdos-program", dll = "application/x-msdos-program", msi = "application/x-msi", nc = "application/x-netcdf", pac = "application/x-ns-proxy-autoconfig", nwc = "application/x-nwc", o = "application/x-object", oza = "application/x-oz-application", p7r = "application/x-pkcs7-certreqresp", crl = "application/x-pkcs7-crl", pyc = "application/x-python-code", pyo = "application/x-python-code", qgs = "application/x-qgis", shp = "application/x-qgis", shx = "application/x-qgis", qtl = "application/x-quicktimeplayer", rdp = "application/x-rdp", rpm = "application/x-redhat-package-manager", rss = "application/x-rss+xml", rb = "application/x-ruby", sci = "application/x-scilab", sce = "application/x-scilab", xcos = "application/x-scilab-xcos", sh = "application/x-sh", shar = "application/x-shar", swf = "application/x-shockwave-flash", swfl = "application/x-shockwave-flash", scr = "application/x-silverlight", sql = "application/x-sql", sit = "application/x-stuffit", sitx = "application/x-stuffit", sv4cpio = "application/x-sv4cpio", sv4crc = "application/x-sv4crc", tar = "application/x-tar", tcl = "application/x-tcl", gf = "application/x-tex-gf", pk = "application/x-tex-pk", texinfo = "application/x-texinfo", texi = "application/x-texinfo", `~` = "application/x-trash", `%` = "application/x-trash", bak = "application/x-trash", old = "application/x-trash", sik = "application/x-trash", t = "application/x-troff", tr = "application/x-troff", roff = "application/x-troff", man = "application/x-troff-man", me = "application/x-troff-me", ms = "application/x-troff-ms", ustar = "application/x-ustar", src = "application/x-wais-source", wz = "application/x-wingz", crt = "application/x-x509-ca-cert", xcf = "application/x-xcf", fig = "application/x-xfig", xpi = "application/x-xpinstall", xz = "application/x-xz", amr = "audio/amr", awb = "audio/amr-wb", axa = "audio/annodex", au = "audio/basic", snd = "audio/basic", csd = "audio/csound", orc = "audio/csound", sco = "audio/csound", flac = "audio/flac", mid = "audio/midi", midi = "audio/midi", kar = "audio/midi", mpga = "audio/mpeg", mpega = "audio/mpeg", mp2 = "audio/mpeg", mp3 = "audio/mpeg", m4a = "audio/mpeg", m3u = "audio/mpegurl", oga = "audio/ogg", ogg = "audio/ogg", opus = "audio/ogg", spx = "audio/ogg", sid = "audio/prs.sid", aif = "audio/x-aiff", aiff = "audio/x-aiff", aifc = "audio/x-aiff", gsm = "audio/x-gsm", wma = "audio/x-ms-wma", wax = "audio/x-ms-wax", ra = "audio/x-pn-realaudio", rm = "audio/x-pn-realaudio", ram = "audio/x-pn-realaudio", pls = "audio/x-scpls", sd2 = "audio/x-sd2", wav = "audio/x-wav", alc = "chemical/x-alchemy", cac = "chemical/x-cache", cache = "chemical/x-cache", csf = "chemical/x-cache-csf", cbin = "chemical/x-cactvs-binary", cascii = "chemical/x-cactvs-binary", ctab = "chemical/x-cactvs-binary", cdx = "chemical/x-cdx", cer = "chemical/x-cerius", c3d = "chemical/x-chem3d", chm = "chemical/x-chemdraw", cif = "chemical/x-cif", cmdf = "chemical/x-cmdf", cml = "chemical/x-cml", cpa = "chemical/x-compass", bsd = "chemical/x-crossfire", csml = "chemical/x-csml", csm = "chemical/x-csml", ctx = "chemical/x-ctx", cxf = "chemical/x-cxf", cef = "chemical/x-cxf", emb = "chemical/x-embl-dl-nucleotide", embl = "chemical/x-embl-dl-nucleotide", spc = "chemical/x-galactic-spc", inp = "chemical/x-gamess-input", gam = "chemical/x-gamess-input", gamin = "chemical/x-gamess-input", fch = "chemical/x-gaussian-checkpoint", fchk = "chemical/x-gaussian-checkpoint", cub = "chemical/x-gaussian-cube", gau = "chemical/x-gaussian-input", gjc = "chemical/x-gaussian-input", gjf = "chemical/x-gaussian-input", gal = "chemical/x-gaussian-log", gcg = "chemical/x-gcg8-sequence", gen = "chemical/x-genbank", hin = "chemical/x-hin", istr = "chemical/x-isostar", ist = "chemical/x-isostar", jdx = "chemical/x-jcamp-dx", dx = "chemical/x-jcamp-dx", kin = "chemical/x-kinemage", mcm = "chemical/x-macmolecule", mmd = "chemical/x-macromodel-input", mmod = "chemical/x-macromodel-input", mol = "chemical/x-mdl-molfile", rd = "chemical/x-mdl-rdfile", rxn = "chemical/x-mdl-rxnfile", sd = "chemical/x-mdl-sdfile", tgf = "chemical/x-mdl-tgf", mcif = "chemical/x-mmcif", mol2 = "chemical/x-mol2", b = "chemical/x-molconn-Z", gpt = "chemical/x-mopac-graph", mop = "chemical/x-mopac-input", mopcrt = "chemical/x-mopac-input", mpc = "chemical/x-mopac-input", zmt = "chemical/x-mopac-input", moo = "chemical/x-mopac-out", mvb = "chemical/x-mopac-vib", asn = "chemical/x-ncbi-asn1", prt = "chemical/x-ncbi-asn1-ascii", ent = "chemical/x-ncbi-asn1-ascii", val = "chemical/x-ncbi-asn1-binary", aso = "chemical/x-ncbi-asn1-binary", pdb = "chemical/x-pdb", ros = "chemical/x-rosdal", sw = "chemical/x-swissprot", vms = "chemical/x-vamas-iso14976", vmd = "chemical/x-vmd", xtel = "chemical/x-xtel", xyz = "chemical/x-xyz", gif = "image/gif", ief = "image/ief", jp2 = "image/jp2", jpg2 = "image/jp2", jpeg = "image/jpeg", jpg = "image/jpeg", jpe = "image/jpeg", jpm = "image/jpm", jpx = "image/jpx", jpf = "image/jpx", pcx = "image/pcx", png = "image/png", svg = "image/svg+xml", svgz = "image/svg+xml", tiff = "image/tiff", tif = "image/tiff", djvu = "image/vnd.djvu", djv = "image/vnd.djvu", ico = "image/vnd.microsoft.icon", wbmp = "image/vnd.wap.wbmp", cr2 = "image/x-canon-cr2", crw = "image/x-canon-crw", ras = "image/x-cmu-raster", cdr = "image/x-coreldraw", pat = "image/x-coreldrawpattern", cdt = "image/x-coreldrawtemplate", erf = "image/x-epson-erf", art = "image/x-jg", jng = "image/x-jng", bmp = "image/x-ms-bmp", nef = "image/x-nikon-nef", orf = "image/x-olympus-orf", psd = "image/x-photoshop", pnm = "image/x-portable-anymap", pbm = "image/x-portable-bitmap", pgm = "image/x-portable-graymap", ppm = "image/x-portable-pixmap", rgb = "image/x-rgb", xbm = "image/x-xbitmap", xpm = "image/x-xpixmap", xwd = "image/x-xwindowdump", eml = "message/rfc822", igs = "model/iges", iges = "model/iges", msh = "model/mesh", mesh = "model/mesh", silo = "model/mesh", wrl = "model/vrml", vrml = "model/vrml", x3dv = "model/x3d+vrml", x3d = "model/x3d+xml", x3db = "model/x3d+binary", appcache = "text/cache-manifest", ics = "text/calendar", icz = "text/calendar", css = "text/css", csv = "text/csv", `323` = "text/h323", html = "text/html", htm = "text/html", shtml = "text/html", uls = "text/iuls", mml = "text/mathml", md = "text/markdown", markdown = "text/markdown", asc = "text/plain", txt = "text/plain", text = "text/plain", pot = "text/plain", brf = "text/plain", srt = "text/plain", rtx = "text/richtext", sct = "text/scriptlet", wsc = "text/scriptlet", tm = "text/texmacs", tsv = "text/tab-separated-values", ttl = "text/turtle", vcf = "text/vcard", vcard = "text/vcard", jad = "text/vnd.sun.j2me.app-descriptor", wml = "text/vnd.wap.wml", wmls = "text/vnd.wap.wmlscript", bib = "text/x-bibtex", boo = "text/x-boo", `h++` = "text/x-c++hdr", hpp = "text/x-c++hdr", hxx = "text/x-c++hdr", hh = "text/x-c++hdr", `c++` = "text/x-c++src", cpp = "text/x-c++src", cxx = "text/x-c++src", cc = "text/x-c++src", h = "text/x-chdr", htc = "text/x-component", c = "text/x-csrc", d = "text/x-dsrc", diff = "text/x-diff", patch = "text/x-diff", hs = "text/x-haskell", java = "text/x-java", ly = "text/x-lilypond", lhs = "text/x-literate-haskell", moc = "text/x-moc", p = "text/x-pascal", pas = "text/x-pascal", gcd = "text/x-pcs-gcd", pl = "text/x-perl", pm = "text/x-perl", py = "text/x-python", scala = "text/x-scala", etx = "text/x-setext", sfv = "text/x-sfv", tk = "text/x-tcl", tex = "text/x-tex", ltx = "text/x-tex", sty = "text/x-tex", cls = "text/x-tex", vcs = "text/x-vcalendar", `3gp` = "video/3gpp", axv = "video/annodex", dl = "video/dl", dif = "video/dv", dv = "video/dv", fli = "video/fli", gl = "video/gl", mpeg = "video/mpeg", mpg = "video/mpeg", mpe = "video/mpeg", ts = "video/MP2T", mp4 = "video/mp4", qt = "video/quicktime", mov = "video/quicktime", ogv = "video/ogg", webm = "video/webm", mxu = "video/vnd.mpegurl", flv = "video/x-flv", lsf = "video/x-la-asf", lsx = "video/x-la-asf", mng = "video/x-mng", asf = "video/x-ms-asf", asx = "video/x-ms-asf", wm = "video/x-ms-wm", wmv = "video/x-ms-wmv", wmx = "video/x-ms-wmx", wvx = "video/x-ms-wvx", avi = "video/x-msvideo", movie = "video/x-sgi-movie", mpv = "video/x-matroska", mkv = "video/x-matroska", ice = "x-conference/x-cooltalk", sisx = "x-epoc/x-sisx-app", vrm = "x-world/x-vrml" ) mime/R/mime.R0000644000176200001440000001122413616322642012461 0ustar liggesusers#' @import utils NULL #' Tables for mapping filename extensions to MIME types #' #' The data \code{mimemap} is a named character vector that stores the filename #' extensions and the corresponding MIME types, e.g. \code{c(html = 'text/html', #' pdf = 'application/pdf', ...)}. The character vector \code{mimeextra} stores #' some additional types that we know, such as Markdown files (\file{.md}), or R #' scripts (\file{.R}). #' @docType data #' @name mimemap #' @source The file \file{/etc/mime.types} on Debian. #' @export #' @examples str(as.list(mimemap)) #' mimemap['pdf'] #' mimemap[c('html', 'js', 'css')] #' # additional MIME types (not exported) #' mime:::mimeextra local({ # the code is executed only when called from Rd2roxygen if (!('Rd2roxygen' %in% loadedNamespaces())) return() if (file.access('R/mimemap.R', 2) != 0) return() # do nothing if we are not under *nix; could read Windows registry, but who cares... if (!file.exists(mimefile <- '/etc/mime.types')) return() message('* Updating R/mimemap.R') lines = readLines(mimefile, warn = FALSE) # remove comments and blank lines lines = grep('^[a-z]', lines, value = TRUE) lines = unlist(lapply(strsplit(lines, '\\s+'), function(x) { # each line is of the form: type ext [ext2 ext3 ...] if (length(x) <= 1) return() # convert to c(html = 'text/html', js = 'application/javascript', ...) setNames(rep(x[1], length(x) - 1), x[-1]) }), recursive = FALSE) # remove duplicated file extensions lines = lines[!duplicated(names(lines))] names = names(lines) # write R source code to the data directory; "hand-writing" instead dump(), to # make sure we can easily catch possible future differences in version control writeLines(c( 'mimemap = c(', paste(sprintf( '%s = "%s"', # invalid names should be quoted using `` ifelse(make.names(names) == names, names, sprintf('`%s`', names)), lines ), collapse = ',\n'), ')' ), con = 'R/mimemap.R') }) #' @rdname mimemap #' @usage NULL #' @format NULL mimeextra = c( geojson = "application/vnd.geo+json", jsonp = "application/javascript", r = "text/plain", rd = "text/plain", rmd = "text/x-markdown", rnw = "text/x-sweave", rproj = "text/rstudio", yml = "text/yaml", scss = "text/css", NULL ) #' Guess the MIME types from filenames #' #' Look up in the \code{\link{mimemap}} table for the MIME types based on the #' extensions of the given filenames. #' @param file a character vector of filenames, or filename extensions #' @param unknown the MIME type to return when the file extension was not found #' in the table #' @param empty the MIME type for files that do not have extensions #' @param mime_extra a named character vector of the form \code{c(extension = #' type)} providing extra MIME types (by default, \code{\link{mimeextra}}); #' note this MIME table takes precedence over the standard table #' \code{\link{mimemap}} #' @param subtype a character vector of MIME subtypes, which should be of the #' same length as \code{file} if provided (use an empty character string for a #' file if we do not want a subtype for it) #' @examples #' library(mime) #' # well-known file types #' guess_type(c('a/b/c.html', 'd.pdf', 'e.odt', 'foo.docx', 'tex')) #' # not in the standard table, but in mimeextra #' guess_type(c('a.md', 'b.R'), mime_extra = NULL) #' guess_type(c('a.md', 'b.R')) #' #' # override the standard MIME table (tex is text/x-tex by default) #' guess_type('tex', mime_extra = c(tex = 'text/plain')) #' # unknown extension 'bar' #' guess_type('foo.bar') #' # force unknown types to be plain text #' guess_type('foo.bar', unknown = 'text/plain') #' #' # empty file extension #' guess_type('Makefile') #' # we know it is a plain text file #' guess_type('Makefile', empty = 'text/plain') #' #' # subtypes #' guess_type(c('abc.html', 'def.htm'), subtype = c('charset=UTF-8', '')) #' @export guess_type = function(file, unknown = 'application/octet-stream', empty = 'text/plain', mime_extra = mimeextra, subtype = '') { file = basename(file) # only need 'bar' from 'foo.bar' file = tools::file_ext(file) type = unname(c(mime_extra, mimemap)[tolower(file)]) type[file == ''] = empty type[is.na(type)] = unknown # unknown file extensions if (any(i <- subtype != '')) { if (length(type) != length(file)) stop("'subtype' must be of the same length as 'file'") type[i] = paste(type[i], subtype[i], sep = '; ') } type } if (.Platform$OS.type == 'windows') basename = function(path) { if (length(path) == 0) return(path) tryCatch(base::basename(path), error = function(e) { vapply(strsplit(path, '[\\/]+'), tail, character(1), 1, USE.NAMES = FALSE) }) } mime/R/parse.R0000644000176200001440000002100513355707537012654 0ustar liggesusers## Rook::Utils$parse() has a few problems: 1. it adds an extra \r\n to the file ## uploaded; 2. if there are multiple files uploaded, only the info about the ## last file is recorded. Besides, I did not escape non-file data, nor did I ## unescape the filenames. The former is not important to me at the moment, ## since the primary purpose of this function is for shiny IE8/9 file uploading; ## the latter is probably not important, either, since the users normally only ## want the content of the file(s) instead of the name(s). #' Parse multipart form data #' #' This function parses the HTML form data from a Rook environment (an HTTP POST #' request). #' @param env the HTTP request environment #' @return A named list containing the values of the form data, and the files #' uploaded are saved to temporary files (the temporary filenames are #' returned). It may also be \code{NULL} if there is anything unexpected in #' the form data, or the form is empty. #' @references This function was borrowed from #' \url{https://github.com/jeffreyhorner/Rook/} with slight modifications. #' @export #' @useDynLib mime, .registration = TRUE parse_multipart = function(env) { ctype = env$CONTENT_TYPE if (length(grep('^multipart', ctype)) == 0L) return() EOL = '\r\n' params = list() input = env$rook.input; input$rewind() content_length = as.integer(env$CONTENT_LENGTH) # some constants regarding boundaries boundary = gsub('^multipart/.*boundary="?([^";,]+)"?', '--\\1', ctype) bytesize = function(x) nchar(x, type = 'bytes') EOL_size = bytesize(EOL) EOL_raw = charToRaw(EOL) boundary_size = bytesize(boundary) boundaryEOL = paste(boundary, EOL, sep = '') boundaryEOL_size = boundary_size + bytesize(EOL) boundaryEOL_raw = charToRaw(boundaryEOL) EOLEOL = paste(EOL, EOL, sep = '') EOLEOL_size = bytesize(EOLEOL) EOLEOL_raw = charToRaw(EOLEOL) buf = new.env(parent = emptyenv()) buf$bufsize = 16384L # never read more than bufsize bytes (16K) buf$read_buffer = input$read(boundaryEOL_size) buf$read_buffer_len = length(buf$read_buffer) buf$unread = content_length - boundary_size if (!identical(boundaryEOL_raw, buf$read_buffer)) { warning('bad content body') input$rewind() return() } # read the smaller one of the unread content and the next chunk fill_buffer = function() { x = input$read(min(buf$bufsize, buf$unread)) n = length(x) if (n == 0L) return() buf$read_buffer = c(buf$read_buffer, x) buf$read_buffer_len = length(buf$read_buffer) buf$unread = buf$unread - n } # slices off the beginning part of read_buffer, e.g. i is the position of # EOLEOL, and size is EOLEOL_size, and read_buffer is [......EOLEOL+++], then # slice_buffer returns the the beginning [......], and turns read_buffer to # the remaining [+++] slice_buffer = function(i, size) { slice = buf$read_buffer[if (i > 1) 1:(i - 1) else 1] buf$read_buffer = if (size < buf$read_buffer_len) buf$read_buffer[(i + size):buf$read_buffer_len] else raw() buf$read_buffer_len = length(buf$read_buffer) slice } # prime the read_buffer buf$read_buffer = raw() fill_buffer() # find the position of the raw vector x1 in x2 raw_match = function(x1, x2) { if (is.character(x1)) x1 = charToRaw(x1) .Call('rawmatch', x1, x2, PACKAGE = 'mime') } unescape = function(x) { unlist(lapply(x, function(s) utils::URLdecode(chartr('+', ' ', s)))) } while (TRUE) { head = value = NULL filename = content_type = name = NULL while (is.null(head)) { i = raw_match(EOLEOL_raw, buf$read_buffer) if (length(i)) { head = slice_buffer(i, EOLEOL_size) break } else if (buf$unread) { fill_buffer() } else { break # we've read everything and still haven't seen a valid head } } if (is.null(head)) { warning('Bad post payload: searching for a header') input$rewind() return() } # cat('Head:',rawToChar(head),'\n') they're 8bit clean head = rawToChar(head) token = '[^\\s()<>,;:\\"\\/\\[\\]?=]+' condisp = sprintf('Content-Disposition:\\s*%s\\s*', token) dispparm = sprintf(';\\s*(%s)=("(?:\\"|[^"])*"|%s)*', token, token) rfc2183 = sprintf('(?m)^%s(%s)+$', condisp, dispparm) broken_quoted = sprintf( '(?m)^%s.*;\\sfilename="(.*?)"(?:\\s*$|\\s*;\\s*%s=)', condisp, token ) broken_unquoted = sprintf('(?m)^%s.*;\\sfilename=(%s)', condisp, token) if (length(grep(rfc2183, head, perl = TRUE))) { first_line = sub(condisp, '', strsplit(head, EOL)[[1L]][1], perl = TRUE) pairs = strsplit(first_line, ';', fixed = TRUE)[[1L]] fnmatch = '\\s*filename=(.*)\\s*' if (any(grepl(fnmatch, pairs, perl = TRUE))) { filename = pairs[grepl(fnmatch, pairs, perl = TRUE)][1] filename = gsub('"', '', sub(fnmatch, '\\1', filename, perl = TRUE)) } } else if (length(grep(broken_quoted, head, perl = TRUE))) { filename = sub( broken_quoted, '\\1', strsplit(head, '\r\n')[[1L]][1], perl = TRUE ) } else if (length(grep(broken_unquoted, head, perl = TRUE))) { filename = sub( broken_unquoted, '\\1', strsplit(head, '\r\n')[[1L]][1], perl = TRUE ) } # TODO: decoding filenames seems to be a mess here; skip it for now # if (!is.null(filename) && filename != '') { # filename = unescape(filename) # } headlines = strsplit(head, EOL, fixed = TRUE)[[1L]] content_type_re = '(?mi)Content-Type: (.*)' content_types = grep(content_type_re, headlines, perl = TRUE, value = TRUE) if (length(content_types)) { content_type = sub(content_type_re, '\\1', content_types[1], perl = TRUE) } name = sub( '(?si)Content-Disposition:.*\\s+name="?([^\";]*).*"?', '\\1', head, perl = TRUE ) while (TRUE) { i = raw_match(boundary, buf$read_buffer) if (length(i)) { value = slice_buffer(i, boundary_size) # strip off the extra EOL before the boundary if (identical(tail(value, EOL_size), EOL_raw)) value = head(value, -EOL_size) if (length(value)) { # drop EOL only values if (identical(value, EOL_raw)) break if (!is.null(filename) || !is.null(content_type)) { data = list() data$name = if (is.null(filename)) NA_character_ else filename data$size = length(value) data$type = if (is.null(content_type)) NA_character_ else content_type data$datapath = tempfile() con = file(data$datapath, open = 'wb') tryCatch(writeBin(value, con), finally = close(con)) params[[name]] = rbind(params[[name]], as.data.frame(data, stringsAsFactors = FALSE)) } else { len = length(value) # trim trailing EOL if (len > 2 && length(raw_match(EOL, value[(len - 1):len]))) len = len - 2 # handle array parameters (TODO: why Utils$escape?) paramValue = rawToChar(value[1:len]) paramSet = FALSE if (grepl('\\[\\]$', name)) { name = sub('\\[\\]$', '', name) if (name %in% names(params)) { params[[name]] = c(params[[name]], paramValue) paramSet = TRUE } } if (!paramSet) params[[name]] = paramValue } } break } else if (buf$unread) { fill_buffer() } else { break # we've read everything and still haven't seen a valid value } } if (is.null(value)) { # bad post payload input$rewind() warning('Bad post payload: searching for a body part') return(NULL) } # now search for ending markers or the beginning of another part while (buf$read_buffer_len < 2 && buf$unread) fill_buffer() if (buf$read_buffer_len < 2 && buf$unread == 0) { # bad stuff at the end; just return what we've got and presume everything # is okay input$rewind() return(params) } # valid ending if (length(raw_match('--', buf$read_buffer[1:2]))) { input$rewind() return(params) } # skip past the EOL. if (length(raw_match(EOL, buf$read_buffer[1:EOL_size]))) { slice_buffer(1, EOL_size) } else { warning('Bad post body: EOL not present') input$rewind() return(params) } # another sanity check before we try to parse another part if ((buf$read_buffer_len + buf$unread) < boundary_size) { warning('Bad post body: unknown trailing bytes') input$rewind() return(params) } } } mime/MD50000644000176200001440000000113513616332726011522 0ustar liggesusersd356104f75e6992c8dc13aa1d25a8f9d *DESCRIPTION 6c0844d0f403d7b8220f569b9abb1fe5 *NAMESPACE 81c8f92da1089b4b880e5f33f2d43af1 *NEWS 010b0ee725f9b853ec4298e8d26f54b1 *R/mime.R 83901de62e9c8b7776b492ef40d24e61 *R/mimemap.R 5ec980a6b02bfbea374050111fb47e45 *R/parse.R d9d67a9662e61c26a011cc1432fe8de0 *README.md 40d372ef8a7fc89eb4c81b57b265f0c6 *man/guess_type.Rd 20b9f8cad2d8ce501c9be8c44f09f744 *man/mimemap.Rd f8f83f528f8794764d58a8a57ebcf01e *man/parse_multipart.Rd 7ac2a343553fd78681382b578acfe057 *src/init.c 29b4222298101062679c7723a12f6f2d *src/rawmatch.c 7fe5cdfaa00ec7d6af8c44921cecb3ac *tests/mime.R