From 2ef8546864aa6b3d40f21e41ec93e7462e568546 Mon Sep 17 00:00:00 2001 From: Jacob Melton Date: Tue, 29 Sep 2015 20:59:59 -0400 Subject: [PATCH] Add basic MIME detection support --- upload.go | 25 +- util.go | 770 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 793 insertions(+), 2 deletions(-) diff --git a/upload.go b/upload.go index 8210a17..13e447a 100644 --- a/upload.go +++ b/upload.go @@ -1,6 +1,7 @@ package main import ( + "bytes" "encoding/json" "errors" "fmt" @@ -12,6 +13,7 @@ import ( "strconv" "strings" + "bitbucket.org/taruti/mimemagic" "github.com/zenazn/goji/web" ) @@ -122,12 +124,28 @@ func processUpload(upReq UploadRequest) (upload Upload, err error) { // Determine the appropriate filename, then write to disk barename, extension := barePlusExt(upReq.filename) + // Pull the first 512 bytes off for use in MIME detection if needed + header := make([]byte, 512) + _, err = upReq.src.Read(header) + if err != nil { + return + } + if upReq.randomBarename || len(barename) == 0 { barename = generateBarename() } if len(extension) == 0 { - extension = "ext" + // Determine the type of file from header + mimetype := mimemagic.Match("", header) + + // If the mime type is in our map, use that + // otherwise just use "ext" + if val, exists := mimeToExtension[mimetype]; exists { + extension = val + } else { + extension = "ext" + } } upload.Filename = strings.Join([]string{barename, extension}, ".") @@ -166,7 +184,10 @@ func processUpload(upReq UploadRequest) (upload Upload, err error) { metadataWrite(upload.Filename, &upload) - bytes, err := io.Copy(dst, upReq.src) + // Make a multi-reader from the header and the remainder of bytes + // in the upReq.src io.Reader + src := io.MultiReader(bytes.NewReader(header), upReq.src) + bytes, err := io.Copy(dst, src) if err != nil { return } else if bytes == 0 { diff --git a/util.go b/util.go index 2a43348..5f210af 100644 --- a/util.go +++ b/util.go @@ -8,6 +8,776 @@ import ( // from http://stackoverflow.com/a/31832326 var src = rand.NewSource(time.Now().UnixNano()) +var mimeToExtension = map[string]string{ + "application/andrew-inset": "ez", + "application/applixware": "aw", + "application/atom+xml": "atom", + "application/atomcat+xml": "atomcat", + "application/atomsvc+xml": "atomsvc", + "application/ccxml+xml": "ccxml", + "application/cdmi-capability": "cdmia", + "application/cdmi-container": "cdmic", + "application/cdmi-domain": "cdmid", + "application/cdmi-object": "cdmio", + "application/cdmi-queue": "cdmiq", + "application/cu-seeme": "cu", + "application/davmount+xml": "davmount", + "application/docbook+xml": "dbk", + "application/dssc+der": "dssc", + "application/dssc+xml": "xdssc", + "application/ecmascript": "ecma", + "application/emma+xml": "emma", + "application/epub+zip": "epub", + "application/exi": "exi", + "application/font-tdpfr": "pfr", + "application/gml+xml": "gml", + "application/gpx+xml": "gpx", + "application/gxf": "gxf", + "application/hyperstudio": "stk", + "application/inkml+xml": "ink inkml", + "application/ipfix": "ipfix", + "application/java-archive": "jar", + "application/java-serialized-object": "ser", + "application/java-vm": "class", + "application/javascript": "js", + "application/json": "json", + "application/jsonml+json": "jsonml", + "application/lost+xml": "lostxml", + "application/mac-binhex40": "hqx", + "application/mac-compactpro": "cpt", + "application/mads+xml": "mads", + "application/marc": "mrc", + "application/marcxml+xml": "mrcx", + "application/mathematica": "ma", + "application/mathml+xml": "mathml", + "application/mbox": "mbox", + "application/mediaservercontrol+xml": "mscml", + "application/metalink+xml": "metalink", + "application/metalink4+xml": "meta4", + "application/mets+xml": "mets", + "application/mods+xml": "mods", + "application/mp21": "mp21", + "application/mp4": "mp4s", + "application/msword": "doc", + "application/mxf": "mxf", + "application/octet-stream": "bin", + "application/oda": "oda", + "application/oebps-package+xml": "opf", + "application/ogg": "ogx", + "application/omdoc+xml": "omdoc", + "application/onenote": "onetoc", + "application/oxps": "oxps", + "application/patch-ops-error+xml": "xer", + "application/pdf": "pdf", + "application/pgp-encrypted": "pgp", + "application/pgp-signature": "asc", + "application/pics-rules": "prf", + "application/pkcs10": "p10", + "application/pkcs7-mime": "p7m", + "application/pkcs7-signature": "p7s", + "application/pkcs8": "p8", + "application/pkix-attr-cert": "ac", + "application/pkix-cert": "cer", + "application/pkix-crl": "crl", + "application/pkix-pkipath": "pkipath", + "application/pkixcmp": "pki", + "application/pls+xml": "pls", + "application/postscript": "ps", + "application/prs.cww": "cww", + "application/pskc+xml": "pskcxml", + "application/rdf+xml": "rdf", + "application/reginfo+xml": "rif", + "application/relax-ng-compact-syntax": "rnc", + "application/resource-lists+xml": "rl", + "application/resource-lists-diff+xml": "rld", + "application/rls-services+xml": "rs", + "application/rpki-ghostbusters": "gbr", + "application/rpki-manifest": "mft", + "application/rpki-roa": "roa", + "application/rsd+xml": "rsd", + "application/rss+xml": "rss", + "application/rtf": "rtf", + "application/sbml+xml": "sbml", + "application/scvp-cv-request": "scq", + "application/scvp-cv-response": "scs", + "application/scvp-vp-request": "spq", + "application/scvp-vp-response": "spp", + "application/sdp": "sdp", + "application/set-payment-initiation": "setpay", + "application/set-registration-initiation": "setreg", + "application/shf+xml": "shf", + "application/smil+xml": "smil", + "application/sparql-query": "rq", + "application/sparql-results+xml": "srx", + "application/srgs": "gram", + "application/srgs+xml": "grxml", + "application/sru+xml": "sru", + "application/ssdl+xml": "ssdl", + "application/ssml+xml": "ssml", + "application/tei+xml": "tei", + "application/thraud+xml": "tfi", + "application/timestamped-data": "tsd", + "application/vnd.3gpp.pic-bw-large": "plb", + "application/vnd.3gpp.pic-bw-small": "psb", + "application/vnd.3gpp.pic-bw-var": "pvb", + "application/vnd.3gpp2.tcap": "tcap", + "application/vnd.3m.post-it-notes": "pwn", + "application/vnd.accpac.simply.aso": "aso", + "application/vnd.accpac.simply.imp": "imp", + "application/vnd.acucobol": "acu", + "application/vnd.acucorp": "atc acutc", + "application/vnd.adobe.air-application-installer-package+zip": "air", + "application/vnd.adobe.formscentral.fcdt": "fcdt", + "application/vnd.adobe.fxp": "fxp", + "application/vnd.adobe.xdp+xml": "xdp", + "application/vnd.adobe.xfdf": "xfdf", + "application/vnd.ahead.space": "ahead", + "application/vnd.airzip.filesecure.azf": "azf", + "application/vnd.airzip.filesecure.azs": "azs", + "application/vnd.amazon.ebook": "azw", + "application/vnd.americandynamics.acc": "acc", + "application/vnd.amiga.ami": "ami", + "application/vnd.android.package-archive": "apk", + "application/vnd.anser-web-certificate-issue-initiation": "cii", + "application/vnd.anser-web-funds-transfer-initiation": "fti", + "application/vnd.antix.game-component": "atx", + "application/vnd.apple.installer+xml": "mpkg", + "application/vnd.apple.mpegurl": "m3u8", + "application/vnd.aristanetworks.swi": "swi", + "application/vnd.astraea-software.iota": "iota", + "application/vnd.audiograph": "aep", + "application/vnd.blueice.multipass": "mpm", + "application/vnd.bmi": "bmi", + "application/vnd.businessobjects": "rep", + "application/vnd.chemdraw+xml": "cdxml", + "application/vnd.chipnuts.karaoke-mmd": "mmd", + "application/vnd.cinderella": "cdy", + "application/vnd.claymore": "cla", + "application/vnd.cloanto.rp9": "rp9", + "application/vnd.clonk.c4group": "c4g", + "application/vnd.cluetrust.cartomobile-config": "c11amc", + "application/vnd.cluetrust.cartomobile-config-pkg": "c11amz", + "application/vnd.commonspace": "csp", + "application/vnd.contact.cmsg": "cdbcmsg", + "application/vnd.cosmocaller": "cmc", + "application/vnd.crick.clicker": "clkx", + "application/vnd.crick.clicker.keyboard": "clkk", + "application/vnd.crick.clicker.palette": "clkp", + "application/vnd.crick.clicker.template": "clkt", + "application/vnd.crick.clicker.wordbank": "clkw", + "application/vnd.criticaltools.wbs+xml": "wbs", + "application/vnd.ctc-posml": "pml", + "application/vnd.cups-ppd": "ppd", + "application/vnd.curl.car": "car", + "application/vnd.curl.pcurl": "pcurl", + "application/vnd.dart": "dart", + "application/vnd.data-vision.rdz": "rdz", + "application/vnd.dece.data": "uvf", + "application/vnd.dece.ttml+xml": "uvt", + "application/vnd.dece.unspecified": "uvx", + "application/vnd.dece.zip": "uvz", + "application/vnd.denovo.fcselayout-link": "fe_launch", + "application/vnd.dna": "dna", + "application/vnd.dolby.mlp": "mlp", + "application/vnd.dpgraph": "dpg", + "application/vnd.dreamfactory": "dfac", + "application/vnd.ds-keypoint": "kpxx", + "application/vnd.dvb.ait": "ait", + "application/vnd.dvb.service": "svc", + "application/vnd.dynageo": "geo", + "application/vnd.ecowin.chart": "mag", + "application/vnd.enliven": "nml", + "application/vnd.epson.esf": "esf", + "application/vnd.epson.msf": "msf", + "application/vnd.epson.quickanime": "qam", + "application/vnd.epson.salt": "slt", + "application/vnd.epson.ssf": "ssf", + "application/vnd.eszigno3+xml": "es3", + "application/vnd.ezpix-album": "ez2", + "application/vnd.ezpix-package": "ez3", + "application/vnd.fdf": "fdf", + "application/vnd.fdsn.mseed": "mseed", + "application/vnd.fdsn.seed": "seed", + "application/vnd.flographit": "gph", + "application/vnd.fluxtime.clip": "ftc", + "application/vnd.framemaker": "fm", + "application/vnd.frogans.fnc": "fnc", + "application/vnd.frogans.ltf": "ltf", + "application/vnd.fsc.weblaunch": "fsc", + "application/vnd.fujitsu.oasys": "oas", + "application/vnd.fujitsu.oasys2": "oa2", + "application/vnd.fujitsu.oasys3": "oa3", + "application/vnd.fujitsu.oasysgp": "fg5", + "application/vnd.fujitsu.oasysprs": "bh2", + "application/vnd.fujixerox.ddd": "ddd", + "application/vnd.fujixerox.docuworks": "xdw", + "application/vnd.fujixerox.docuworks.binder": "xbd", + "application/vnd.fuzzysheet": "fzs", + "application/vnd.genomatix.tuxedo": "txd", + "application/vnd.geogebra.file": "ggb", + "application/vnd.geogebra.tool": "ggt", + "application/vnd.geometry-explorer": "gex gre", + "application/vnd.geonext": "gxt", + "application/vnd.geoplan": "g2w", + "application/vnd.geospace": "g3w", + "application/vnd.gmx": "gmx", + "application/vnd.google-earth.kml+xml": "kml", + "application/vnd.google-earth.kmz": "kmz", + "application/vnd.grafeq": "gqf gqs", + "application/vnd.groove-account": "gac", + "application/vnd.groove-help": "ghf", + "application/vnd.groove-identity-message": "gim", + "application/vnd.groove-injector": "grv", + "application/vnd.groove-tool-message": "gtm", + "application/vnd.groove-tool-template": "tpl", + "application/vnd.groove-vcard": "vcg", + "application/vnd.hal+xml": "hal", + "application/vnd.handheld-entertainment+xml": "zmm", + "application/vnd.hbci": "hbci", + "application/vnd.hhe.lesson-player": "les", + "application/vnd.hp-hpgl": "hpgl", + "application/vnd.hp-hpid": "hpid", + "application/vnd.hp-hps": "hps", + "application/vnd.hp-jlyt": "jlt", + "application/vnd.hp-pcl": "pcl", + "application/vnd.hp-pclxl": "pclxl", + "application/vnd.hydrostatix.sof-data": "sfd-hdstx", + "application/vnd.ibm.minipay": "mpy", + "application/vnd.ibm.modcap": "afp", + "application/vnd.ibm.rights-management": "irm", + "application/vnd.ibm.secure-container": "sc", + "application/vnd.iccprofile": "icc icm", + "application/vnd.igloader": "igl", + "application/vnd.immervision-ivp": "ivp", + "application/vnd.immervision-ivu": "ivu", + "application/vnd.insors.igm": "igm", + "application/vnd.intercon.formnet": "xpw", + "application/vnd.intergeo": "i2g", + "application/vnd.intu.qbo": "qbo", + "application/vnd.intu.qfx": "qfx", + "application/vnd.ipunplugged.rcprofile": "rcprofile", + "application/vnd.irepository.package+xml": "irp", + "application/vnd.is-xpr": "xpr", + "application/vnd.isac.fcs": "fcs", + "application/vnd.jam": "jam", + "application/vnd.jcp.javame.midlet-rms": "rms", + "application/vnd.jisp": "jisp", + "application/vnd.joost.joda-archive": "joda", + "application/vnd.kahootz": "ktz", + "application/vnd.kde.karbon": "karbon", + "application/vnd.kde.kchart": "chrt", + "application/vnd.kde.kformula": "kfo", + "application/vnd.kde.kivio": "flw", + "application/vnd.kde.kontour": "kon", + "application/vnd.kde.kpresenter": "kpr", + "application/vnd.kde.kspread": "ksp", + "application/vnd.kde.kword": "kwd", + "application/vnd.kenameaapp": "htke", + "application/vnd.kidspiration": "kia", + "application/vnd.kinar": "kne knp", + "application/vnd.koan": "skp", + "application/vnd.kodak-descriptor": "sse", + "application/vnd.las.las+xml": "lasxml", + "application/vnd.llamagraphics.life-balance.desktop": "lbd", + "application/vnd.llamagraphics.life-balance.exchange+xml": "lbe", + "application/vnd.lotus-1-2-3": "123", + "application/vnd.lotus-approach": "apr", + "application/vnd.lotus-freelance": "pre", + "application/vnd.lotus-notes": "nsf", + "application/vnd.lotus-organizer": "org", + "application/vnd.lotus-screencam": "scm", + "application/vnd.lotus-wordpro": "lwp", + "application/vnd.macports.portpkg": "portpkg", + "application/vnd.mcd": "mcd", + "application/vnd.medcalcdata": "mc1", + "application/vnd.mediastation.cdkey": "cdkey", + "application/vnd.mfer": "mwf", + "application/vnd.mfmp": "mfm", + "application/vnd.micrografx.flo": "flo", + "application/vnd.micrografx.igx": "igx", + "application/vnd.mif": "mif", + "application/vnd.mobius.daf": "daf", + "application/vnd.mobius.dis": "dis", + "application/vnd.mobius.mbk": "mbk", + "application/vnd.mobius.mqy": "mqy", + "application/vnd.mobius.msl": "msl", + "application/vnd.mobius.plc": "plc", + "application/vnd.mobius.txf": "txf", + "application/vnd.mophun.application": "mpn", + "application/vnd.mophun.certificate": "mpc", + "application/vnd.mozilla.xul+xml": "xul", + "application/vnd.ms-artgalry": "cil", + "application/vnd.ms-cab-compressed": "cab", + "application/vnd.ms-excel": "xls", + "application/vnd.ms-excel.addin.macroenabled.12": "xlam", + "application/vnd.ms-excel.sheet.binary.macroenabled.12": "xlsb", + "application/vnd.ms-excel.sheet.macroenabled.12": "xlsm", + "application/vnd.ms-excel.template.macroenabled.12": "xltm", + "application/vnd.ms-fontobject": "eot", + "application/vnd.ms-htmlhelp": "chm", + "application/vnd.ms-ims": "ims", + "application/vnd.ms-lrm": "lrm", + "application/vnd.ms-officetheme": "thmx", + "application/vnd.ms-pki.seccat": "cat", + "application/vnd.ms-pki.stl": "stl", + "application/vnd.ms-powerpoint": "ppt pps pot", + "application/vnd.ms-powerpoint.addin.macroenabled.12": "ppam", + "application/vnd.ms-powerpoint.presentation.macroenabled.12": "pptm", + "application/vnd.ms-powerpoint.slide.macroenabled.12": "sldm", + "application/vnd.ms-powerpoint.slideshow.macroenabled.12": "ppsm", + "application/vnd.ms-powerpoint.template.macroenabled.12": "potm", + "application/vnd.ms-project": "mpp mpt", + "application/vnd.ms-word.document.macroenabled.12": "docm", + "application/vnd.ms-word.template.macroenabled.12": "dotm", + "application/vnd.ms-works": "wps", + "application/vnd.ms-wpl": "wpl", + "application/vnd.ms-xpsdocument": "xps", + "application/vnd.mseq": "mseq", + "application/vnd.musician": "mus", + "application/vnd.muvee.style": "msty", + "application/vnd.mynfc": "taglet", + "application/vnd.neurolanguage.nlu": "nlu", + "application/vnd.nitf": "ntf nitf", + "application/vnd.noblenet-directory": "nnd", + "application/vnd.noblenet-sealer": "nns", + "application/vnd.noblenet-web": "nnw", + "application/vnd.nokia.n-gage.data": "ngdat", + "application/vnd.nokia.n-gage.symbian.install": "n-gage", + "application/vnd.nokia.radio-preset": "rpst", + "application/vnd.nokia.radio-presets": "rpss", + "application/vnd.novadigm.edm": "edm", + "application/vnd.novadigm.edx": "edx", + "application/vnd.novadigm.ext": "ext", + "application/vnd.oasis.opendocument.chart": "odc", + "application/vnd.oasis.opendocument.chart-template": "otc", + "application/vnd.oasis.opendocument.database": "odb", + "application/vnd.oasis.opendocument.formula": "odf", + "application/vnd.oasis.opendocument.formula-template": "odft", + "application/vnd.oasis.opendocument.graphics": "odg", + "application/vnd.oasis.opendocument.graphics-template": "otg", + "application/vnd.oasis.opendocument.image": "odi", + "application/vnd.oasis.opendocument.image-template": "oti", + "application/vnd.oasis.opendocument.presentation": "odp", + "application/vnd.oasis.opendocument.presentation-template": "otp", + "application/vnd.oasis.opendocument.spreadsheet": "ods", + "application/vnd.oasis.opendocument.spreadsheet-template": "ots", + "application/vnd.oasis.opendocument.text": "odt", + "application/vnd.oasis.opendocument.text-master": "odm", + "application/vnd.oasis.opendocument.text-template": "ott", + "application/vnd.oasis.opendocument.text-web": "oth", + "application/vnd.olpc-sugar": "xo", + "application/vnd.oma.dd2+xml": "dd2", + "application/vnd.openofficeorg.extension": "oxt", + "application/vnd.openxmlformats-officedocument.presentationml.presentation": "pptx", + "application/vnd.openxmlformats-officedocument.presentationml.slide": "sldx", + "application/vnd.openxmlformats-officedocument.presentationml.slideshow": "ppsx", + "application/vnd.openxmlformats-officedocument.presentationml.template": "potx", + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "xlsx", + "application/vnd.openxmlformats-officedocument.spreadsheetml.template": "xltx", + "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "docx", + "application/vnd.openxmlformats-officedocument.wordprocessingml.template": "dotx", + "application/vnd.osgeo.mapguide.package": "mgp", + "application/vnd.osgi.dp": "dp", + "application/vnd.osgi.subsystem": "esa", + "application/vnd.palm": "pdb pqa oprc", + "application/vnd.pawaafile": "paw", + "application/vnd.pg.format": "str", + "application/vnd.pg.osasli": "ei6", + "application/vnd.picsel": "efif", + "application/vnd.pmi.widget": "wg", + "application/vnd.pocketlearn": "plf", + "application/vnd.powerbuilder6": "pbd", + "application/vnd.previewsystems.box": "box", + "application/vnd.proteus.magazine": "mgz", + "application/vnd.publishare-delta-tree": "qps", + "application/vnd.pvi.ptid1": "ptid", + "application/vnd.quark.quarkxpress": "qxd", + "application/vnd.realvnc.bed": "bed", + "application/vnd.recordare.musicxml": "mxl", + "application/vnd.recordare.musicxml+xml": "musicxml", + "application/vnd.rig.cryptonote": "cryptonote", + "application/vnd.rim.cod": "cod", + "application/vnd.rn-realmedia": "rm", + "application/vnd.rn-realmedia-vbr": "rmvb", + "application/vnd.route66.link66+xml": "link66", + "application/vnd.sailingtracker.track": "st", + "application/vnd.seemail": "see", + "application/vnd.sema": "sema", + "application/vnd.semd": "semd", + "application/vnd.semf": "semf", + "application/vnd.shana.informed.formdata": "ifm", + "application/vnd.shana.informed.formtemplate": "itp", + "application/vnd.shana.informed.interchange": "iif", + "application/vnd.shana.informed.package": "ipk", + "application/vnd.simtech-mindmapper": "twd", + "application/vnd.smaf": "mmf", + "application/vnd.smart.teacher": "teacher", + "application/vnd.solent.sdkm+xml": "sdkm", + "application/vnd.spotfire.dxp": "dxp", + "application/vnd.spotfire.sfs": "sfs", + "application/vnd.stardivision.calc": "sdc", + "application/vnd.stardivision.draw": "sda", + "application/vnd.stardivision.impress": "sdd", + "application/vnd.stardivision.math": "smf", + "application/vnd.stardivision.writer": "sdw", + "application/vnd.stardivision.writer-global": "sgl", + "application/vnd.stepmania.package": "smzip", + "application/vnd.stepmania.stepchart": "sm", + "application/vnd.sun.xml.calc": "sxc", + "application/vnd.sun.xml.calc.template": "stc", + "application/vnd.sun.xml.draw": "sxd", + "application/vnd.sun.xml.draw.template": "std", + "application/vnd.sun.xml.impress": "sxi", + "application/vnd.sun.xml.impress.template": "sti", + "application/vnd.sun.xml.math": "sxm", + "application/vnd.sun.xml.writer": "sxw", + "application/vnd.sun.xml.writer.global": "sxg", + "application/vnd.sun.xml.writer.template": "stw", + "application/vnd.sus-calendar": "sus", + "application/vnd.svd": "svd", + "application/vnd.symbian.install": "sis", + "application/vnd.syncml+xml": "xsm", + "application/vnd.syncml.dm+wbxml": "bdm", + "application/vnd.syncml.dm+xml": "xdm", + "application/vnd.tao.intent-module-archive": "tao", + "application/vnd.tcpdump.pcap": "pcap", + "application/vnd.tmobile-livetv": "tmo", + "application/vnd.trid.tpt": "tpt", + "application/vnd.triscape.mxs": "mxs", + "application/vnd.trueapp": "tra", + "application/vnd.ufdl": "ufdl", + "application/vnd.uiq.theme": "utz", + "application/vnd.umajin": "umj", + "application/vnd.unity": "unityweb", + "application/vnd.uoml+xml": "uoml", + "application/vnd.vcx": "vcx", + "application/vnd.visio": "vsd", + "application/vnd.visionary": "vis", + "application/vnd.vsf": "vsf", + "application/vnd.wap.wbxml": "wbxml", + "application/vnd.wap.wmlc": "wmlc", + "application/vnd.wap.wmlscriptc": "wmlsc", + "application/vnd.webturbo": "wtb", + "application/vnd.wolfram.player": "nbp", + "application/vnd.wordperfect": "wpd", + "application/vnd.wqd": "wqd", + "application/vnd.wt.stf": "stf", + "application/vnd.xara": "xar", + "application/vnd.xfdl": "xfdl", + "application/vnd.yamaha.hv-dic": "hvd", + "application/vnd.yamaha.hv-script": "hvs", + "application/vnd.yamaha.hv-voice": "hvp", + "application/vnd.yamaha.openscoreformat": "osf", + "application/vnd.yamaha.openscoreformat.osfpvg+xml": "osfpvg", + "application/vnd.yamaha.smaf-audio": "saf", + "application/vnd.yamaha.smaf-phrase": "spf", + "application/vnd.yellowriver-custom-menu": "cmp", + "application/vnd.zul": "zir", + "application/vnd.zzazz.deck+xml": "zaz", + "application/voicexml+xml": "vxml", + "application/widget": "wgt", + "application/winhlp": "hlp", + "application/wsdl+xml": "wsdl", + "application/wspolicy+xml": "wspolicy", + "application/x-7z-compressed": "7z", + "application/x-abiword": "abw", + "application/x-ace-compressed": "ace", + "application/x-apple-diskimage": "dmg", + "application/x-authorware-bin": "aab", + "application/x-authorware-map": "aam", + "application/x-authorware-seg": "aas", + "application/x-bcpio": "bcpio", + "application/x-bittorrent": "torrent", + "application/x-blorb": "blb", + "application/x-bzip": "bz", + "application/x-bzip2": "bz2", + "application/x-cbr": "cbr", + "application/x-cdlink": "vcd", + "application/x-cfs-compressed": "cfs", + "application/x-chat": "chat", + "application/x-chess-pgn": "pgn", + "application/x-conference": "nsc", + "application/x-cpio": "cpio", + "application/x-csh": "csh", + "application/x-debian-package": "deb", + "application/x-dgc-compressed": "dgc", + "application/x-director": "dir", + "application/x-doom": "wad", + "application/x-dtbncx+xml": "ncx", + "application/x-dtbook+xml": "dtb", + "application/x-dtbresource+xml": "res", + "application/x-dvi": "dvi", + "application/x-envoy": "evy", + "application/x-eva": "eva", + "application/x-font-bdf": "bdf", + "application/x-font-ghostscript": "gsf", + "application/x-font-linux-psf": "psf", + "application/x-font-otf": "otf", + "application/x-font-pcf": "pcf", + "application/x-font-snf": "snf", + "application/x-font-ttf": "ttf", + "application/x-font-type1": "pfa", + "application/x-font-woff": "woff", + "application/x-freearc": "arc", + "application/x-futuresplash": "spl", + "application/x-gca-compressed": "gca", + "application/x-glulx": "ulx", + "application/x-gnumeric": "gnumeric", + "application/x-gramps-xml": "gramps", + "application/x-gtar": "gtar", + "application/x-hdf": "hdf", + "application/x-install-instructions": "install", + "application/x-iso9660-image": "iso", + "application/x-java-jnlp-file": "jnlp", + "application/x-latex": "latex", + "application/x-lzh-compressed": "lzh", + "application/x-mie": "mie", + "application/x-mobipocket-ebook": "prc", + "application/x-ms-application": "application", + "application/x-ms-shortcut": "lnk", + "application/x-ms-wmd": "wmd", + "application/x-ms-wmz": "wmz", + "application/x-ms-xbap": "xbap", + "application/x-msaccess": "mdb", + "application/x-msbinder": "obd", + "application/x-mscardfile": "crd", + "application/x-msclip": "clp", + "application/x-msdownload": "exe", + "application/x-msmediaview": "mvb", + "application/x-msmetafile": "wmf", + "application/x-msmoney": "mny", + "application/x-mspublisher": "pub", + "application/x-msschedule": "scd", + "application/x-msterminal": "trm", + "application/x-mswrite": "wri", + "application/x-netcdf": "nc", + "application/x-nzb": "nzb", + "application/x-pkcs12": "p12", + "application/x-pkcs7-certificates": "p7b", + "application/x-pkcs7-certreqresp": "p7r", + "application/x-rar-compressed": "rar", + "application/x-research-info-systems": "ris", + "application/x-sh": "sh", + "application/x-shar": "shar", + "application/x-shockwave-flash": "swf", + "application/x-silverlight-app": "xap", + "application/x-sql": "sql", + "application/x-stuffit": "sit", + "application/x-stuffitx": "sitx", + "application/x-subrip": "srt", + "application/x-sv4cpio": "sv4cpio", + "application/x-sv4crc": "sv4crc", + "application/x-t3vm-image": "t3", + "application/x-tads": "gam", + "application/x-tar": "tar", + "application/x-tcl": "tcl", + "application/x-tex": "tex", + "application/x-tex-tfm": "tfm", + "application/x-texinfo": "texinfo", + "application/x-tgif": "obj", + "application/x-ustar": "ustar", + "application/x-wais-source": "src", + "application/x-x509-ca-cert": "der", + "application/x-xfig": "fig", + "application/x-xliff+xml": "xlf", + "application/x-xpinstall": "xpi", + "application/x-xz": "xz", + "application/x-zmachine": "z1", + "application/xaml+xml": "xaml", + "application/xcap-diff+xml": "xdf", + "application/xenc+xml": "xenc", + "application/xhtml+xml": "xhtml", + "application/xml": "xml", + "application/xml-dtd": "dtd", + "application/xop+xml": "xop", + "application/xproc+xml": "xpl", + "application/xslt+xml": "xslt", + "application/xspf+xml": "xspf", + "application/xv+xml": "mxml", + "application/yang": "yang", + "application/yin+xml": "yin", + "application/zip": "zip", + "audio/adpcm": "adp", + "audio/basic": "au", + "audio/midi": "mid", + "audio/mp4": "mp4a", + "audio/mpeg": "mpga", + "audio/ogg": "oga", + "audio/s3m": "s3m", + "audio/silk": "sil", + "audio/vnd.dece.audio": "uva", + "audio/vnd.digital-winds": "eol", + "audio/vnd.dra": "dra", + "audio/vnd.dts": "dts", + "audio/vnd.dts.hd": "dtshd", + "audio/vnd.lucent.voice": "lvp", + "audio/vnd.ms-playready.media.pya": "pya", + "audio/vnd.nuera.ecelp4800": "ecelp4800", + "audio/vnd.nuera.ecelp7470": "ecelp7470", + "audio/vnd.nuera.ecelp9600": "ecelp9600", + "audio/vnd.rip": "rip", + "audio/webm": "weba", + "audio/x-aac": "aac", + "audio/x-aiff": "aif", + "audio/x-caf": "caf", + "audio/x-flac": "flac", + "audio/x-matroska": "mka", + "audio/x-mpegurl": "m3u", + "audio/x-ms-wax": "wax", + "audio/x-ms-wma": "wma", + "audio/x-pn-realaudio": "ram", + "audio/x-pn-realaudio-plugin": "rmp", + "audio/x-wav": "wav", + "audio/xm": "xm", + "chemical/x-cdx": "cdx", + "chemical/x-cif": "cif", + "chemical/x-cmdf": "cmdf", + "chemical/x-cml": "cml", + "chemical/x-csml": "csml", + "chemical/x-xyz": "xyz", + "image/bmp": "bmp", + "image/cgm": "cgm", + "image/g3fax": "g3", + "image/gif": "gif", + "image/ief": "ief", + "image/jpeg": "jpeg", + "image/ktx": "ktx", + "image/png": "png", + "image/prs.btif": "btif", + "image/sgi": "sgi", + "image/svg+xml": "svg svgz", + "image/tiff": "tiff tif", + "image/vnd.adobe.photoshop": "psd", + "image/vnd.dece.graphic": "uvi", + "image/vnd.dvb.subtitle": "sub", + "image/vnd.djvu": "djvu", + "image/vnd.dwg": "dwg", + "image/vnd.dxf": "dxf", + "image/vnd.fastbidsheet": "fbs", + "image/vnd.fpx": "fpx", + "image/vnd.fst": "fst", + "image/vnd.fujixerox.edmics-mmr": "mmr", + "image/vnd.fujixerox.edmics-rlc": "rlc", + "image/vnd.ms-modi": "mdi", + "image/vnd.ms-photo": "wdp", + "image/vnd.net-fpx": "npx", + "image/vnd.wap.wbmp": "wbmp", + "image/vnd.xiff": "xif", + "image/webp": "webp", + "image/x-3ds": "3ds", + "image/x-cmu-raster": "ras", + "image/x-cmx": "cmx", + "image/x-freehand": "fh", + "image/x-icon": "ico", + "image/x-mrsid-image": "sid", + "image/x-pcx": "pcx", + "image/x-pict": "pic", + "image/x-portable-anymap": "pnm", + "image/x-portable-bitmap": "pbm", + "image/x-portable-graymap": "pgm", + "image/x-portable-pixmap": "ppm", + "image/x-rgb": "rgb", + "image/x-tga": "tga", + "image/x-xbitmap": "xbm", + "image/x-xpixmap": "xpm", + "image/x-xwindowdump": "xwd", + "message/rfc822": "eml mime", + "model/iges": "igs", + "model/mesh": "mesh", + "model/vnd.collada+xml": "dae", + "model/vnd.dwf": "dwf", + "model/vnd.gdl": "gdl", + "model/vnd.gtw": "gtw", + "model/vnd.mts": "mts", + "model/vnd.vtu": "vtu", + "model/vrml": "wrl vrml", + "model/x3d+binary": "x3db", + "model/x3d+vrml": "x3dv", + "model/x3d+xml": "x3d", + "text/cache-manifest": "appcache", + "text/calendar": "ics ifb", + "text/css": "css", + "text/csv": "csv", + "text/html": "html", + "text/n3": "n3", + "text/plain": "txt", + "text/prs.lines.tag": "dsc", + "text/richtext": "rtx", + "text/sgml": "sgml sgm", + "text/tab-separated-values": "tsv", + "text/troff": "t", + "text/turtle": "ttl", + "text/uri-list": "uri", + "text/vcard": "vcard", + "text/vnd.curl": "curl", + "text/vnd.curl.dcurl": "dcurl", + "text/vnd.curl.scurl": "scurl", + "text/vnd.curl.mcurl": "mcurl", + "text/vnd.dvb.subtitle": "sub", + "text/vnd.fly": "fly", + "text/vnd.fmi.flexstor": "flx", + "text/vnd.graphviz": "gv", + "text/vnd.in3d.3dml": "3dml", + "text/vnd.in3d.spot": "spot", + "text/vnd.sun.j2me.app-descriptor": "jad", + "text/vnd.wap.wml": "wml", + "text/vnd.wap.wmlscript": "wmls", + "text/x-asm": "s asm", + "text/x-c": "c", + "text/x-fortran": "f", + "text/x-java-source": "java", + "text/x-opml": "opml", + "text/x-pascal": "p pas", + "text/x-nfo": "nfo", + "text/x-shellscript": "sh", + "text/x-setext": "etx", + "text/x-sfv": "sfv", + "text/x-tex": "tex", + "text/x-uuencode": "uu", + "text/x-vcalendar": "vcs", + "text/x-vcard": "vcf", + "video/3gpp": "3gp", + "video/3gpp2": "3g2", + "video/h261": "h261", + "video/h263": "h263", + "video/h264": "h264", + "video/jpeg": "jpgv", + "video/jpm": "jpm", + "video/mj2": "mj2", + "video/mp4": "mp4", + "video/mpeg": "mpeg", + "video/ogg": "ogv", + "video/quicktime": "qt", + "video/vnd.dece.hd": "uvh", + "video/vnd.dece.mobile": "uvm", + "video/vnd.dece.pd": "uvp", + "video/vnd.dece.sd": "uvs", + "video/vnd.dece.video": "uvv", + "video/vnd.dvb.file": "dvb", + "video/vnd.fvt": "fvt", + "video/vnd.mpegurl": "m4u", + "video/vnd.ms-playready.media.pyv": "pyv", + "video/vnd.uvvu.mp4": "uvvu", + "video/vnd.vivo": "viv", + "video/webm": "webm", + "video/x-f4v": "f4v", + "video/x-fli": "fli", + "video/x-flv": "flv", + "video/x-m4v": "m4v", + "video/x-matroska": "mkv", + "video/x-mng": "mng", + "video/x-ms-asf": "asf", + "video/x-ms-vob": "vob", + "video/x-ms-wm": "wm", + "video/x-ms-wmv": "wmv", + "video/x-ms-wmx": "wmx", + "video/x-ms-wvx": "wvx", + "video/x-msvideo": "avi", + "video/x-sgi-movie": "movie", + "video/x-smv": "smv", + "x-conference/x-cooltalk": "ice", +} + const letterBytes = "abcdefghijklmnopqrstuvwxyz1234567890" const ( letterIdxBits = 6 // 6 bits to represent a letter index