├── .npmrc ├── CONTRIBUTING.md ├── .github ├── PULL_REQUEST_TEMPLATE.md └── ISSUE_TEMPLATE.md ├── .coveralls.yml ├── test ├── .eslintrc.json ├── browser │ ├── http1.test.js │ ├── http2.test.js │ └── main.js ├── node │ ├── http1.test.js │ ├── sync.test.js │ ├── http2.test.js │ ├── util.test.js │ ├── main.js │ └── file.test.disabled ├── interop.js ├── server.js └── main.js ├── .gitignore ├── .npmignore ├── webpack.config.js ├── .travis.yml ├── sync.js ├── src ├── node │ ├── mime.js │ ├── FormData.js │ ├── socket.js │ ├── index.js │ ├── mimeOfBuffer.js │ └── mimes.json ├── browser │ └── index.js ├── index.mjs └── index.js ├── scripts ├── travis-test.sh └── travis-deploy.sh ├── LICENSE ├── docs.js ├── .eslintrc.js ├── README.md ├── package.json ├── CODE_OF_CONDUCT.md └── CHANGELOG.md /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | don't break stuff when you pr 2 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | if your pr is about typescript go away 2 | -------------------------------------------------------------------------------- /.coveralls.yml: -------------------------------------------------------------------------------- 1 | repo_token: uobmSN68zkCLG1IaQm9zm9ZcSPlZYk74b 2 | service_name: travis-pro 3 | -------------------------------------------------------------------------------- /test/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../.eslintrc.js"], 3 | "env": { "jest": true } 4 | } 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | docs 3 | .cache 4 | coverage 5 | browser.js 6 | sonar-project.properties 7 | .scannerwork 8 | .eslintcache 9 | -------------------------------------------------------------------------------- /test/browser/http1.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * @jest-environment jsdom 5 | */ 6 | 7 | global.HTTP_VERSION = 1; 8 | 9 | require('./main'); 10 | -------------------------------------------------------------------------------- /test/browser/http2.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * @jest-environment jsdom 5 | */ 6 | 7 | global.HTTP_VERSION = 2; 8 | 9 | require('./main'); 10 | -------------------------------------------------------------------------------- /test/node/http1.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment node 3 | */ 4 | 5 | 'use strict'; 6 | 7 | global.HTTP_VERSION = 1; 8 | 9 | require('./main'); 10 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | docs 3 | .cache 4 | coverage 5 | sonar-project.properties 6 | .scannerwork 7 | test 8 | .github 9 | scripts 10 | webpack.config.js 11 | docs.js 12 | .eslintrc.js 13 | .coveralls.yml 14 | .travis.yml 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Version or commit hash: 2 | 3 | 4 | ## Explanation of issue: 5 | 6 | 7 | ## Example code to reproduce: 8 | ```js 9 | // code here 10 | ``` 11 | 12 | - [ ] Issue occurs in browser 13 | - [ ] Issue occurs in node 14 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | mode: 'production', 5 | entry: require.resolve('.'), 6 | output: { 7 | path: __dirname, 8 | filename: 'browser.js', 9 | library: 'Snekfetch', 10 | libraryTarget: 'umd', 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /test/interop.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.Snekfetch = require('../'); 4 | 5 | try { 6 | exports.SnekfetchSync = require('../sync'); 7 | } catch (err) {} // eslint-disable-line no-empty 8 | 9 | exports.TestRoot = global.HTTP_VERSION === 2 ? 10 | 'https://nghttp2.org/httpbin' : 11 | 'https://httpbin.org'; 12 | 13 | -------------------------------------------------------------------------------- /test/node/sync.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment node 3 | */ 4 | 5 | 'use strict'; 6 | 7 | const { SnekfetchSync, TestRoot } = require('../interop'); 8 | 9 | test('sync get', SnekfetchSync && (() => { 10 | const res = SnekfetchSync.get(`${TestRoot}/get`).end(); 11 | expect(res.body).not.toBeUndefined(); 12 | })); 13 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "10" 4 | - "9" 5 | - "8" 6 | install: npm install 7 | jobs: 8 | include: 9 | - stage: test 10 | script: bash ./scripts/travis-test.sh 11 | - stage: deploy 12 | script: bash ./scripts/travis-deploy.sh 13 | cache: 14 | directories: 15 | - node_modules 16 | notifications: 17 | email: false 18 | -------------------------------------------------------------------------------- /test/node/http2.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment node 3 | */ 4 | 5 | 'use strict'; 6 | 7 | global.HTTP_VERSION = 2; 8 | 9 | const hasHttp2 = (() => { 10 | const [a, b, c] = process.version.split('.'); 11 | return (+a.slice(1) * 0x1000) + (+b * 0x100) + +c >= 38912; 12 | })(); 13 | 14 | if (hasHttp2) { 15 | require('./main'); 16 | } else { 17 | test.skip('no http2 support', () => 1); 18 | } 19 | -------------------------------------------------------------------------------- /sync.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | let syncify; 4 | try { 5 | syncify = require('@snek/syncify'); 6 | } catch (err) { 7 | throw new Error('Using sync requires @snek/syncify (npm install @snek/syncify)'); 8 | } 9 | 10 | const Snekfetch = require('.'); 11 | 12 | class SnekfetchSync extends Snekfetch { 13 | end() { 14 | return syncify(super.end()); 15 | } 16 | } 17 | 18 | module.exports = SnekfetchSync; 19 | -------------------------------------------------------------------------------- /src/node/mime.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const mimes = require('./mimes.json'); 4 | const mimeOfBuffer = require('./mimeOfBuffer.js'); 5 | 6 | function lookupMime(ext) { 7 | return mimes[ext.replace(/^\./, '')] || mimes.bin; 8 | } 9 | 10 | function lookupBuffer(buffer) { 11 | const ret = mimeOfBuffer(buffer); 12 | return ret ? ret.mime : mimes.bin; 13 | } 14 | 15 | module.exports = { 16 | buffer: lookupBuffer, 17 | lookup: lookupMime, 18 | }; 19 | -------------------------------------------------------------------------------- /scripts/travis-test.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | 3 | npm run setup 4 | npm run lint 5 | npm run test 6 | 7 | if [ "$TRAVIS_BRANCH" != "master" -o -n "$TRAVIS_TAG" -o "$TRAVIS_PULL_REQUEST" != "false" ]; then 8 | echo -e "Not sending coverage for a non master branch push - covering without sending." 9 | exit 0 10 | fi 11 | 12 | node -e "const [a,b,c]=process.version.split('.');((+a.slice(1)*0x1000)+(+b*0x100)+(+c)>=38912)||process.exit(1)" 13 | if [ $? == 0 ]; then 14 | echo -e "Generating Coverage for a master branch push - covering and sending." 15 | npm run coverage 16 | fi 17 | -------------------------------------------------------------------------------- /test/browser/main.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* eslint-env browser */ 4 | 5 | window.fetch = require('node-fetch'); 6 | window.URLSearchParams = require('url').URLSearchParams; 7 | window.FormData = require('form-data'); 8 | window.TextDecoder = require('util').TextDecoder; 9 | 10 | const { Snekfetch, TestRoot } = require('../interop'); 11 | 12 | require('../main'); 13 | 14 | test('arraybuffer evil works', () => 15 | Snekfetch.get(`${TestRoot}/get`, { responseType: 'arraybuffer' }) 16 | .then((res) => { 17 | expect(res.body.url).toContain('/get'); 18 | })); 19 | -------------------------------------------------------------------------------- /test/node/util.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const FormData = require('../../src/node/FormData'); 4 | const mime = require('../../src/node/mime'); 5 | 6 | test('node/FormData behaves predictably', () => { 7 | const f = new FormData(); 8 | f.append('hello'); 9 | f.append('hello', 'world'); 10 | expect(f.length).toBe(77); 11 | f.append('meme', 'dream', 'name'); 12 | expect(f.length).toBe(210); 13 | }); 14 | 15 | test('node/mimes behaves predictably', () => { 16 | expect(mime.lookup('js')).toBe('application/javascript'); 17 | expect(mime.lookup('nope')).toBe('application/octet-stream'); 18 | expect(mime.buffer([0xFF, 0xD8, 0xFF])).toBe('image/jpeg'); 19 | }); 20 | -------------------------------------------------------------------------------- /test/node/main.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | 5 | const { Snekfetch, TestRoot } = require('../interop'); 6 | 7 | require('../main'); 8 | 9 | test('node/pipe get', (done) => { 10 | Snekfetch.get(`${TestRoot}/get`) 11 | .pipe(fs.createWriteStream('/dev/null')) 12 | .on('finish', done); 13 | }); 14 | 15 | 16 | test('node/FormData json works', () => 17 | Snekfetch.post(`${TestRoot}/post`) 18 | .attach('object', { a: 1 }) 19 | .then((res) => { 20 | const { form } = res.body; 21 | expect(form.object).toBe('{"a":1}'); 22 | })); 23 | 24 | test('node/rawsend post', () => 25 | Snekfetch.post(`${TestRoot}/post`) 26 | .send(Buffer.from('memes')).end()); 27 | -------------------------------------------------------------------------------- /scripts/travis-deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Based on https://github.com/hydrabolt/discord.js-site/blob/master/deploy/deploy.sh 3 | 4 | set -e 5 | 6 | if [ "$TRAVIS_BRANCH" != "master" -o -n "$TRAVIS_TAG" -o "$TRAVIS_PULL_REQUEST" != "false" ]; then 7 | echo -e "Not building for a non master branch push - building without deploying." 8 | npm run docs 9 | exit 0 10 | fi 11 | 12 | echo -e "Building for a master branch push - building and deploying." 13 | 14 | REPO=$(git config remote.origin.url) 15 | SHA=$(git rev-parse --verify HEAD) 16 | 17 | TARGET_BRANCH="gh-pages" 18 | git clone $REPO dist -b $TARGET_BRANCH 19 | 20 | npm run docs 21 | 22 | rsync -vau docs/ dist/ 23 | 24 | cd dist 25 | git add --all . 26 | git config user.name "Travis CI" 27 | git config user.email "${COMMIT_EMAIL}" 28 | git commit -m "Docs build: ${SHA}" || true 29 | git push "https://${GH_TOKEN}@${GH_REF}" $TARGET_BRANCH 30 | -------------------------------------------------------------------------------- /test/server.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const http = require('http'); 4 | 5 | const ref = require.main === module; 6 | 7 | const server = http.createServer((req, res) => { 8 | if (!ref) { 9 | req.connection.unref(); 10 | } 11 | switch (req.url) { 12 | case '/invalid-json': 13 | res.setHeader('Content-Type', 'application/json'); 14 | res.end('{ "a": 1'); 15 | break; 16 | case '/form-urlencoded': 17 | res.setHeader('Content-Type', 'application/x-www-form-urlencoded'); 18 | res.end('test=1&hello=world'); 19 | break; 20 | case '/echo': { 21 | req.on('data', (c) => { 22 | res.write(c); 23 | }); 24 | req.on('end', () => { 25 | res.end(); 26 | }); 27 | break; 28 | } 29 | default: 30 | res.end(); 31 | break; 32 | } 33 | }); 34 | 35 | server.on('connection', (socket) => { 36 | if (!ref) { 37 | socket.unref(); 38 | } 39 | }); 40 | 41 | server.listen(0); 42 | 43 | exports.port = server.address().port; 44 | 45 | if (ref) { 46 | console.log(exports.port); // eslint-disable-line no-console 47 | } 48 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Gus Caplan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/browser/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* eslint-env browser */ 4 | 5 | function request(snek) { 6 | snek.options.body = snek.options.data; 7 | const type = snek.options.responseType === 'arraybuffer' ? 'arrayBuffer' : 'text'; 8 | return window.fetch(snek.options.url, snek.options) 9 | .then((r) => r[type]().then((raw) => { 10 | const headers = {}; 11 | for (const [k, v] of r.headers.entries()) { 12 | headers[k.toLowerCase()] = v; 13 | } 14 | return { 15 | raw, 16 | headers, 17 | statusCode: r.status, 18 | statusText: r.statusText, 19 | }; 20 | })); 21 | } 22 | 23 | module.exports = { 24 | request, 25 | shouldSendRaw: () => false, 26 | METHODS: ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'PATCH'], 27 | Parent: Object, 28 | FormData: window.FormData, 29 | querystring: { 30 | parse: (str) => { 31 | const parsed = {}; 32 | for (const [k, v] of new window.URLSearchParams(str).entries()) { 33 | parsed[k] = v; 34 | } 35 | return parsed; 36 | }, 37 | stringify: (obj) => new window.URLSearchParams(obj).toString(), 38 | }, 39 | }; 40 | 41 | -------------------------------------------------------------------------------- /test/node/file.test.disabled: -------------------------------------------------------------------------------- 1 | /** 2 | * @jest-environment node 3 | */ 4 | 5 | 'use strict'; 6 | 7 | const fs = require('fs'); 8 | const { Snekfetch } = require('../interop'); 9 | 10 | const resolve = (x) => require.resolve(x); 11 | 12 | test('node/file get', () => { 13 | const original = fs.readFileSync(resolve('../../package.json')).toString(); 14 | return Snekfetch.get(`file://${resolve('../../package.json')}`) 15 | .then((res) => { 16 | expect(res.raw.toString()).toBe(original); 17 | }); 18 | }); 19 | 20 | test('node/file post', () => { 21 | const content = 'wow this is a\n\ntest!!'; 22 | const file = './test_file_post.txt'; 23 | return Snekfetch.post(`file://${file}`) 24 | .send(content) 25 | .then(() => Snekfetch.get(`file://${file}`)) 26 | .then((res) => { 27 | expect(res.raw.toString()).toBe(content); 28 | }) 29 | .then(() => { 30 | fs.unlinkSync(file); 31 | }); 32 | }); 33 | 34 | test('node/file delete', () => { 35 | const file = './test_file_delete.txt'; 36 | fs.closeSync(fs.openSync(file, 'w')); 37 | expect(fs.existsSync(file)).toBe(true); 38 | return Snekfetch.delete(`file://${file}`) 39 | .then(() => { 40 | expect(fs.existsSync(file)).toBe(false); 41 | }); 42 | }); 43 | 44 | 45 | test('node/file invalid method', () => { 46 | expect(() => { 47 | Snekfetch.options('file:///dev/urandom'); 48 | }).toThrow(/Invalid request method for file:/); 49 | }); 50 | -------------------------------------------------------------------------------- /docs.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Docma = require('docma'); 4 | const Package = require('./package'); 5 | 6 | Docma.create() 7 | .build({ 8 | app: { 9 | title: Package.name, 10 | base: '/', 11 | entrance: 'content:readme', 12 | routing: 'query', 13 | server: Docma.ServerType.GITHUB, 14 | }, 15 | markdown: { 16 | gfm: true, 17 | tables: true, 18 | breaks: false, 19 | pedantic: false, 20 | sanitize: false, 21 | smartLists: false, 22 | smartypants: false, 23 | tasks: false, 24 | emoji: true, 25 | }, 26 | src: [ 27 | { readme: './README.md' }, 28 | { snekfetch: './src/index.js' }, 29 | ], 30 | dest: './docs', 31 | jsdoc: { 32 | plugins: ['jsdoc-dynamic'], 33 | }, 34 | template: { 35 | options: { 36 | title: Package.name, 37 | navItems: [ 38 | { 39 | label: 'Readme', 40 | href: '?content=readme', 41 | }, 42 | { 43 | label: 'Documentation', 44 | href: '?api=snekfetch', 45 | iconClass: 'ico-book', 46 | }, 47 | { 48 | label: 'GitHub', 49 | href: Package.repository.homepage, 50 | target: '_blank', 51 | iconClass: 'ico-md ico-github', 52 | }, 53 | ], 54 | }, 55 | }, 56 | }) 57 | .catch(console.error); // eslint-disable-line no-console 58 | -------------------------------------------------------------------------------- /src/index.mjs: -------------------------------------------------------------------------------- 1 | import Snekfetch from './index.js'; 2 | 3 | export default Snekfetch; 4 | 5 | export const { version } = Snekfetch; 6 | export const { METHODS } = Snekfetch; 7 | 8 | export const { acl } = Snekfetch; 9 | export const { bind } = Snekfetch; 10 | export const { checkout } = Snekfetch; 11 | export const { connect } = Snekfetch; 12 | export const { copy } = Snekfetch; 13 | const { delete: _delete } = Snekfetch; 14 | export { _delete as delete }; 15 | export const { get } = Snekfetch; 16 | export const { head } = Snekfetch; 17 | export const { link } = Snekfetch; 18 | export const { lock } = Snekfetch; 19 | export const { merge } = Snekfetch; 20 | export const { mkactivity } = Snekfetch; 21 | export const { mkcalendar } = Snekfetch; 22 | export const { mkcol } = Snekfetch; 23 | export const { move } = Snekfetch; 24 | export const { notify } = Snekfetch; 25 | export const { options } = Snekfetch; 26 | export const { patch } = Snekfetch; 27 | export const { post } = Snekfetch; 28 | export const { propfind } = Snekfetch; 29 | export const { proppatch } = Snekfetch; 30 | export const { purge } = Snekfetch; 31 | export const { put } = Snekfetch; 32 | export const { rebind } = Snekfetch; 33 | export const { report } = Snekfetch; 34 | export const { search } = Snekfetch; 35 | export const { source } = Snekfetch; 36 | export const { subscribe } = Snekfetch; 37 | export const { trace } = Snekfetch; 38 | export const { unbind } = Snekfetch; 39 | export const { unlink } = Snekfetch; 40 | export const { unlock } = Snekfetch; 41 | export const { unsubscribe } = Snekfetch; 42 | -------------------------------------------------------------------------------- /src/node/FormData.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const mime = require('./mime'); 5 | 6 | class FormData { 7 | constructor() { 8 | this.boundary = `--snekfetch--${Math.random().toString().slice(2, 7)}`; 9 | this.buffers = []; 10 | } 11 | 12 | append(name, data, filename) { 13 | if (typeof data === 'undefined') { 14 | return; 15 | } 16 | let str = `\r\n--${this.boundary}\r\nContent-Disposition: form-data; name="${name}"`; 17 | let mimetype = null; 18 | if (filename) { 19 | str += `; filename="${filename}"`; 20 | mimetype = 'application/octet-stream'; 21 | const extname = path.extname(filename).slice(1); 22 | if (extname) { 23 | mimetype = mime.lookup(extname); 24 | } 25 | } 26 | 27 | if (data instanceof Buffer) { 28 | mimetype = mime.buffer(data); 29 | } else if (typeof data === 'object') { 30 | mimetype = 'application/json'; 31 | data = Buffer.from(JSON.stringify(data)); 32 | } else { 33 | data = Buffer.from(String(data)); 34 | } 35 | 36 | if (mimetype) { 37 | str += `\r\nContent-Type: ${mimetype}`; 38 | } 39 | this.buffers.push(Buffer.from(`${str}\r\n\r\n`)); 40 | this.buffers.push(data); 41 | } 42 | 43 | getBoundary() { 44 | return this.boundary; 45 | } 46 | 47 | end() { 48 | return Buffer.concat([...this.buffers, Buffer.from(`\r\n--${this.boundary}--`)]); 49 | } 50 | 51 | get length() { 52 | return this.buffers.reduce((sum, b) => sum + Buffer.byteLength(b), 0); 53 | } 54 | } 55 | 56 | module.exports = FormData; 57 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | extends: 'airbnb', 5 | parser: 'babel-eslint', 6 | parserOptions: { 7 | ecmaVersion: 2018, 8 | sourceType: 'script', 9 | ecmaFeatures: { 10 | experimentalObjectRestSpread: true, 11 | }, 12 | }, 13 | env: { 14 | es6: true, 15 | node: true, 16 | }, 17 | overrides: [ 18 | { 19 | files: ['*.jsx'], 20 | parserOptions: { 21 | sourceType: 'module', 22 | ecmaFeatures: { jsx: true }, 23 | }, 24 | }, 25 | { 26 | files: ['*.mjs'], 27 | parserOptions: { sourceType: 'module' }, 28 | env: { 29 | node: true, 30 | }, 31 | rules: { 32 | 'no-restricted-globals': ['error', 'require'], 33 | }, 34 | }, 35 | { 36 | files: ['*.web.js'], 37 | env: { browser: true }, 38 | }, 39 | ], 40 | rules: { 41 | 'strict': ['error', 'global'], 42 | 'no-bitwise': 'off', 43 | 'no-iterator': 'off', 44 | 'global-require': 'off', 45 | 'quote-props': ['error', 'consistent-as-needed'], 46 | 'brace-style': ['error', '1tbs', { allowSingleLine: false }], 47 | 'curly': ['error', 'all'], 48 | 'no-param-reassign': 'off', 49 | 'arrow-parens': ['error', 'always'], 50 | 'no-multi-assign': 'off', 51 | 'no-underscore-dangle': 'off', 52 | 'no-restricted-syntax': 'off', 53 | 'object-curly-newline': 'off', 54 | 'prefer-const': ['error', { destructuring: 'all' }], 55 | 'class-methods-use-this': 'off', 56 | 'import/no-dynamic-require': 'off', 57 | 'import/no-extraneous-dependencies': ['error', { 58 | devDependencies: true, 59 | }], 60 | 'import/extensions': 'off', 61 | }, 62 | globals: { 63 | WebAssembly: false, 64 | BigInt: false, 65 | URL: false, 66 | }, 67 | }; 68 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![npm][download-badge]][npm] 2 | [![David][dep-badge]][dep-link] 3 | [![Coverage Status][coverage-badge]][coverage-link] 4 | [![Build Status][build-badge]][build-link] 5 | 6 | [![NPM][large-badge]][stats-link] 7 | 8 | # snekfetch [![Version Badge][version-badge]][npm] 9 | 10 | Snekfetch is a fast, efficient, and user-friendly library for making HTTP requests. 11 | 12 | It also supports native ALPN negotiation in node for efficient http/2 requests! 13 | 14 | The API was inspired by superagent, however it is much smaller and faster. 15 | In fact, in browser, it is a mere 4.0kb. 16 | 17 | Documentation is available at https://snekfetch.js.org/ 18 | 19 | ## Some examples 20 | 21 | ```javascript 22 | const request = require('snekfetch'); 23 | 24 | request.post('https://httpbin.org/post') 25 | .send({ usingGoodRequestLibrary: true }) 26 | .then(r => console.log(r.body)); // r.body is object from json response 27 | 28 | request.get('https://s.gc.gy/o-SNAKES.jpg') 29 | .then(r => fs.writeFile('download.jpg', r.body)); // r.body is buffer 30 | 31 | request.get('https://s.gc.gy/o-SNAKES.jpg') 32 | .pipe(fs.createWriteStream('download.jpg')); // pipes 33 | ``` 34 | 35 | Available for browser as UMD from [unpkg][unpkg-link] 36 | ```html 37 | 38 | ``` 39 | 40 | [npm]: https://npmjs.org/package/snekfetch 41 | [large-badge]: https://nodei.co/npm/snekfetch.png?downloads=true&downloadRank=true&stars=true 42 | [stats-link]: https://nodei.co/npm/snekfetch/ 43 | [version-badge]: https://versionbadge.now.sh/npm/snekfetch.svg 44 | [download-badge]: https://img.shields.io/npm/dt/snekfetch.svg?maxAge=3600 45 | [build-badge]: https://api.travis-ci.com/devsnek/snekfetch.svg?branch=master 46 | [build-link]: https://travis-ci.com/devsnek/snekfetch 47 | [dep-badge]: https://david-dm.org/devsnek/snekfetch.svg 48 | [dep-link]: https://david-dm.org/devsnek/snekfetch 49 | [coverage-badge]: https://coveralls.io/repos/github/devsnek/snekfetch/badge.svg?branch=master 50 | [coverage-link]: https://coveralls.io/github/devsnek/snekfetch?branch=master 51 | [unpkg-link]: https://unpkg.com/ 52 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "snekfetch", 3 | "version": "4.0.4", 4 | "main": "src/index", 5 | "module": "src/index.mjs", 6 | "unpkg": "browser.js", 7 | "jsdelivr": "browser.js", 8 | "scripts": { 9 | "setup": "install-peerdeps --dev eslint-config-airbnb", 10 | "lint": "eslint --ext=mjs,js src test sync.js webpack.config.js", 11 | "test": "node ./node_modules/.bin/jest", 12 | "coverage": "cat ./coverage/lcov.info | coveralls", 13 | "docs": "node docs.js", 14 | "build:browser": "webpack-cli", 15 | "prepublishOnly": "npm run lint && npm run test && npm run build:browser", 16 | "changelog": "git log dd0c84b^..HEAD --pretty=format:'* [[`%h`](https://github.com/devsnek/snekfetch/commit/%H)] - %s' > CHANGELOG.md" 17 | }, 18 | "repository": { 19 | "type": "git", 20 | "url": "git+https://github.com/devsnek/snekfetch.git", 21 | "homepage": "https://github.com/devsnek/snekfetch" 22 | }, 23 | "author": "Gus Caplan ", 24 | "license": "MIT", 25 | "bugs": { 26 | "url": "https://github.com/devsnek/snekfetch/issues" 27 | }, 28 | "homepage": "https://snekfetch.js.org/", 29 | "dependencies": {}, 30 | "devDependencies": { 31 | "@snek/syncify": "0.0.6", 32 | "babel-eslint": "^8.2.3", 33 | "coveralls": "^3.0.1", 34 | "docma": "^2.1.0", 35 | "eslint": "^4.19.1", 36 | "eslint-config-airbnb": "^16.1.0", 37 | "eslint-plugin-import": "^2.11.0", 38 | "eslint-plugin-jsx-a11y": "^6.0.3", 39 | "eslint-plugin-react": "^7.7.0", 40 | "form-data": "^2.3.2", 41 | "install-peerdeps": "^1.6.0", 42 | "jest": "^22.4.3", 43 | "jsdoc-dynamic": "^1.0.4", 44 | "json-filter-loader": "^1.0.0", 45 | "node-fetch": "^2.1.2", 46 | "webpack": "^4.8.1", 47 | "webpack-cli": "^2.1.3" 48 | }, 49 | "description": "Just do http requests without all that weird nastiness from other libs", 50 | "browser": { 51 | "./src/node/index.js": false, 52 | "./src/meta.js": false 53 | }, 54 | "jest": { 55 | "collectCoverage": true, 56 | "collectCoverageFrom": [ 57 | "src/**/*.js", 58 | "!src/node/mimeOfBuffer.js", 59 | "!src/node/transports/http2.js" 60 | ], 61 | "verbose": true 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/node/socket.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const tls = require('tls'); 4 | const http = require('http'); 5 | const https = require('https'); 6 | // lazy require http2 because it emits a warning 7 | let http2; 8 | 9 | const hasHttp2 = (() => { 10 | const [a, b, c] = process.version.split('.'); 11 | return (+a.slice(1) * 0x1000) + (+b * 0x100) + +c >= 38912; 12 | })(); 13 | const ALPNProtocols = hasHttp2 ? ['h2', 'http/1.1'] : ['http/1.1']; 14 | 15 | function connectHttp(opt) { 16 | const req = http.request(opt); 17 | return Promise.resolve({ req }); 18 | } 19 | 20 | function http2req(connection, opt) { 21 | return connection.request(Object.assign({ 22 | ':path': opt.path, 23 | ':method': opt.method, 24 | ':authority': opt.host, 25 | }, opt.headers)); 26 | } 27 | 28 | function connectHttps(opt) { 29 | return new Promise((resolve, reject) => { 30 | const port = opt.port = +opt.port || 443; 31 | const socket = tls.connect({ 32 | host: opt.host, 33 | port, 34 | servername: opt.host, 35 | ALPNProtocols, 36 | }); 37 | socket.once('error', reject); 38 | socket.once('secureConnect', () => { 39 | switch (socket.alpnProtocol) { 40 | case false: 41 | case 'http/1.1': { 42 | const req = https.request(Object.assign({ 43 | createConnection: () => socket, 44 | }, opt)); 45 | resolve({ req }); 46 | break; 47 | } 48 | case 'h2': { 49 | if (http2 === undefined) { 50 | http2 = require('http2'); 51 | } 52 | 53 | const connection = http2.connect({ 54 | host: opt.host, 55 | port, 56 | }, { 57 | createConnection: () => socket, 58 | }); 59 | 60 | connection.port = opt.port; 61 | connection.host = opt.host; 62 | 63 | const req = http2req(connection, opt); 64 | resolve({ req, http2: true, connection }); 65 | break; 66 | } 67 | default: 68 | reject(new Error(`No supported ALPN protocol was negotiated, got ${socket.alpnProtocol}`)); 69 | break; 70 | } 71 | }); 72 | }); 73 | } 74 | 75 | module.exports = (options) => 76 | (options.protocol === 'https:' ? connectHttps : connectHttp)(options); 77 | 78 | module.exports.http2req = http2req; 79 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at me@gus.host. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /src/node/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const zlib = require('zlib'); 4 | const { parse: UrlParse, resolve: UrlResolve } = require('url'); 5 | const socket = require('./socket'); 6 | const Stream = require('stream'); 7 | const querystring = require('querystring'); 8 | const { METHODS, STATUS_CODES } = require('http'); 9 | const Package = require('../../package'); 10 | const FormData = require('./FormData'); 11 | 12 | function shouldUnzip(statusCode, headers) { 13 | /* istanbul ignore next */ 14 | if (statusCode === 204 || statusCode === 304) { 15 | return false; 16 | } 17 | if (+headers['content-length'] === 0) { 18 | return false; 19 | } 20 | return /^\s*(?:deflate|gzip)\s*$/.test(headers['content-encoding']); 21 | } 22 | 23 | function request(snek, options = snek.options) { 24 | return new Promise(async (resolve, reject) => { 25 | Object.assign(options, UrlParse(options.url)); 26 | 27 | if (!options.headers['user-agent']) { 28 | options.headers['user-agent'] = `snekfetch/${Package.version} (${Package.homepage})`; 29 | } 30 | 31 | let { data } = options; 32 | if (data && data.end) { 33 | data = data.end(); 34 | } 35 | 36 | if (!options.headers['content-length']) { 37 | let length = 0; 38 | if (data) { 39 | try { 40 | length = Buffer.byteLength(data); 41 | } catch (err) {} // eslint-disable-line no-empty 42 | } 43 | options.headers['content-length'] = length; 44 | } 45 | 46 | let req; 47 | let http2 = false; 48 | try { 49 | if (options.connection && options.connection.port === options.port && 50 | options.connection.host === options.host) { 51 | req = socket.http2req(options.connection, options); 52 | http2 = true; 53 | } else { 54 | const O = await socket(options); 55 | ({ req } = O); 56 | if (O.http2) { 57 | http2 = true; 58 | } 59 | if (O.connection) { 60 | options.connection = O.connection; 61 | } 62 | } 63 | } catch (err) { 64 | reject(err); 65 | return; 66 | } 67 | 68 | req.once('error', reject); 69 | 70 | const body = []; 71 | let headers; 72 | let statusCode; 73 | let statusText; 74 | 75 | const handleResponse = (stream) => { 76 | if (options.redirect === 'follow' && [301, 302, 303, 307, 308].includes(statusCode)) { 77 | resolve(request(snek, Object.assign({}, options, { 78 | url: UrlResolve(options.url, headers.location), 79 | }))); 80 | if (req.abort) { 81 | req.abort(); 82 | } else if (req.close) { 83 | req.close(); 84 | } 85 | return; 86 | } 87 | 88 | stream.once('error', reject); 89 | 90 | if (shouldUnzip(statusCode, headers)) { 91 | stream = stream.pipe(zlib.createUnzip({ 92 | flush: zlib.Z_SYNC_FLUSH, 93 | finishFlush: zlib.Z_SYNC_FLUSH, 94 | })); 95 | 96 | stream.once('error', reject); 97 | } 98 | 99 | stream.on('data', (chunk) => { 100 | /* istanbul ignore next */ 101 | if (!snek.push(chunk)) { 102 | snek.pause(); 103 | } 104 | body.push(chunk); 105 | }); 106 | 107 | stream.once('end', () => { 108 | snek.push(null); 109 | const raw = Buffer.concat(body); 110 | if (options.connection && options.connection.close) { 111 | options.connection.close(); 112 | } 113 | resolve({ 114 | raw, headers, statusCode, statusText, 115 | }); 116 | }); 117 | }; 118 | 119 | req.on('response', (res) => { 120 | if (!http2) { 121 | statusText = res.statusMessage || STATUS_CODES[statusCode]; 122 | ({ headers, statusCode } = res); 123 | handleResponse(res); 124 | } else { 125 | statusCode = res[':status']; 126 | statusText = STATUS_CODES[statusCode]; 127 | headers = res; 128 | handleResponse(req); 129 | } 130 | }); 131 | 132 | /* istanbul ignore next */ 133 | if (data instanceof Stream) { 134 | data.pipe(req); 135 | } else if (data instanceof Buffer) { 136 | req.write(data); 137 | } else if (data) { 138 | req.write(data); 139 | } 140 | req.end(); 141 | }); 142 | } 143 | 144 | module.exports = { 145 | request, 146 | shouldSendRaw: (data) => data instanceof Buffer || data instanceof Stream, 147 | querystring, 148 | METHODS, 149 | FormData, 150 | Parent: Stream.Readable, 151 | }; 152 | -------------------------------------------------------------------------------- /test/main.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | jest.setTimeout(10e3); 4 | 5 | const { Snekfetch, TestRoot } = require('./interop'); 6 | 7 | const server = require('./server'); 8 | 9 | function makeTestObj({ unicode = true, numbers = false } = {}) { 10 | const test = { 11 | Hello: 'world', 12 | Test: numbers ? 1337 : '1337', 13 | }; 14 | if (unicode) { 15 | test.Unicode = '( ͡° ͜ʖ ͡°)'; 16 | } 17 | const single = { key: 'singleKey', value: 'awoooo' }; 18 | return { 19 | test, 20 | single, 21 | check(obj) { 22 | expect(obj).not.toBeUndefined(); 23 | expect(obj.Hello).toBe(test.Hello); 24 | expect(obj.Test).toBe(test.Test); 25 | if (unicode) { 26 | expect(obj.Unicode).toBe(test.Unicode); 27 | } 28 | if (obj[single.key]) { 29 | expect(obj[single.key]).toBe(single.value); 30 | } 31 | }, 32 | }; 33 | } 34 | 35 | test('should return a promise', () => { 36 | for (const C of [ 37 | Snekfetch.get(`${TestRoot}/get`).end(), 38 | Snekfetch.get.call(null, `${TestRoot}/get`).end(), 39 | Snekfetch.get.call({}, `${TestRoot}/get`).end(), 40 | ]) { 41 | expect(C) 42 | .toBeInstanceOf(Promise); 43 | } 44 | }); 45 | 46 | test('should reject with error on network failure', () => { 47 | const invalid = 'http://localhost:0/'; 48 | /* 49 | https://gc.gy/❥ȗ.png 50 | return expect(Snekfetch.get(invalid).end()) 51 | .rejects.toBeInstanceOf(Error); 52 | */ 53 | return Snekfetch.get(invalid).catch((err) => { 54 | expect(err.name).toMatch(/(Fetch)?Error/); 55 | }); 56 | }); 57 | 58 | test('should resolve on success', () => 59 | Snekfetch.get(`${TestRoot}/get`).then((res) => { 60 | expect(res.statusCode).toBe(200); 61 | expect(res.ok).toBe(true); 62 | expect(res).toHaveProperty('raw'); 63 | expect(res).toHaveProperty('body'); 64 | })); 65 | 66 | test('end should work', () => 67 | Snekfetch.get(`${TestRoot}/get`).end((err, res) => { 68 | expect(err).toBe(null); 69 | expect(res.body).not.toBeUndefined(); 70 | })); 71 | 72 | test('should reject if response is not between 200 and 300', () => 73 | Snekfetch.get(`${TestRoot}/404`).catch((err) => { 74 | expect(err.statusCode).toBe(404); 75 | expect(err.ok).toBe(false); 76 | })); 77 | 78 | test('unzipping works', () => 79 | Snekfetch.get(`${TestRoot}/gzip`) 80 | .then((res) => { 81 | expect(res.body).not.toBeUndefined(); 82 | expect(res.body.gzipped).toBe(true); 83 | })); 84 | 85 | test('query should work', () => { 86 | const { test, check, single } = makeTestObj(); 87 | Promise.all([ 88 | Snekfetch.get(`${TestRoot}/get?inline=true`) 89 | .query(test) 90 | .query(single.key, single.value) 91 | .end(), 92 | Snekfetch.get(`${TestRoot}/get?inline=true`, { query: test }) 93 | .end(), 94 | ]) 95 | .then((ress) => { 96 | for (const res of ress) { 97 | const { args } = res.body; 98 | check(args); 99 | expect(args.inline).toBe('true'); 100 | } 101 | }); 102 | }); 103 | 104 | test('headers should work', () => { 105 | const { test, check } = makeTestObj({ unicode: false }); 106 | return Promise.all([ 107 | Snekfetch.get(`${TestRoot}/get`) 108 | .set(test).end(), 109 | Snekfetch.get(`${TestRoot}/get`, { headers: test }) 110 | .end(), 111 | ]) 112 | .then((ress) => { 113 | for (const res of ress) { 114 | check(res.body.headers); 115 | } 116 | }); 117 | }); 118 | 119 | test('attach should work', () => { 120 | const { test, check } = makeTestObj(); 121 | return Snekfetch.post(`${TestRoot}/post`) 122 | .attach(test) 123 | .then((res) => check(res.body.form)); 124 | }); 125 | 126 | test('send should work with json', () => { 127 | const { test, check } = makeTestObj({ numbers: true }); 128 | return Promise.all([ 129 | Snekfetch.post(`${TestRoot}/post`) 130 | .send(test).end(), 131 | Snekfetch.post(`${TestRoot}/post`, { data: test }) 132 | .end(), 133 | ]) 134 | .then((ress) => { 135 | for (const res of ress) { 136 | check(res.body.json); 137 | } 138 | }); 139 | }); 140 | 141 | test('send should work with urlencoded', () => { 142 | const { test, check } = makeTestObj(); 143 | return Snekfetch.post(`${TestRoot}/post`) 144 | .set('content-type', 'application/x-www-form-urlencoded') 145 | .send(test) 146 | .then((res) => check(res.body.form)); 147 | }); 148 | 149 | test('invalid json is text', () => 150 | Snekfetch.get(`http://localhost:${server.port}/invalid-json`) 151 | .then((res) => { 152 | expect(res.body).toBe('{ "a": 1'); 153 | })); 154 | 155 | test('x-www-form-urlencoded response body', () => 156 | Snekfetch.get(`http://localhost:${server.port}/form-urlencoded`) 157 | .then((res) => { 158 | const { body } = res; 159 | expect(body.test).toBe('1'); 160 | expect(body.hello).toBe('world'); 161 | })); 162 | 163 | test('redirects', () => 164 | Snekfetch.get(`${TestRoot}/redirect/1`) 165 | .then((res) => { 166 | expect(res.body).not.toBeUndefined(); 167 | expect(res.body.url).toBe(`${TestRoot}/get`); 168 | })); 169 | 170 | test('res should be defined when rejecting', () => 171 | Snekfetch.get(`${TestRoot}/404`) 172 | .end((err, res) => { 173 | expect(err.statusCode).not.toBeUndefined(); 174 | expect(res).not.toBe(null); 175 | })); 176 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const transport = require(typeof window !== 'undefined' ? './browser' : './node'); 4 | 5 | /** 6 | * Snekfetch 7 | * @extends Stream.Readable 8 | * @extends Promise 9 | */ 10 | class Snekfetch extends transport.Parent { 11 | /** 12 | * Options to pass to the Snekfetch constructor 13 | * @typedef {object} SnekfetchOptions 14 | * @memberof Snekfetch 15 | * @property {object} [headers] Headers to initialize the request with 16 | * @property {object|string|Buffer} [data] Data to initialize the request with 17 | * @property {string|Object} [query] Query to intialize the request with 18 | * @property {boolean} [redirect='follow'] If the request should follow redirects 19 | * @property {object} [qs=querystring] Querystring module to use, any object providing 20 | * `stringify` and `parse` for querystrings 21 | * @property {external:Agent|boolean} [agent] Whether to use an http agent 22 | */ 23 | 24 | /** 25 | * Create a request. 26 | * Usually you'll want to do `Snekfetch#method(url [, options])` instead of 27 | * `new Snekfetch(method, url [, options])` 28 | * @param {string} method HTTP method 29 | * @param {string} url URL 30 | * @param {SnekfetchOptions} [opts] Options 31 | */ 32 | constructor(method, url, opts = {}) { 33 | super(); 34 | this.options = Object.assign({ 35 | qs: transport.querystring, 36 | method, 37 | url, 38 | redirect: 'follow', 39 | }, opts, { 40 | headers: {}, 41 | query: undefined, 42 | data: undefined, 43 | }); 44 | if (opts.headers) { 45 | this.set(opts.headers); 46 | } 47 | if (opts.query) { 48 | this.query(opts.query); 49 | } 50 | if (opts.data) { 51 | this.send(opts.data); 52 | } 53 | } 54 | 55 | /** 56 | * Add a query param to the request 57 | * @param {string|Object} name Name of query param or object to add to query 58 | * @param {string} [value] If name is a string value, this will be the value of the query param 59 | * @returns {Snekfetch} This request 60 | */ 61 | query(name, value) { 62 | if (this.options.query === undefined) { 63 | this.options.query = {}; 64 | } 65 | if (typeof name === 'object') { 66 | Object.assign(this.options.query, name); 67 | } else { 68 | this.options.query[name] = value; 69 | } 70 | 71 | return this; 72 | } 73 | 74 | /** 75 | * Add a header to the request 76 | * @param {string|Object} name Name of query param or object to add to headers 77 | * @param {string} [value] If name is a string value, this will be the value of the header 78 | * @returns {Snekfetch} This request 79 | */ 80 | set(name, value) { 81 | if (typeof name === 'object') { 82 | for (const [k, v] of Object.entries(name)) { 83 | this.options.headers[k.toLowerCase()] = v; 84 | } 85 | } else { 86 | this.options.headers[name.toLowerCase()] = value; 87 | } 88 | 89 | return this; 90 | } 91 | 92 | /** 93 | * Attach a form data object 94 | * @param {string} name Name of the form attachment 95 | * @param {string|Object|Buffer} data Data for the attachment 96 | * @param {string} [filename] Optional filename if form attachment name needs to be overridden 97 | * @returns {Snekfetch} This request 98 | */ 99 | attach(...args) { 100 | const form = this.options.data instanceof transport.FormData ? 101 | this.options.data : this.options.data = new transport.FormData(); 102 | if (typeof args[0] === 'object') { 103 | for (const [k, v] of Object.entries(args[0])) { 104 | this.attach(k, v); 105 | } 106 | } else { 107 | form.append(...args); 108 | } 109 | 110 | return this; 111 | } 112 | 113 | /** 114 | * Send data with the request 115 | * @param {string|Buffer|Object} data Data to send 116 | * @returns {Snekfetch} This request 117 | */ 118 | send(data) { 119 | if (data instanceof transport.FormData || transport.shouldSendRaw(data)) { 120 | this.options.data = data; 121 | } else if (data !== null && typeof data === 'object') { 122 | const header = this.options.headers['content-type']; 123 | let serialize; 124 | if (header) { 125 | if (header.includes('application/json')) { 126 | serialize = JSON.stringify; 127 | } else if (header.includes('urlencoded')) { 128 | serialize = this.options.qs.stringify; 129 | } 130 | } else { 131 | this.set('Content-Type', 'application/json'); 132 | serialize = JSON.stringify; 133 | } 134 | this.options.data = serialize(data); 135 | } else { 136 | this.options.data = data; 137 | } 138 | return this; 139 | } 140 | 141 | then(resolver, rejector) { 142 | if (this._response) { 143 | return this._response.then(resolver, rejector); 144 | } 145 | this._finalizeRequest(); 146 | // eslint-disable-next-line no-return-assign 147 | return this._response = transport.request(this) 148 | .then(({ raw, headers, statusCode, statusText }) => { 149 | // forgive me :( 150 | const self = this; // eslint-disable-line consistent-this 151 | /** 152 | * Response from Snekfetch 153 | * @typedef {Object} SnekfetchResponse 154 | * @memberof Snekfetch 155 | * @prop {?string|object|Buffer} body Processed response body 156 | * @prop {Buffer} raw Raw response body 157 | * @prop {boolean} ok If the response code is >= 200 and < 300 158 | * @prop {number} statusCode HTTP status code 159 | * @prop {string} statusText Human readable HTTP status 160 | */ 161 | const res = { 162 | get body() { 163 | delete res.body; 164 | const type = res.headers['content-type']; 165 | if (raw instanceof ArrayBuffer) { 166 | raw = new window.TextDecoder('utf8').decode(raw); // eslint-disable-line no-undef 167 | } 168 | if (/application\/json/.test(type)) { 169 | try { 170 | res.body = JSON.parse(raw); 171 | } catch (err) { 172 | res.body = String(raw); 173 | } 174 | } else if (/application\/x-www-form-urlencoded/.test(type)) { 175 | res.body = self.options.qs.parse(String(raw)); 176 | } else { 177 | res.body = raw; 178 | } 179 | return res.body; 180 | }, 181 | raw, 182 | ok: statusCode >= 200 && statusCode < 400, 183 | headers, 184 | statusCode, 185 | statusText, 186 | }; 187 | 188 | if (res.ok) { 189 | return res; 190 | } 191 | const err = new Error(`${statusCode} ${statusText}`.trim()); 192 | Object.assign(err, res); 193 | return Promise.reject(err); 194 | }) 195 | .then(resolver, rejector); 196 | } 197 | 198 | catch(rejector) { 199 | return this.then(null, rejector); 200 | } 201 | 202 | /** 203 | * End the request 204 | * @param {Function} [cb] Optional callback to handle the response 205 | * @returns {Promise} This request 206 | */ 207 | end(cb) { 208 | return this.then( 209 | (res) => (cb ? cb(null, res) : res), 210 | (err) => (cb ? cb(err, err.statusCode ? err : null) : Promise.reject(err)), 211 | ); 212 | } 213 | 214 | _finalizeRequest() { 215 | if (this.options.method !== 'HEAD') { 216 | this.set('Accept-Encoding', 'gzip, deflate'); 217 | } 218 | if (this.options.data && this.options.data.getBoundary) { 219 | this.set('Content-Type', `multipart/form-data; boundary=${this.options.data.getBoundary()}`); 220 | } 221 | 222 | if (this.options.query) { 223 | const [url, query] = this.options.url.split('?'); 224 | this.options.url = `${url}?${this.options.qs.stringify(this.options.query)}${query ? `&${query}` : ''}`; 225 | } 226 | } 227 | 228 | _read() { 229 | this.resume(); 230 | if (this._response) { 231 | return; 232 | } 233 | this.catch((err) => this.emit('error', err)); 234 | } 235 | } 236 | 237 | /** 238 | * Create a ((THIS)) request 239 | * @dynamic this.METHODS 240 | * @method Snekfetch.((THIS)lowerCase) 241 | * @param {string} url The url to request 242 | * @param {Snekfetch.snekfetchOptions} [opts] Options 243 | * @returns {Snekfetch} 244 | */ 245 | Snekfetch.METHODS = transport.METHODS.filter((m) => m !== 'M-SEARCH'); 246 | for (const method of Snekfetch.METHODS) { 247 | Snekfetch[method.toLowerCase()] = function runMethod(url, opts) { 248 | const Constructor = this && this.prototype instanceof Snekfetch ? this : Snekfetch; 249 | return new Constructor(method, url, opts); 250 | }; 251 | } 252 | 253 | module.exports = Snekfetch; 254 | 255 | /** 256 | * @external Agent 257 | * @see {@link https://nodejs.org/api/http.html#http_class_http_agent} 258 | */ 259 | -------------------------------------------------------------------------------- /src/node/mimeOfBuffer.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* eslint-disable */ 4 | 5 | // from file-type by @sindresorhus under the MIT license 6 | 7 | function mimeOfBuffer(input) { 8 | const buf = new Uint8Array(input); 9 | 10 | if (!(buf && buf.length > 1)) 11 | return null; 12 | 13 | 14 | if (buf[0] === 0xFF && buf[1] === 0xD8 && buf[2] === 0xFF) { 15 | return { 16 | ext: 'jpg', 17 | mime: 'image/jpeg', 18 | }; 19 | } 20 | 21 | if (buf[0] === 0x89 && buf[1] === 0x50 && buf[2] === 0x4E && buf[3] === 0x47) { 22 | return { 23 | ext: 'png', 24 | mime: 'image/png', 25 | }; 26 | } 27 | 28 | if (buf[0] === 0x47 && buf[1] === 0x49 && buf[2] === 0x46) { 29 | return { 30 | ext: 'gif', 31 | mime: 'image/gif', 32 | }; 33 | } 34 | 35 | if (buf[8] === 0x57 && buf[9] === 0x45 && buf[10] === 0x42 && buf[11] === 0x50) { 36 | return { 37 | ext: 'webp', 38 | mime: 'image/webp', 39 | }; 40 | } 41 | 42 | if (buf[0] === 0x46 && buf[1] === 0x4C && buf[2] === 0x49 && buf[3] === 0x46) { 43 | return { 44 | ext: 'flif', 45 | mime: 'image/flif', 46 | }; 47 | } 48 | 49 | // needs to be before `tif` check 50 | if ( 51 | ((buf[0] === 0x49 && buf[1] === 0x49 && buf[2] === 0x2A && buf[3] === 0x0) || 52 | (buf[0] === 0x4D && buf[1] === 0x4D && buf[2] === 0x0 && buf[3] === 0x2A)) && buf[8] === 0x43 && buf[9] === 0x52 53 | ) { 54 | return { 55 | ext: 'cr2', 56 | mime: 'image/x-canon-cr2', 57 | }; 58 | } 59 | 60 | if ( 61 | (buf[0] === 0x49 && buf[1] === 0x49 && buf[2] === 0x2A && buf[3] === 0x0) || 62 | (buf[0] === 0x4D && buf[1] === 0x4D && buf[2] === 0x0 && buf[3] === 0x2A) 63 | ) { 64 | return { 65 | ext: 'tif', 66 | mime: 'image/tiff', 67 | }; 68 | } 69 | 70 | if (buf[0] === 0x42 && buf[1] === 0x4D) { 71 | return { 72 | ext: 'bmp', 73 | mime: 'image/bmp', 74 | }; 75 | } 76 | 77 | if (buf[0] === 0x49 && buf[1] === 0x49 && buf[2] === 0xBC) { 78 | return { 79 | ext: 'jxr', 80 | mime: 'image/vnd.ms-photo', 81 | }; 82 | } 83 | 84 | if (buf[0] === 0x38 && buf[1] === 0x42 && buf[2] === 0x50 && buf[3] === 0x53) { 85 | return { 86 | ext: 'psd', 87 | mime: 'image/vnd.adobe.photoshop', 88 | }; 89 | } 90 | 91 | // needs to be before `zip` check 92 | if ( 93 | buf[0] === 0x50 && buf[1] === 0x4B && buf[2] === 0x3 && buf[3] === 0x4 && buf[30] === 0x6D && buf[31] === 0x69 && 94 | buf[32] === 0x6D && buf[33] === 0x65 && buf[34] === 0x74 && buf[35] === 0x79 && buf[36] === 0x70 && 95 | buf[37] === 0x65 && buf[38] === 0x61 && buf[39] === 0x70 && buf[40] === 0x70 && buf[41] === 0x6C && 96 | buf[42] === 0x69 && buf[43] === 0x63 && buf[44] === 0x61 && buf[45] === 0x74 && buf[46] === 0x69 && 97 | buf[47] === 0x6F && buf[48] === 0x6E && buf[49] === 0x2F && buf[50] === 0x65 && buf[51] === 0x70 && 98 | buf[52] === 0x75 && buf[53] === 0x62 && buf[54] === 0x2B && buf[55] === 0x7A && buf[56] === 0x69 && 99 | buf[57] === 0x70 100 | ) { 101 | return { 102 | ext: 'epub', 103 | mime: 'application/epub+zip', 104 | }; 105 | } 106 | 107 | // needs to be before `zip` check 108 | // assumes signed .xpi from addons.mozilla.org 109 | if ( 110 | buf[0] === 0x50 && buf[1] === 0x4B && buf[2] === 0x3 && buf[3] === 0x4 && buf[30] === 0x4D && buf[31] === 0x45 && 111 | buf[32] === 0x54 && buf[33] === 0x41 && buf[34] === 0x2D && buf[35] === 0x49 && buf[36] === 0x4E && 112 | buf[37] === 0x46 && buf[38] === 0x2F && buf[39] === 0x6D && buf[40] === 0x6F && buf[41] === 0x7A && 113 | buf[42] === 0x69 && buf[43] === 0x6C && buf[44] === 0x6C && buf[45] === 0x61 && buf[46] === 0x2E && 114 | buf[47] === 0x72 && buf[48] === 0x73 && buf[49] === 0x61 115 | ) { 116 | return { 117 | ext: 'xpi', 118 | mime: 'application/x-xpinstall', 119 | }; 120 | } 121 | 122 | if ( 123 | buf[0] === 0x50 && buf[1] === 0x4B && (buf[2] === 0x3 || buf[2] === 0x5 || buf[2] === 0x7) && 124 | (buf[3] === 0x4 || buf[3] === 0x6 || buf[3] === 0x8) 125 | ) { 126 | return { 127 | ext: 'zip', 128 | mime: 'application/zip', 129 | }; 130 | } 131 | 132 | if (buf[257] === 0x75 && buf[258] === 0x73 && buf[259] === 0x74 && buf[260] === 0x61 && buf[261] === 0x72) { 133 | return { 134 | ext: 'tar', 135 | mime: 'application/x-tar', 136 | }; 137 | } 138 | 139 | if ( 140 | buf[0] === 0x52 && buf[1] === 0x61 && buf[2] === 0x72 && buf[3] === 0x21 && buf[4] === 0x1A && buf[5] === 0x7 && 141 | (buf[6] === 0x0 || buf[6] === 0x1) 142 | ) { 143 | return { 144 | ext: 'rar', 145 | mime: 'application/x-rar-compressed', 146 | }; 147 | } 148 | 149 | if (buf[0] === 0x1F && buf[1] === 0x8B && buf[2] === 0x8) { 150 | return { 151 | ext: 'gz', 152 | mime: 'application/gzip', 153 | }; 154 | } 155 | 156 | if (buf[0] === 0x42 && buf[1] === 0x5A && buf[2] === 0x68) { 157 | return { 158 | ext: 'bz2', 159 | mime: 'application/x-bzip2', 160 | }; 161 | } 162 | 163 | if (buf[0] === 0x37 && buf[1] === 0x7A && buf[2] === 0xBC && buf[3] === 0xAF && buf[4] === 0x27 && buf[5] === 0x1C) { 164 | return { 165 | ext: '7z', 166 | mime: 'application/x-7z-compressed', 167 | }; 168 | } 169 | 170 | if (buf[0] === 0x78 && buf[1] === 0x01) { 171 | return { 172 | ext: 'dmg', 173 | mime: 'application/x-apple-diskimage', 174 | }; 175 | } 176 | 177 | if ( 178 | (buf[0] === 0x0 && buf[1] === 0x0 && buf[2] === 0x0 && (buf[3] === 0x18 || buf[3] === 0x20) && buf[4] === 0x66 && 179 | buf[5] === 0x74 && buf[6] === 0x79 && buf[7] === 0x70) || 180 | (buf[0] === 0x33 && buf[1] === 0x67 && buf[2] === 0x70 && buf[3] === 0x35) || 181 | (buf[0] === 0x0 && buf[1] === 0x0 && buf[2] === 0x0 && buf[3] === 0x1C && buf[4] === 0x66 && buf[5] === 0x74 && 182 | buf[6] === 0x79 && buf[7] === 0x70 && buf[8] === 0x6D && buf[9] === 0x70 && buf[10] === 0x34 && 183 | buf[11] === 0x32 && buf[16] === 0x6D && buf[17] === 0x70 && buf[18] === 0x34 && buf[19] === 0x31 && 184 | buf[20] === 0x6D && buf[21] === 0x70 && buf[22] === 0x34 && buf[23] === 0x32 && buf[24] === 0x69 && 185 | buf[25] === 0x73 && buf[26] === 0x6F && buf[27] === 0x6D) || 186 | (buf[0] === 0x0 && buf[1] === 0x0 && buf[2] === 0x0 && buf[3] === 0x1C && buf[4] === 0x66 && buf[5] === 0x74 && 187 | buf[6] === 0x79 && buf[7] === 0x70 && buf[8] === 0x69 && buf[9] === 0x73 && buf[10] === 0x6F && 188 | buf[11] === 0x6D) || 189 | (buf[0] === 0x0 && buf[1] === 0x0 && buf[2] === 0x0 && buf[3] === 0x1c && buf[4] === 0x66 && buf[5] === 0x74 && 190 | buf[6] === 0x79 && buf[7] === 0x70 && buf[8] === 0x6D && buf[9] === 0x70 && buf[10] === 0x34 && 191 | buf[11] === 0x32 && buf[12] === 0x0 && buf[13] === 0x0 && buf[14] === 0x0 && buf[15] === 0x0) 192 | ) { 193 | return { 194 | ext: 'mp4', 195 | mime: 'video/mp4', 196 | }; 197 | } 198 | 199 | if ( 200 | buf[0] === 0x0 && buf[1] === 0x0 && buf[2] === 0x0 && buf[3] === 0x1C && buf[4] === 0x66 && 201 | buf[5] === 0x74 && buf[6] === 0x79 && buf[7] === 0x70 && buf[8] === 0x4D && buf[9] === 0x34 && buf[10] === 0x56 202 | ) { 203 | return { 204 | ext: 'm4v', 205 | mime: 'video/x-m4v', 206 | }; 207 | } 208 | 209 | if (buf[0] === 0x4D && buf[1] === 0x54 && buf[2] === 0x68 && buf[3] === 0x64) { 210 | return { 211 | ext: 'mid', 212 | mime: 'audio/midi', 213 | }; 214 | } 215 | 216 | // https://github.com/threatstack/libmagic/blob/master/magic/Magdir/matroska 217 | if (buf[0] === 0x1A && buf[1] === 0x45 && buf[2] === 0xDF && buf[3] === 0xA3) { 218 | const sliced = buf.subarray(4, 4 + 4096); 219 | const idPos = sliced.findIndex((el, i, arr) => arr[i] === 0x42 && arr[i + 1] === 0x82); 220 | 221 | if (idPos >= 0) { 222 | const docTypePos = idPos + 3; 223 | const findDocType = (type) => Array.from(type).every((c, i) => sliced[docTypePos + i] === c.charCodeAt(0)); 224 | 225 | if (findDocType('matroska')) { 226 | return { 227 | ext: 'mkv', 228 | mime: 'video/x-matroska', 229 | }; 230 | } 231 | if (findDocType('webm')) { 232 | return { 233 | ext: 'webm', 234 | mime: 'video/webm', 235 | }; 236 | } 237 | } 238 | } 239 | 240 | if ( 241 | buf[0] === 0x0 && buf[1] === 0x0 && buf[2] === 0x0 && buf[3] === 0x14 && buf[4] === 0x66 && buf[5] === 0x74 && 242 | buf[6] === 0x79 && buf[7] === 0x70 243 | ) { 244 | return { 245 | ext: 'mov', 246 | mime: 'video/quicktime', 247 | }; 248 | } 249 | 250 | if ( 251 | buf[0] === 0x52 && buf[1] === 0x49 && buf[2] === 0x46 && buf[3] === 0x46 && buf[8] === 0x41 && buf[9] === 0x56 && 252 | buf[10] === 0x49 253 | ) { 254 | return { 255 | ext: 'avi', 256 | mime: 'video/x-msvideo', 257 | }; 258 | } 259 | 260 | if ( 261 | buf[0] === 0x30 && buf[1] === 0x26 && buf[2] === 0xB2 && buf[3] === 0x75 && buf[4] === 0x8E && buf[5] === 0x66 && 262 | buf[6] === 0xCF && buf[7] === 0x11 && buf[8] === 0xA6 && buf[9] === 0xD9 263 | ) { 264 | return { 265 | ext: 'wmv', 266 | mime: 'video/x-ms-wmv', 267 | }; 268 | } 269 | 270 | if (buf[0] === 0x0 && buf[1] === 0x0 && buf[2] === 0x1 && buf[3].toString(16)[0] === 'b') { 271 | return { 272 | ext: 'mpg', 273 | mime: 'video/mpeg', 274 | }; 275 | } 276 | 277 | if ((buf[0] === 0x49 && buf[1] === 0x44 && buf[2] === 0x33) || (buf[0] === 0xFF && buf[1] === 0xfb)) { 278 | return { 279 | ext: 'mp3', 280 | mime: 'audio/mpeg', 281 | }; 282 | } 283 | 284 | if ((buf[4] === 0x66 && buf[5] === 0x74 && buf[6] === 0x79 && buf[7] === 0x70 && buf[8] === 0x4D && 285 | buf[9] === 0x34 && buf[10] === 0x41) || (buf[0] === 0x4D && buf[1] === 0x34 && buf[2] === 0x41 && buf[3] === 0x20) 286 | ) { 287 | return { 288 | ext: 'm4a', 289 | mime: 'audio/m4a', 290 | }; 291 | } 292 | 293 | // needs to be before `ogg` check 294 | if ( 295 | buf[28] === 0x4F && buf[29] === 0x70 && buf[30] === 0x75 && buf[31] === 0x73 && buf[32] === 0x48 && 296 | buf[33] === 0x65 && buf[34] === 0x61 && buf[35] === 0x64 297 | ) { 298 | return { 299 | ext: 'opus', 300 | mime: 'audio/opus', 301 | }; 302 | } 303 | 304 | if (buf[0] === 0x4F && buf[1] === 0x67 && buf[2] === 0x67 && buf[3] === 0x53) { 305 | return { 306 | ext: 'ogg', 307 | mime: 'audio/ogg', 308 | }; 309 | } 310 | 311 | if (buf[0] === 0x66 && buf[1] === 0x4C && buf[2] === 0x61 && buf[3] === 0x43) { 312 | return { 313 | ext: 'flac', 314 | mime: 'audio/x-flac', 315 | }; 316 | } 317 | 318 | if ( 319 | buf[0] === 0x52 && buf[1] === 0x49 && buf[2] === 0x46 && buf[3] === 0x46 && buf[8] === 0x57 && buf[9] === 0x41 && 320 | buf[10] === 0x56 && buf[11] === 0x45 321 | ) { 322 | return { 323 | ext: 'wav', 324 | mime: 'audio/x-wav', 325 | }; 326 | } 327 | 328 | if (buf[0] === 0x23 && buf[1] === 0x21 && buf[2] === 0x41 && buf[3] === 0x4D && buf[4] === 0x52 && buf[5] === 0x0A) { 329 | return { 330 | ext: 'amr', 331 | mime: 'audio/amr', 332 | }; 333 | } 334 | 335 | if (buf[0] === 0x25 && buf[1] === 0x50 && buf[2] === 0x44 && buf[3] === 0x46) { 336 | return { 337 | ext: 'pdf', 338 | mime: 'application/pdf', 339 | }; 340 | } 341 | 342 | if (buf[0] === 0x4D && buf[1] === 0x5A) { 343 | return { 344 | ext: 'exe', 345 | mime: 'application/x-msdownload', 346 | }; 347 | } 348 | 349 | if ((buf[0] === 0x43 || buf[0] === 0x46) && buf[1] === 0x57 && buf[2] === 0x53) { 350 | return { 351 | ext: 'swf', 352 | mime: 'application/x-shockwave-flash', 353 | }; 354 | } 355 | 356 | if (buf[0] === 0x7B && buf[1] === 0x5C && buf[2] === 0x72 && buf[3] === 0x74 && buf[4] === 0x66) { 357 | return { 358 | ext: 'rtf', 359 | mime: 'application/rtf', 360 | }; 361 | } 362 | 363 | if ( 364 | (buf[0] === 0x77 && buf[1] === 0x4F && buf[2] === 0x46 && buf[3] === 0x46) && 365 | ( 366 | (buf[4] === 0x00 && buf[5] === 0x01 && buf[6] === 0x00 && buf[7] === 0x00) || 367 | (buf[4] === 0x4F && buf[5] === 0x54 && buf[6] === 0x54 && buf[7] === 0x4F) 368 | ) 369 | ) { 370 | return { 371 | ext: 'woff', 372 | mime: 'application/font-woff', 373 | }; 374 | } 375 | 376 | if ( 377 | (buf[0] === 0x77 && buf[1] === 0x4F && buf[2] === 0x46 && buf[3] === 0x32) && 378 | ( 379 | (buf[4] === 0x00 && buf[5] === 0x01 && buf[6] === 0x00 && buf[7] === 0x00) || 380 | (buf[4] === 0x4F && buf[5] === 0x54 && buf[6] === 0x54 && buf[7] === 0x4F) 381 | ) 382 | ) { 383 | return { 384 | ext: 'woff2', 385 | mime: 'application/font-woff', 386 | }; 387 | } 388 | 389 | if ( 390 | (buf[34] === 0x4C && buf[35] === 0x50) && 391 | ( 392 | (buf[8] === 0x00 && buf[9] === 0x00 && buf[10] === 0x01) || 393 | (buf[8] === 0x01 && buf[9] === 0x00 && buf[10] === 0x02) || 394 | (buf[8] === 0x02 && buf[9] === 0x00 && buf[10] === 0x02) 395 | ) 396 | ) { 397 | return { 398 | ext: 'eot', 399 | mime: 'application/octet-stream', 400 | }; 401 | } 402 | 403 | if (buf[0] === 0x00 && buf[1] === 0x01 && buf[2] === 0x00 && buf[3] === 0x00 && buf[4] === 0x00) { 404 | return { 405 | ext: 'ttf', 406 | mime: 'application/font-sfnt', 407 | }; 408 | } 409 | 410 | if (buf[0] === 0x4F && buf[1] === 0x54 && buf[2] === 0x54 && buf[3] === 0x4F && buf[4] === 0x00) { 411 | return { 412 | ext: 'otf', 413 | mime: 'application/font-sfnt', 414 | }; 415 | } 416 | 417 | if (buf[0] === 0x00 && buf[1] === 0x00 && buf[2] === 0x01 && buf[3] === 0x00) { 418 | return { 419 | ext: 'ico', 420 | mime: 'image/x-icon', 421 | }; 422 | } 423 | 424 | if (buf[0] === 0x46 && buf[1] === 0x4C && buf[2] === 0x56 && buf[3] === 0x01) { 425 | return { 426 | ext: 'flv', 427 | mime: 'video/x-flv', 428 | }; 429 | } 430 | 431 | if (buf[0] === 0x25 && buf[1] === 0x21) { 432 | return { 433 | ext: 'ps', 434 | mime: 'application/postscript', 435 | }; 436 | } 437 | 438 | if (buf[0] === 0xFD && buf[1] === 0x37 && buf[2] === 0x7A && buf[3] === 0x58 && buf[4] === 0x5A && buf[5] === 0x00) { 439 | return { 440 | ext: 'xz', 441 | mime: 'application/x-xz', 442 | }; 443 | } 444 | 445 | if (buf[0] === 0x53 && buf[1] === 0x51 && buf[2] === 0x4C && buf[3] === 0x69) { 446 | return { 447 | ext: 'sqlite', 448 | mime: 'application/x-sqlite3', 449 | }; 450 | } 451 | 452 | if (buf[0] === 0x4E && buf[1] === 0x45 && buf[2] === 0x53 && buf[3] === 0x1A) { 453 | return { 454 | ext: 'nes', 455 | mime: 'application/x-nintendo-nes-rom', 456 | }; 457 | } 458 | 459 | if (buf[0] === 0x43 && buf[1] === 0x72 && buf[2] === 0x32 && buf[3] === 0x34) { 460 | return { 461 | ext: 'crx', 462 | mime: 'application/x-google-chrome-extension', 463 | }; 464 | } 465 | 466 | if ( 467 | (buf[0] === 0x4D && buf[1] === 0x53 && buf[2] === 0x43 && buf[3] === 0x46) || 468 | (buf[0] === 0x49 && buf[1] === 0x53 && buf[2] === 0x63 && buf[3] === 0x28) 469 | ) { 470 | return { 471 | ext: 'cab', 472 | mime: 'application/vnd.ms-cab-compressed', 473 | }; 474 | } 475 | 476 | // needs to be before `ar` check 477 | if ( 478 | buf[0] === 0x21 && buf[1] === 0x3C && buf[2] === 0x61 && buf[3] === 0x72 && buf[4] === 0x63 && buf[5] === 0x68 && 479 | buf[6] === 0x3E && buf[7] === 0x0A && buf[8] === 0x64 && buf[9] === 0x65 && buf[10] === 0x62 && buf[11] === 0x69 && 480 | buf[12] === 0x61 && buf[13] === 0x6E && buf[14] === 0x2D && buf[15] === 0x62 && buf[16] === 0x69 && 481 | buf[17] === 0x6E && buf[18] === 0x61 && buf[19] === 0x72 && buf[20] === 0x79 482 | ) { 483 | return { 484 | ext: 'deb', 485 | mime: 'application/x-deb', 486 | }; 487 | } 488 | 489 | if ( 490 | buf[0] === 0x21 && buf[1] === 0x3C && buf[2] === 0x61 && buf[3] === 0x72 && buf[4] === 0x63 && buf[5] === 0x68 && 491 | buf[6] === 0x3E 492 | ) { 493 | return { 494 | ext: 'ar', 495 | mime: 'application/x-unix-archive', 496 | }; 497 | } 498 | 499 | if (buf[0] === 0xED && buf[1] === 0xAB && buf[2] === 0xEE && buf[3] === 0xDB) { 500 | return { 501 | ext: 'rpm', 502 | mime: 'application/x-rpm', 503 | }; 504 | } 505 | 506 | if ( 507 | (buf[0] === 0x1F && buf[1] === 0xA0) || 508 | (buf[0] === 0x1F && buf[1] === 0x9D) 509 | ) { 510 | return { 511 | ext: 'Z', 512 | mime: 'application/x-compress', 513 | }; 514 | } 515 | 516 | if (buf[0] === 0x4C && buf[1] === 0x5A && buf[2] === 0x49 && buf[3] === 0x50) { 517 | return { 518 | ext: 'lz', 519 | mime: 'application/x-lzip', 520 | }; 521 | } 522 | 523 | if ( 524 | buf[0] === 0xD0 && buf[1] === 0xCF && buf[2] === 0x11 && buf[3] === 0xE0 && buf[4] === 0xA1 && buf[5] === 0xB1 && 525 | buf[6] === 0x1A && buf[7] === 0xE1 526 | ) { 527 | return { 528 | ext: 'msi', 529 | mime: 'application/x-msi', 530 | }; 531 | } 532 | 533 | if ( 534 | buf[0] === 0x06 && buf[1] === 0x0E && buf[2] === 0x2B && buf[3] === 0x34 && buf[4] === 0x02 && buf[5] === 0x05 && 535 | buf[6] === 0x01 && buf[7] === 0x01 && buf[8] === 0x0D && buf[9] === 0x01 && buf[10] === 0x02 && buf[11] === 0x01 && 536 | buf[12] === 0x01 && buf[13] === 0x02 537 | ) { 538 | return { 539 | ext: 'mxf', 540 | mime: 'application/mxf', 541 | }; 542 | } 543 | 544 | return null; 545 | } 546 | 547 | module.exports = mimeOfBuffer; 548 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | * [[`025d579`](https://github.com/devsnek/snekfetch/commit/025d57918b0615ac403d613abe558ed53330580f)] - [core] remove undefined `request` property from response 2 | * [[`b0014a3`](https://github.com/devsnek/snekfetch/commit/b0014a3109a64fde9dcd5b65a1a5d8b493d38fac)] - [changelog] update 3 | * [[`e073a72`](https://github.com/devsnek/snekfetch/commit/e073a720678fa6eb9269ea4310bf4189e992c3d8)] - [version] 4.0.4 4 | * [[`0e603fa`](https://github.com/devsnek/snekfetch/commit/0e603fa740e9482cafdef4f34072306f61f1c1ba)] - [browser] fix webpack output 5 | * [[`2d8cd56`](https://github.com/devsnek/snekfetch/commit/2d8cd56d65befdb693a03e0e9746cdb5e2aa2dcd)] - [changelog] update 6 | * [[`26182ff`](https://github.com/devsnek/snekfetch/commit/26182ff9ab32ba787335df55557441aa266c7bf7)] - [version] 4.0.3 7 | * [[`9fef333`](https://github.com/devsnek/snekfetch/commit/9fef33367056c5e7b9f999ee407817a5a1d8765a)] - add script to package to generate changelog 8 | * [[`08ad9f6`](https://github.com/devsnek/snekfetch/commit/08ad9f6936203c5b86cc84659d91c91b9d1d3206)] - cut older commits from changelog 9 | * [[`75cd455`](https://github.com/devsnek/snekfetch/commit/75cd455353d50b9bfa643f1e0aed249b68d2e83f)] - change changelog format 10 | * [[`0cb076b`](https://github.com/devsnek/snekfetch/commit/0cb076b81e8c3c948602d5b681636e9e23be70e9)] - things i said i would do 11 | * [[`9222cbe`](https://github.com/devsnek/snekfetch/commit/9222cbe2f055335c5f173c050e43e07dd5f906f8)] - 4.0.2 12 | * [[`b9d53f5`](https://github.com/devsnek/snekfetch/commit/b9d53f555599e471eb29a5e033fb22d946600d6b)] - status is now statusCode (#41) 13 | * [[`32c5da6`](https://github.com/devsnek/snekfetch/commit/32c5da60a2c0401ee6b66cc4a5caa86c3aa20ec8)] - 4.0.1 14 | * [[`d925b7a`](https://github.com/devsnek/snekfetch/commit/d925b7a506d99633d941628fd0a6dd3f8d38a453)] - add repo token 15 | * [[`aaa505a`](https://github.com/devsnek/snekfetch/commit/aaa505adfcb5c2622eed8b6d78a3b74d159a0e26)] - change badge 16 | * [[`7ca062d`](https://github.com/devsnek/snekfetch/commit/7ca062d3bd70ebd292a2c0e230b894e933e96a9b)] - use string concat for speeeeeed 17 | * [[`8fb6c5c`](https://github.com/devsnek/snekfetch/commit/8fb6c5c42963cc36606635807bcfda14b274cef6)] - cleanup 18 | * [[`f22d100`](https://github.com/devsnek/snekfetch/commit/f22d100724d9156cfe2658aac976d4663d39b7d0)] - catch stream errors 19 | * [[`834d3ab`](https://github.com/devsnek/snekfetch/commit/834d3ab39edfb1cfe9de57949f4f0ad430117b43)] - version 4 yo 20 | * [[`9b2cfcd`](https://github.com/devsnek/snekfetch/commit/9b2cfcd1b101dd63c1cbc716ccd0dd01a78cffc5)] - add node 10 21 | * [[`7554922`](https://github.com/devsnek/snekfetch/commit/75549220a44e03d889034b24ff5a4385ed7d52f5)] - update eslint 22 | * [[`7770ae9`](https://github.com/devsnek/snekfetch/commit/7770ae911fad92863ca1ed4f73eca9baff03d9f1)] - fix github link in docs 23 | * [[`907319b`](https://github.com/devsnek/snekfetch/commit/907319b9b907f5fae73c8277f5447345e84bdf82)] - fix version badge 24 | * [[`62d3574`](https://github.com/devsnek/snekfetch/commit/62d35745cb7ed480a39fa80a7dfd15f352ffddab)] - remove object spread 25 | * [[`b69ecfb`](https://github.com/devsnek/snekfetch/commit/b69ecfbe916df673bb32c601484b75a1f20654ad)] - http2 on 9.8.0 26 | * [[`4250ab6`](https://github.com/devsnek/snekfetch/commit/4250ab6970ad4b5e2963a2f71f489ebe2996a970)] - buffers for everyone yay 27 | * [[`a49b282`](https://github.com/devsnek/snekfetch/commit/a49b2828dc6188ee9d214cad5d2ca673ef5888c8)] - avoid scaring users 28 | * [[`4157fa2`](https://github.com/devsnek/snekfetch/commit/4157fa21644aea746181ae6cab4f9da6d223b602)] - agh 29 | * [[`57b4e67`](https://github.com/devsnek/snekfetch/commit/57b4e674157760a2de56b1108590fdc0c2326e55)] - bump version 30 | * [[`6054801`](https://github.com/devsnek/snekfetch/commit/6054801e56ae7e06bb02dd6466474b3600bfea91)] - lock http2 to node >= 10 31 | * [[`8dc7321`](https://github.com/devsnek/snekfetch/commit/8dc732119e726aab2466a0df69597143455d6cb1)] - fix regression with static methods 32 | * [[`5948edd`](https://github.com/devsnek/snekfetch/commit/5948edd824388d4e2b88b85caf9619e6c64ed56c)] - fall back to destroying http2 connection 33 | * [[`d321cfe`](https://github.com/devsnek/snekfetch/commit/d321cfecd630d6323e8143278528fca0a28fd7ef)] - many bugg fixx 34 | * [[`3baaa7d`](https://github.com/devsnek/snekfetch/commit/3baaa7d3d75c50d881285e63432beedb8ec12698)] - clean up errors and thing 35 | * [[`2cff41d`](https://github.com/devsnek/snekfetch/commit/2cff41d34e9ca1a08ecb40a8615aa0b38f0d96ff)] - Update ISSUE_TEMPLATE.md 36 | * [[`daac3ce`](https://github.com/devsnek/snekfetch/commit/daac3ce57f7775f29412fcc5619e1a39138b5415)] - update travis node 37 | * [[`6373531`](https://github.com/devsnek/snekfetch/commit/6373531976811b9e0509155cfe7b4ca2723cc01e)] - remove .eslintcache 38 | * [[`914ab80`](https://github.com/devsnek/snekfetch/commit/914ab802dd9a7d2b39646129d530a2448a515b13)] - clean up 39 | * [[`aff503a`](https://github.com/devsnek/snekfetch/commit/aff503aa616d00bc469c18e6fb87eb88d5e78864)] - update readme 40 | * [[`3b0b531`](https://github.com/devsnek/snekfetch/commit/3b0b5317b29cc363f5b7fd9babbf7790442935be)] - reuse connection and close connection 41 | * [[`1032a5b`](https://github.com/devsnek/snekfetch/commit/1032a5b812417acf6d258f08b4adab0e9be45308)] - update docs and such 42 | * [[`98cba31`](https://github.com/devsnek/snekfetch/commit/98cba3127ddb1eab5b80f688e6be6d2cf0cf46d4)] - fix browser build 43 | * [[`a281002`](https://github.com/devsnek/snekfetch/commit/a2810020191a309d505bb612b5a7833d3337f4e7)] - http2 rewrite 44 | * [[`51d6568`](https://github.com/devsnek/snekfetch/commit/51d6568a5f724bc8916c845049930e4c049475f7)] - move around esm 45 | * [[`c939e4f`](https://github.com/devsnek/snekfetch/commit/c939e4fd5af8391dd4ebc627200698c739689519)] - version 4 46 | * [[`eb86f67`](https://github.com/devsnek/snekfetch/commit/eb86f67aac211a05147ae4058d0280f9f37df66f)] - clean up mocks and do some golf 47 | * [[`6b3f822`](https://github.com/devsnek/snekfetch/commit/6b3f82254491b6e30b9fa1b86cb3ffd3c0a2fa42)] - add tests for qs_mock 48 | * [[`25f0f86`](https://github.com/devsnek/snekfetch/commit/25f0f865ec6d63a2a71bd8941d90cfd5b574340c)] - bump version 49 | * [[`591fe30`](https://github.com/devsnek/snekfetch/commit/591fe305b7f99b17683fc44ee8c9078ed244a38a)] - Merge branch 'master' of https://github.com/devsnek/snekfetch 50 | * [[`c4c7816`](https://github.com/devsnek/snekfetch/commit/c4c7816e77ffd2fa496ff86e78e86d47bf9f3635)] - many fixes 51 | * [[`359c2dc`](https://github.com/devsnek/snekfetch/commit/359c2dc1d078154e6478978cb27bfa9fe12e7b4d)] - fix tests 52 | * [[`0934d09`](https://github.com/devsnek/snekfetch/commit/0934d0967113241d06c109a44ba0a885b5546414)] - bump version 53 | * [[`92e76ef`](https://github.com/devsnek/snekfetch/commit/92e76efc21f0d37f3a08246274ffca84c57ce1f1)] - move default user agent to node 54 | * [[`f85d9d6`](https://github.com/devsnek/snekfetch/commit/f85d9d66f29030d33bec485715943588874c7337)] - stuff 55 | * [[`f41be40`](https://github.com/devsnek/snekfetch/commit/f41be400b0fe6ff4db5e30fe3327080eeafe5618)] - update dep badge 56 | * [[`aa79d40`](https://github.com/devsnek/snekfetch/commit/aa79d40045f7c609a2972f4c8e5eaa7f5b99fb12)] - eslint better 57 | * [[`ac841a9`](https://github.com/devsnek/snekfetch/commit/ac841a9405292502aad905ec3c63ce28ddd82f24)] - bump version 58 | * [[`f45a2ba`](https://github.com/devsnek/snekfetch/commit/f45a2ba57aaf022c70b237dcd79b86df9a764d5a)] - add jsdelivr entry to package.json 59 | * [[`6612b18`](https://github.com/devsnek/snekfetch/commit/6612b18b3c6bab1adc4925d110745fc495e1e0b0)] - fix tests 60 | * [[`014f4bd`](https://github.com/devsnek/snekfetch/commit/014f4bd1ad73254f69510d24290d549bd420e653)] - clean up 61 | * [[`c0f1ee8`](https://github.com/devsnek/snekfetch/commit/c0f1ee8e5948df065815f87248a956feb1a47c34)] - bump version 62 | * [[`6db72a4`](https://github.com/devsnek/snekfetch/commit/6db72a440b1450e789e5ed1b029ac51b075cfede)] - coverage 63 | * [[`052f027`](https://github.com/devsnek/snekfetch/commit/052f02745afcf663530819c1fbb862ef56706f96)] - destroy response once we don't need it 64 | * [[`8a1f0eb`](https://github.com/devsnek/snekfetch/commit/8a1f0eba16d852c76970e5001a053f85dcb9634d)] - clean up agents and redirects, handling body is more effecient now 65 | * [[`8df39ad`](https://github.com/devsnek/snekfetch/commit/8df39ad5778798cadef99574dc7a17497ad580c2)] - clean up inheritence 66 | * [[`30a7445`](https://github.com/devsnek/snekfetch/commit/30a7445ab7bf3c02f363bf0c44d1d6057c722de0)] - clean up tests 67 | * [[`9d2479a`](https://github.com/devsnek/snekfetch/commit/9d2479a50784aee69a13a8537135a384d02e796e)] - update syncify dep 68 | * [[`3574cb3`](https://github.com/devsnek/snekfetch/commit/3574cb3be69395b991d99ddc8704721260c7be8b)] - update syncify 69 | * [[`eceedee`](https://github.com/devsnek/snekfetch/commit/eceedeec254e6b849d55c73572a8513bc6cc04a7)] - misc 70 | * [[`a42ec62`](https://github.com/devsnek/snekfetch/commit/a42ec62d86d9c20adfe5678afc01ed486adeeb47)] - sync api 71 | * [[`ea75c58`](https://github.com/devsnek/snekfetch/commit/ea75c587e6329abab233067303c934e0906f9842)] - new test setup 72 | * [[`e12bbda`](https://github.com/devsnek/snekfetch/commit/e12bbda89b1effd3e60521149bcb1f0451f7fb4b)] - expand esm 73 | * [[`d277881`](https://github.com/devsnek/snekfetch/commit/d27788129a25bb04b49bc83b27b84ae9c1e70d57)] - new eslint 74 | * [[`f687e93`](https://github.com/devsnek/snekfetch/commit/f687e937b33a75bbcbdc4d8e20fe048e2f5a0297)] - clean snekfetch options docs 75 | * [[`d142b32`](https://github.com/devsnek/snekfetch/commit/d142b321b085c7ccc3922d0aeb44951740afe170)] - make readme nicer 76 | * [[`3130126`](https://github.com/devsnek/snekfetch/commit/3130126bac849d5813a8a2cfc3ebd928c1009e86)] - Create CONTRIBUTING.md 77 | * [[`8078e14`](https://github.com/devsnek/snekfetch/commit/8078e14ee83f5d566d37f33151302699647c1911)] - github made me do this 78 | * [[`8e42545`](https://github.com/devsnek/snekfetch/commit/8e42545a555c6023221a1a9de062815cb8cd1905)] - Create LICENSE 79 | * [[`d69a3ce`](https://github.com/devsnek/snekfetch/commit/d69a3ce522ace5b37915ea2aef40589aacf36829)] - agh 80 | * [[`437b9d7`](https://github.com/devsnek/snekfetch/commit/437b9d7e2811e8ad4110fc70aef13bff2ccc9f50)] - plz work 81 | * [[`7f45688`](https://github.com/devsnek/snekfetch/commit/7f45688aa635c4581f68a484e8c805707de4ac71)] - fix stuff more 82 | * [[`c6fedc2`](https://github.com/devsnek/snekfetch/commit/c6fedc25ff304ecec96c050423824b3d628488fb)] - more esm 83 | * [[`13e8355`](https://github.com/devsnek/snekfetch/commit/13e8355233493f42277d9a8df802f4c678b65c89)] - fix 84 | * [[`0ce04a1`](https://github.com/devsnek/snekfetch/commit/0ce04a166d0f8b75dd1605f8f2259e574882e45c)] - module, sonar 85 | * [[`07e2984`](https://github.com/devsnek/snekfetch/commit/07e2984dfd0320260985885acfeb9936709b3b23)] - prepublish 86 | * [[`1b42f5c`](https://github.com/devsnek/snekfetch/commit/1b42f5c644240e4028fe6dd7cba52b04cf6c058f)] - misc 87 | * [[`1301576`](https://github.com/devsnek/snekfetch/commit/1301576da41266c342fec8e4db174d6131137e5e)] - add unpkg to package.json 88 | * [[`06685fd`](https://github.com/devsnek/snekfetch/commit/06685fd019eaabd83a8cfad15feb30caade9badc)] - bump to 3.5.6 89 | * [[`728085a`](https://github.com/devsnek/snekfetch/commit/728085a5e74213b82faeb763080c1fe03c652d41)] - use umd 90 | * [[`dfe5121`](https://github.com/devsnek/snekfetch/commit/dfe5121834eb2b806feb5496beb5fbf6c5fa01df)] - whoops 91 | * [[`6a404b6`](https://github.com/devsnek/snekfetch/commit/6a404b64fb7518c2d69764ee2f02ed649883b742)] - bump version 92 | * [[`a22772d`](https://github.com/devsnek/snekfetch/commit/a22772d05ce687119d6028ddb7a6f6d3ae16153e)] - fix issue with default params 93 | * [[`5dcb17d`](https://github.com/devsnek/snekfetch/commit/5dcb17d5a666a850a84e74171a7863eec0ce7392)] - stuff 94 | * [[`7da75cf`](https://github.com/devsnek/snekfetch/commit/7da75cf2d21454824cdf803880f94c582ccdc6a7)] - add supplemental stuff for packages that want benefits of my rules 95 | * [[`38558b4`](https://github.com/devsnek/snekfetch/commit/38558b4fecb546caa0d48eaa49a647b1cf3de442)] - try release with browser 96 | * [[`9cbbb57`](https://github.com/devsnek/snekfetch/commit/9cbbb5742ece337d0b2f3d068736cffe607e3bd4)] - bump to 3.5.2 97 | * [[`f7b4e10`](https://github.com/devsnek/snekfetch/commit/f7b4e10b0a2a23b4da81b6e0bd960a09ea8c4620)] - encoding 98 | * [[`897f596`](https://github.com/devsnek/snekfetch/commit/897f596e03a61b7a162681e40e610c782426a963)] - add gzip test 99 | * [[`d799b52`](https://github.com/devsnek/snekfetch/commit/d799b524152257f3835d713c11d8417d453715b7)] - move more node things out of index.js 100 | * [[`201cd36`](https://github.com/devsnek/snekfetch/commit/201cd368b64e689d365e291d5a71789e1fb8909a)] - move node specific method out of index.js 101 | * [[`e9a40dc`](https://github.com/devsnek/snekfetch/commit/e9a40dcb8143c4a42663c5cc487ad3737366dfab)] - clean up redirect header building 102 | * [[`59b7e1b`](https://github.com/devsnek/snekfetch/commit/59b7e1b6ccf4c048691c7c9bc98a74ae9e79d74c)] - pass resolver/rejector to promise in then call 103 | * [[`6b88278`](https://github.com/devsnek/snekfetch/commit/6b88278cd61a46e76164c447465a702351e912af)] - clean up 104 | * [[`4fbff07`](https://github.com/devsnek/snekfetch/commit/4fbff07175f7f644b53815859d4c01db2df48e93)] - fix enormous bug where requests were fetched n+1 times for each call 105 | * [[`4f89c02`](https://github.com/devsnek/snekfetch/commit/4f89c020a38aeaed3ff85f9b865dcb3fea5baae6)] - fix up markdown rendering 106 | * [[`242cfea`](https://github.com/devsnek/snekfetch/commit/242cfea0fe06b5b48c5370acd51d263e6c2b115a)] - more scoping of agent key 107 | * [[`9429fac`](https://github.com/devsnek/snekfetch/commit/9429facbd590b6325eeb3b0280326040fc1846d2)] - more standardization of test object 108 | * [[`a0661e3`](https://github.com/devsnek/snekfetch/commit/a0661e368d819431722a17300c2eff545487e2cc)] - standardize test objects 109 | * [[`f28879f`](https://github.com/devsnek/snekfetch/commit/f28879f84c7224c49df68c09a5f4ea9377ee2695)] - fuck you js strings rot in hell 110 | * [[`95fa2ab`](https://github.com/devsnek/snekfetch/commit/95fa2abcdebd1e2c8294d80df0a624c2d5cd1e8d)] - more golf 111 | * [[`492a04e`](https://github.com/devsnek/snekfetch/commit/492a04e6aa9c3e75daa1248cc5931947d0e4c550)] - add build link 112 | * [[`3f2008a`](https://github.com/devsnek/snekfetch/commit/3f2008aeda01fb4ebc2f883eac03422d3463f816)] - no idea why this is so high 113 | * [[`39ab0a4`](https://github.com/devsnek/snekfetch/commit/39ab0a451cdf228d29480c9ef3288bae0223866e)] - bump version hype 114 | * [[`ec20c02`](https://github.com/devsnek/snekfetch/commit/ec20c02c15999ef67fa956f44c04d6e3eade77c1)] - playing code golf 115 | * [[`ee6ef49`](https://github.com/devsnek/snekfetch/commit/ee6ef49a91ed314d5859f8c53a9e4fd457e7027c)] - new qs mock for increased tinyness 116 | * [[`1854e6a`](https://github.com/devsnek/snekfetch/commit/1854e6aaf651e196e6d41493b426b1cb19889883)] - entries bug is only in latest npm release 117 | * [[`a07755e`](https://github.com/devsnek/snekfetch/commit/a07755e2133121b866b4d2504a29a65d3f499389)] - fix lint 118 | * [[`ac69061`](https://github.com/devsnek/snekfetch/commit/ac6906171fd43b492a184c2d540f2113b28d2778)] - increase coverage 119 | * [[`58ca5a4`](https://github.com/devsnek/snekfetch/commit/58ca5a49ee4465702704c33380eabf2114cc4d44)] - [wip] testing (#18) 120 | * [[`c7465d7`](https://github.com/devsnek/snekfetch/commit/c7465d75fafa73710d9bb8067381388a2d99c1cf)] - update jsdoc-dynamic dep 121 | * [[`7682983`](https://github.com/devsnek/snekfetch/commit/76829830b5cc58115935301bb1afd371734bed90)] - fix site 122 | * [[`b66f988`](https://github.com/devsnek/snekfetch/commit/b66f988a40c7c21efdb565fe81de4630aa1c0218)] - clean up config 123 | * [[`7672006`](https://github.com/devsnek/snekfetch/commit/76720066646502bd677759b9a667a74ed5146bb5)] - new docs 124 | * [[`0f404fc`](https://github.com/devsnek/snekfetch/commit/0f404fc2f21e91be332843ef390f3834777035de)] - fix deps for http2 from npm 125 | * [[`d66bdf2`](https://github.com/devsnek/snekfetch/commit/d66bdf21423d65b1b159ca2d24acabdd1016a2f0)] - remove M-SEARCH because method name doc issues and no one uses it 126 | * [[`4d2f885`](https://github.com/devsnek/snekfetch/commit/4d2f885b1ee7d6ecaaf3418230728f412965d45a)] - update jsdoc-dynamic 127 | * [[`76d9cbd`](https://github.com/devsnek/snekfetch/commit/76d9cbda468270b81c3306c9b490db5620054e59)] - Merge branch 'master' of https://github.com/devsnek/snekfetch 128 | * [[`7aea2c8`](https://github.com/devsnek/snekfetch/commit/7aea2c82b19a99b97468321de1153fcbf6806564)] - update issue template 129 | * [[`7372470`](https://github.com/devsnek/snekfetch/commit/73724709c7bcb732165f12503066ba86cd922198)] - fix content type bug 130 | * [[`d089ab7`](https://github.com/devsnek/snekfetch/commit/d089ab751bfd447c7178081a9a8e92961c05b667)] - remove socket listeners 131 | * [[`5081c2f`](https://github.com/devsnek/snekfetch/commit/5081c2f859baed1cc1cb56af7427c7116a0255ac)] - Release 3.4.3 132 | * [[`fd610ec`](https://github.com/devsnek/snekfetch/commit/fd610ece2d8df60cf8bc1323c1b536cf1237d11e)] - handle socket errors in a way that only node could think of 133 | * [[`e29c9f5`](https://github.com/devsnek/snekfetch/commit/e29c9f58cf6386c3e92c9a58597ac72260969efd)] - these are static 134 | * [[`dad2b8d`](https://github.com/devsnek/snekfetch/commit/dad2b8d235f60ab785bdbdbb7665e623571a4cea)] - update jsdoc-dynamic dep 135 | * [[`498fc92`](https://github.com/devsnek/snekfetch/commit/498fc92ba0c63370498bcd74e5fb6c4f609a122d)] - new doc stuff 136 | * [[`328e9e6`](https://github.com/devsnek/snekfetch/commit/328e9e6bf148ed2198d70768a017bf528b16ce1f)] - update readme 137 | * [[`9c8dd75`](https://github.com/devsnek/snekfetch/commit/9c8dd75f3c8bf8409b4781c99d5171e2075f7d77)] - damn gitignore oddities 138 | * [[`5ee30b2`](https://github.com/devsnek/snekfetch/commit/5ee30b2242aa8e0fd0075bd148d94f0a078d00e1)] - switch theme 139 | * [[`30695c7`](https://github.com/devsnek/snekfetch/commit/30695c74bc7732cb002e7e4e54b4b74426154e46)] - disable emails 140 | * [[`1b969f8`](https://github.com/devsnek/snekfetch/commit/1b969f8b391aad7de6ddc7ccc5c7a10821d1cde8)] - Docsgen (#15) 141 | * [[`7234c5a`](https://github.com/devsnek/snekfetch/commit/7234c5a446f53f4c93b8620822c5e3aa1dd6c5ff)] - remove unused file 142 | * [[`f011cc0`](https://github.com/devsnek/snekfetch/commit/f011cc0d2236468ea9a61ba7f1a6fd9254d2ef0f)] - Release 3.4.2 143 | * [[`9c2af2b`](https://github.com/devsnek/snekfetch/commit/9c2af2be6975d93c5015d5f29c1f7a53216234ec)] - Release 3.4.1 144 | * [[`69a02ae`](https://github.com/devsnek/snekfetch/commit/69a02ae653f42e51b71334853df258e990a23894)] - http2 and form data fix 145 | * [[`2aaae71`](https://github.com/devsnek/snekfetch/commit/2aaae71aef8064a7b5d1c254c0e4ae62b4f73348)] - http2 body works now 146 | * [[`2bcc585`](https://github.com/devsnek/snekfetch/commit/2bcc585a7eaabfaa7f9a883796cfa92fe8f4ab1a)] - Merge branch 'master' of https://github.com/devsnek/snekfetch 147 | * [[`3a99360`](https://github.com/devsnek/snekfetch/commit/3a99360357918b751f043266573450a421aee6eb)] - delete passthrough stream 148 | * [[`e9addda`](https://github.com/devsnek/snekfetch/commit/e9addda1930529c112823a16dc90773df8756775)] - Update index.js 149 | * [[`d625e43`](https://github.com/devsnek/snekfetch/commit/d625e4314ae7db6138cbbc5f37b7dfbeb8176986)] - bump version 150 | * [[`c629c15`](https://github.com/devsnek/snekfetch/commit/c629c15fa0f0268b461cae137c2da7e90e3af956)] - don't allow agent if not following redirects 151 | * [[`9e568db`](https://github.com/devsnek/snekfetch/commit/9e568db3a83e42f83ed9f9e19b0aac14b9e4e190)] - redirect stuff 152 | * [[`68ee0f8`](https://github.com/devsnek/snekfetch/commit/68ee0f8774da5d55f23f231fc018c3836a343424)] - [fix/browser] redirect behavior 153 | * [[`9b9c8d8`](https://github.com/devsnek/snekfetch/commit/9b9c8d84754f9c2867ce08b1a8cc43d4781b16c7)] - fix header object name 154 | * [[`b555054`](https://github.com/devsnek/snekfetch/commit/b555054de419a8153f0450bfe31697df71edda25)] - fix version regression 155 | * [[`ca8fd71`](https://github.com/devsnek/snekfetch/commit/ca8fd71bae0934b3e50637f7cdc4ddaf35522f37)] - change to rc for npm release 156 | * [[`8eabe8f`](https://github.com/devsnek/snekfetch/commit/8eabe8f960736dca0dc4638562d02f3b947e13c1)] - clean up query handling 157 | * [[`5438a11`](https://github.com/devsnek/snekfetch/commit/5438a11944112a14e7eed3819504dade13140d26)] - webpack magic half the build size 158 | * [[`49b3bc7`](https://github.com/devsnek/snekfetch/commit/49b3bc728b6a4e4b04c3dd4ca8c83281e78834e3)] - finalize browser builds 159 | * [[`b9081a5`](https://github.com/devsnek/snekfetch/commit/b9081a5933cb014eb067ff4e27935a9a1a9294b6)] - clean up 160 | * [[`9c1d4b6`](https://github.com/devsnek/snekfetch/commit/9c1d4b6128dc37caa13fb20f3093e1bf4c5aa65b)] - fix up query and final headers 161 | * [[`80f56f8`](https://github.com/devsnek/snekfetch/commit/80f56f86a7519d1ebed62161c796db2880c153f6)] - bump version 162 | * [[`4c5cd25`](https://github.com/devsnek/snekfetch/commit/4c5cd25549bb36f00d12aef041f7167276fd54ee)] - update readme 163 | * [[`6350e96`](https://github.com/devsnek/snekfetch/commit/6350e965b9a97659bd93f0a47eec65b6d224f359)] - remove dev build 164 | * [[`97333e2`](https://github.com/devsnek/snekfetch/commit/97333e2354e977c23bd8b649bcafc1cbddff8e08)] - disable process shim in a hacky way 165 | * [[`d4bf84a`](https://github.com/devsnek/snekfetch/commit/d4bf84a44e0f2cd7fd0da9c52ea692cdb552dd24)] - fix selector error 166 | * [[`6296e7a`](https://github.com/devsnek/snekfetch/commit/6296e7a721c6a62ca67f1419b5de9e68b540f1c2)] - wow it works 167 | * [[`568a1f3`](https://github.com/devsnek/snekfetch/commit/568a1f3206818862a2eea70b97192d93525fa2fd)] - begin rewrite 168 | * [[`feba8ae`](https://github.com/devsnek/snekfetch/commit/feba8ae8ceed8a3bada13503e5a2cfd6a09ac4b4)] - begin rewrite 169 | * [[`a7d2c68`](https://github.com/devsnek/snekfetch/commit/a7d2c68f09b873a0d663c1115de5b11d9d3273b7)] - fix stupid replace error 170 | * [[`b379521`](https://github.com/devsnek/snekfetch/commit/b3795219bc3e67b94c30c072a84c381680e3416d)] - move exports around 171 | * [[`13d6538`](https://github.com/devsnek/snekfetch/commit/13d65386217356e1da9a230233edf30f91011bab)] - remove FormData polyfill from webpack 172 | * [[`a0b55c1`](https://github.com/devsnek/snekfetch/commit/a0b55c1fac15e333602b0fdc6b07fdf05e4e69c4)] - bump version 173 | * [[`4307f7e`](https://github.com/devsnek/snekfetch/commit/4307f7ea7168c4b7f4f12bdf6114bb6cd89af2e2)] - fix webpack 174 | * [[`9a67ea9`](https://github.com/devsnek/snekfetch/commit/9a67ea914a18f053a24a5a372df5690a5988a1b4)] - bump version 175 | * [[`7b4fff6`](https://github.com/devsnek/snekfetch/commit/7b4fff64301580b46668d46e45a88fbd0330b055)] - Merge branch 'master' of https://github.com/devsnek/snekfetch 176 | * [[`21549f7`](https://github.com/devsnek/snekfetch/commit/21549f7edb4a7ea8a6757a7e9322766fe0e5b131)] - fix more small bugs 177 | * [[`434b096`](https://github.com/devsnek/snekfetch/commit/434b0964d75ad4f923e8a39219d5a41595226f99)] - Add license scan report and status (#7) 178 | * [[`bca7b08`](https://github.com/devsnek/snekfetch/commit/bca7b089e562c2e5cdbd22fc62655e1fb5c3fa55)] - add intial http2 support 179 | * [[`f27aa24`](https://github.com/devsnek/snekfetch/commit/f27aa2406a5eeeaec6aa12b478ed14c06e0081c2)] - bump version 180 | * [[`a06e6f1`](https://github.com/devsnek/snekfetch/commit/a06e6f1b513f89ea34f06a4038077f5958abb25e)] - Fix Content-Length header (#6) 181 | * [[`a02c170`](https://github.com/devsnek/snekfetch/commit/a02c170f3ba279d7962a7b0c63453648608bd0ae)] - fix mime buffer checking 182 | * [[`050c91b`](https://github.com/devsnek/snekfetch/commit/050c91b0d170394789416a70b114ecafa247becd)] - fix form uploads 183 | * [[`cf763fc`](https://github.com/devsnek/snekfetch/commit/cf763fcd64a30e4c8c63c84d8b28240119a62563)] - bump version 184 | * [[`75b69ad`](https://github.com/devsnek/snekfetch/commit/75b69ad1f653c57d15d4cc4a68f4968a04e6c6f0)] - add handlers for buffers and streams 185 | * [[`3501019`](https://github.com/devsnek/snekfetch/commit/35010194ea8824e075e96dd2b13e5b94c9b7ee0a)] - so much cool stuff 186 | * [[`b0b160b`](https://github.com/devsnek/snekfetch/commit/b0b160bed114bcc9d71932eac8cbb741351e212c)] - add agent support 187 | * [[`9143280`](https://github.com/devsnek/snekfetch/commit/9143280d1b5f504cf7e2fd4d7a38d359f3db3195)] - Delete .fileLoader.js.swp 188 | * [[`139f09f`](https://github.com/devsnek/snekfetch/commit/139f09f32a670371f07cb78215eab9385d12f41e)] - fix stuff 189 | * [[`5eeae29`](https://github.com/devsnek/snekfetch/commit/5eeae2934d5aeeabea18ef86729d534da696e392)] - Update index.js 190 | * [[`038dada`](https://github.com/devsnek/snekfetch/commit/038dada4aba8ba74423faab20dc1b9768114a3a6)] - Disable Automatic Redirects (#5) 191 | * [[`67f2366`](https://github.com/devsnek/snekfetch/commit/67f2366a6751585958e2a5ca58278edf5a7f21e6)] - help out rollup 192 | * [[`eaf21ae`](https://github.com/devsnek/snekfetch/commit/eaf21ae15646177d7104e20d2b7902acb6e6fed2)] - fix mime bug 193 | * [[`ae936f5`](https://github.com/devsnek/snekfetch/commit/ae936f50d748e77f82905f64ece925e00fdbbb3a)] - bump version 194 | * [[`6f103c9`](https://github.com/devsnek/snekfetch/commit/6f103c9f5ad9037a412413687ddfb7f4557520c9)] - wowee 404s work now 195 | * [[`6b6e8db`](https://github.com/devsnek/snekfetch/commit/6b6e8db679e63ca9f8db7d85202263977f48e922)] - development file read/write 196 | * [[`adf8aa1`](https://github.com/devsnek/snekfetch/commit/adf8aa1b110336be981a2a6617b0469ac5705389)] - this should really be a buffer 197 | * [[`df8d646`](https://github.com/devsnek/snekfetch/commit/df8d6468f608f5cdb5aac1b84a83ced3c1f5eeae)] - docs and lazy load res.body 198 | * [[`f60812f`](https://github.com/devsnek/snekfetch/commit/f60812fe9de9cfa6e0329943e64e5166f926e19e)] - ugh 199 | * [[`cd4bfd9`](https://github.com/devsnek/snekfetch/commit/cd4bfd91bae58076e7a2f210a1ff85d4295490b1)] - merge 200 | * [[`befd0eb`](https://github.com/devsnek/snekfetch/commit/befd0ebaf97317ea888c5e62c7aa52b789d6a0c6)] - i dunno 201 | * [[`1db6103`](https://github.com/devsnek/snekfetch/commit/1db6103ca263c5687ed318358fee863dbad5c2b7)] - fix a thing 202 | * [[`35736c4`](https://github.com/devsnek/snekfetch/commit/35736c42c94fda9709401e31947e2c101fec1c0a)] - add docs 203 | * [[`c5e03b1`](https://github.com/devsnek/snekfetch/commit/c5e03b1b0cf1c4434e82c3205f70ca24c26b5144)] - bump version 204 | * [[`50400f5`](https://github.com/devsnek/snekfetch/commit/50400f50d15fed3f0373dfabecf0e31d4e5fef49)] - fix up checking if response is here 205 | * [[`7c35045`](https://github.com/devsnek/snekfetch/commit/7c35045e9e9dd28bfc5e0a4ed55a3ba2e6d6ecd4)] - bump version 206 | * [[`f47ae61`](https://github.com/devsnek/snekfetch/commit/f47ae6179addc843c76041a5b0a1013c67759729)] - fix stuff 207 | * [[`498c722`](https://github.com/devsnek/snekfetch/commit/498c722dd86ac6428e92a8f490a2d5ad07542853)] - Update package.json 208 | * [[`9830b16`](https://github.com/devsnek/snekfetch/commit/9830b165c395c17b055e0d2c45704209a09ed904)] - fix redirecting 209 | * [[`b03a6bb`](https://github.com/devsnek/snekfetch/commit/b03a6bb7d3b73ac3a4b27c7cfffcfbaa87d38700)] - fix extname 210 | * [[`9b5f0bc`](https://github.com/devsnek/snekfetch/commit/9b5f0bc9700e5d2fc03bc2cdae9e6494d45e6dcd)] - Create PULL_REQUEST_TEMPLATE.md 211 | * [[`37f0341`](https://github.com/devsnek/snekfetch/commit/37f03415473ccc52436590d4741dce40fc49d526)] - Create ISSUE_TEMPLATE.md 212 | * [[`6679e13`](https://github.com/devsnek/snekfetch/commit/6679e138e66f50b3843ba207fc5b0dda1bc76e95)] - friggin stupid issues https://github.com/jhiesey/stream-http/pull/77 213 | * [[`8608de3`](https://github.com/devsnek/snekfetch/commit/8608de3d1af3e8eec3c9a36b710dca72e572a728)] - disable sync 214 | * [[`43e2312`](https://github.com/devsnek/snekfetch/commit/43e23127bb29b5660e04c2431a5c5f3cfc8d9f24)] - this is so unprofessional 215 | * [[`88a2f7e`](https://github.com/devsnek/snekfetch/commit/88a2f7e9d5b319136c92f91fc4e07fe248c91b5f)] - i really hate working with mock libs 216 | * [[`a79f686`](https://github.com/devsnek/snekfetch/commit/a79f6867d21ca58ffe6fc59eb77b06f257f8ad29)] - Update package.json 217 | * [[`8c881ca`](https://github.com/devsnek/snekfetch/commit/8c881ca030ccc67d3dd40c247a85971654279991)] - i hate myself 218 | * [[`e4c9d25`](https://github.com/devsnek/snekfetch/commit/e4c9d25d7da9293f0800b833dc702e1b15ac072e)] - i really shouldn't use webeditor 219 | * [[`e6a467d`](https://github.com/devsnek/snekfetch/commit/e6a467d6d0798873eb0312c0d586b88373dfd2c2)] - Change read() back to _read() 220 | * [[`25647d1`](https://github.com/devsnek/snekfetch/commit/25647d1c4dfbc57198853d5ebc17a01bbea3dd09)] - Fix breaking .getHeader typo 221 | * [[`8a8b2eb`](https://github.com/devsnek/snekfetch/commit/8a8b2eba604450363bf80e8e0caac97157f15820)] - Update package.json 222 | * [[`d6d7364`](https://github.com/devsnek/snekfetch/commit/d6d7364438ce034040655a80e3edb6f0f20ea669)] - Update index.js 223 | * [[`fa1566c`](https://github.com/devsnek/snekfetch/commit/fa1566c04831fa7272e01dff8936e1f5d467dc6b)] - Update index.js 224 | * [[`89ee801`](https://github.com/devsnek/snekfetch/commit/89ee801ae233177b8cbca8e1fd02cd9915264e2b)] - bump version 225 | * [[`0f2f25e`](https://github.com/devsnek/snekfetch/commit/0f2f25e2620de84e41b2ab0465a73af87b3471f2)] - make send smarter 226 | * [[`24077d8`](https://github.com/devsnek/snekfetch/commit/24077d847f1ddf6149c8ae9ce1448f046c94946b)] - optimize 227 | * [[`f94a195`](https://github.com/devsnek/snekfetch/commit/f94a195dc1048a249858a234b691073543172d3b)] - bump to 3.0.3 228 | * [[`06a7a0e`](https://github.com/devsnek/snekfetch/commit/06a7a0ee1e994bae5947faef6730b5607f5e18b0)] - all sorts of cleanup 229 | * [[`1eb5225`](https://github.com/devsnek/snekfetch/commit/1eb52253daa176a2391fc8aab329e7b095f46671)] - better query 230 | * [[`a2dbe10`](https://github.com/devsnek/snekfetch/commit/a2dbe10b308f9d9ffad8debac3f83bab37c1de8a)] - query 231 | * [[`224554f`](https://github.com/devsnek/snekfetch/commit/224554f658db6489deb253b327fbaa53d839c2ca)] - rip 232 | * [[`ebf0c31`](https://github.com/devsnek/snekfetch/commit/ebf0c310c8e1d5c72ec1c1447b0b06b0c868de55)] - remove timeout 233 | * [[`71fa23a`](https://github.com/devsnek/snekfetch/commit/71fa23aec96a4a40ce6acca2ed104db20308c8e6)] - add timeout 234 | * [[`8a54efd`](https://github.com/devsnek/snekfetch/commit/8a54efdb43c46fddea69d83a7b0361f2f59fa7bb)] - fix extremely stupid mistake 235 | * [[`572e34c`](https://github.com/devsnek/snekfetch/commit/572e34c14bd1b78a6287091cfc54784d49a90dc9)] - bump to 3.0.1 236 | * [[`6073d6c`](https://github.com/devsnek/snekfetch/commit/6073d6cbc847dfc3e2f0667b9bd5dc4e1aba7348)] - standardize methods, properly emit errors when piping 237 | * [[`63a0abb`](https://github.com/devsnek/snekfetch/commit/63a0abb0a5863e6cbb19919eb7f5438b8711e142)] - add sync requests for memes not real usage 238 | * [[`390f8f4`](https://github.com/devsnek/snekfetch/commit/390f8f49f0300924fb12ada247c6ff8b1133df5d)] - add sync requests for memes not real usage 239 | * [[`50ae37a`](https://github.com/devsnek/snekfetch/commit/50ae37a558c1dd1b8a345e299a5f23a8987bc9e4)] - add sync requests for memes not real usage 240 | * [[`dd0c84b`](https://github.com/devsnek/snekfetch/commit/dd0c84becf244f4b5157c3874a1f8812ef714c78)] - v3 -------------------------------------------------------------------------------- /src/node/mimes.json: -------------------------------------------------------------------------------- 1 | { 2 | "123": "application/vnd.lotus-1-2-3", 3 | "ez": "application/andrew-inset", 4 | "aw": "application/applixware", 5 | "atom": "application/atom+xml", 6 | "atomcat": "application/atomcat+xml", 7 | "atomsvc": "application/atomsvc+xml", 8 | "bdoc": "application/x-bdoc", 9 | "ccxml": "application/ccxml+xml", 10 | "cdmia": "application/cdmi-capability", 11 | "cdmic": "application/cdmi-container", 12 | "cdmid": "application/cdmi-domain", 13 | "cdmio": "application/cdmi-object", 14 | "cdmiq": "application/cdmi-queue", 15 | "cu": "application/cu-seeme", 16 | "mpd": "application/dash+xml", 17 | "davmount": "application/davmount+xml", 18 | "dbk": "application/docbook+xml", 19 | "dssc": "application/dssc+der", 20 | "xdssc": "application/dssc+xml", 21 | "ecma": "application/ecmascript", 22 | "emma": "application/emma+xml", 23 | "epub": "application/epub+zip", 24 | "exi": "application/exi", 25 | "pfr": "application/font-tdpfr", 26 | "woff": "application/font-woff", 27 | "woff2": "application/font-woff2", 28 | "geojson": "application/geo+json", 29 | "gml": "application/gml+xml", 30 | "gpx": "application/gpx+xml", 31 | "gxf": "application/gxf", 32 | "stk": "application/hyperstudio", 33 | "ink": "application/inkml+xml", 34 | "inkml": "application/inkml+xml", 35 | "ipfix": "application/ipfix", 36 | "jar": "application/java-archive", 37 | "war": "application/java-archive", 38 | "ear": "application/java-archive", 39 | "ser": "application/java-serialized-object", 40 | "class": "application/java-vm", 41 | "js": "application/javascript", 42 | "json": "application/json", 43 | "map": "application/json", 44 | "json5": "application/json5", 45 | "jsonml": "application/jsonml+json", 46 | "jsonld": "application/ld+json", 47 | "lostxml": "application/lost+xml", 48 | "hqx": "application/mac-binhex40", 49 | "cpt": "application/mac-compactpro", 50 | "mads": "application/mads+xml", 51 | "webmanifest": "application/manifest+json", 52 | "mrc": "application/marc", 53 | "mrcx": "application/marcxml+xml", 54 | "ma": "application/mathematica", 55 | "nb": "application/mathematica", 56 | "mb": "application/mathematica", 57 | "mathml": "application/mathml+xml", 58 | "mbox": "application/mbox", 59 | "mscml": "application/mediaservercontrol+xml", 60 | "metalink": "application/metalink+xml", 61 | "meta4": "application/metalink4+xml", 62 | "mets": "application/mets+xml", 63 | "mods": "application/mods+xml", 64 | "m21": "application/mp21", 65 | "mp21": "application/mp21", 66 | "mp4s": "application/mp4", 67 | "m4p": "application/mp4", 68 | "doc": "application/msword", 69 | "dot": "application/msword", 70 | "mxf": "application/mxf", 71 | "bin": "application/octet-stream", 72 | "dms": "application/octet-stream", 73 | "lrf": "application/octet-stream", 74 | "mar": "application/octet-stream", 75 | "so": "application/octet-stream", 76 | "dist": "application/octet-stream", 77 | "distz": "application/octet-stream", 78 | "pkg": "application/octet-stream", 79 | "bpk": "application/octet-stream", 80 | "dump": "application/octet-stream", 81 | "elc": "application/octet-stream", 82 | "deploy": "application/octet-stream", 83 | "exe": "application/x-msdownload", 84 | "dll": "application/x-msdownload", 85 | "deb": "application/x-debian-package", 86 | "dmg": "application/x-apple-diskimage", 87 | "iso": "application/x-iso9660-image", 88 | "img": "application/octet-stream", 89 | "msi": "application/x-msdownload", 90 | "msp": "application/octet-stream", 91 | "msm": "application/octet-stream", 92 | "buffer": "application/octet-stream", 93 | "oda": "application/oda", 94 | "opf": "application/oebps-package+xml", 95 | "ogx": "application/ogg", 96 | "omdoc": "application/omdoc+xml", 97 | "onetoc": "application/onenote", 98 | "onetoc2": "application/onenote", 99 | "onetmp": "application/onenote", 100 | "onepkg": "application/onenote", 101 | "oxps": "application/oxps", 102 | "xer": "application/patch-ops-error+xml", 103 | "pdf": "application/pdf", 104 | "pgp": "application/pgp-encrypted", 105 | "asc": "application/pgp-signature", 106 | "sig": "application/pgp-signature", 107 | "prf": "application/pics-rules", 108 | "p10": "application/pkcs10", 109 | "p7m": "application/pkcs7-mime", 110 | "p7c": "application/pkcs7-mime", 111 | "p7s": "application/pkcs7-signature", 112 | "p8": "application/pkcs8", 113 | "ac": "application/pkix-attr-cert", 114 | "cer": "application/pkix-cert", 115 | "crl": "application/pkix-crl", 116 | "pkipath": "application/pkix-pkipath", 117 | "pki": "application/pkixcmp", 118 | "pls": "application/pls+xml", 119 | "ai": "application/postscript", 120 | "eps": "application/postscript", 121 | "ps": "application/postscript", 122 | "cww": "application/prs.cww", 123 | "pskcxml": "application/pskc+xml", 124 | "rdf": "application/rdf+xml", 125 | "rif": "application/reginfo+xml", 126 | "rnc": "application/relax-ng-compact-syntax", 127 | "rl": "application/resource-lists+xml", 128 | "rld": "application/resource-lists-diff+xml", 129 | "rs": "application/rls-services+xml", 130 | "gbr": "application/rpki-ghostbusters", 131 | "mft": "application/rpki-manifest", 132 | "roa": "application/rpki-roa", 133 | "rsd": "application/rsd+xml", 134 | "rss": "application/rss+xml", 135 | "rtf": "text/rtf", 136 | "sbml": "application/sbml+xml", 137 | "scq": "application/scvp-cv-request", 138 | "scs": "application/scvp-cv-response", 139 | "spq": "application/scvp-vp-request", 140 | "spp": "application/scvp-vp-response", 141 | "sdp": "application/sdp", 142 | "setpay": "application/set-payment-initiation", 143 | "setreg": "application/set-registration-initiation", 144 | "shf": "application/shf+xml", 145 | "smi": "application/smil+xml", 146 | "smil": "application/smil+xml", 147 | "rq": "application/sparql-query", 148 | "srx": "application/sparql-results+xml", 149 | "gram": "application/srgs", 150 | "grxml": "application/srgs+xml", 151 | "sru": "application/sru+xml", 152 | "ssdl": "application/ssdl+xml", 153 | "ssml": "application/ssml+xml", 154 | "tei": "application/tei+xml", 155 | "teicorpus": "application/tei+xml", 156 | "tfi": "application/thraud+xml", 157 | "tsd": "application/timestamped-data", 158 | "plb": "application/vnd.3gpp.pic-bw-large", 159 | "psb": "application/vnd.3gpp.pic-bw-small", 160 | "pvb": "application/vnd.3gpp.pic-bw-var", 161 | "tcap": "application/vnd.3gpp2.tcap", 162 | "pwn": "application/vnd.3m.post-it-notes", 163 | "aso": "application/vnd.accpac.simply.aso", 164 | "imp": "application/vnd.accpac.simply.imp", 165 | "acu": "application/vnd.acucobol", 166 | "atc": "application/vnd.acucorp", 167 | "acutc": "application/vnd.acucorp", 168 | "air": "application/vnd.adobe.air-application-installer-package+zip", 169 | "fcdt": "application/vnd.adobe.formscentral.fcdt", 170 | "fxp": "application/vnd.adobe.fxp", 171 | "fxpl": "application/vnd.adobe.fxp", 172 | "xdp": "application/vnd.adobe.xdp+xml", 173 | "xfdf": "application/vnd.adobe.xfdf", 174 | "ahead": "application/vnd.ahead.space", 175 | "azf": "application/vnd.airzip.filesecure.azf", 176 | "azs": "application/vnd.airzip.filesecure.azs", 177 | "azw": "application/vnd.amazon.ebook", 178 | "acc": "application/vnd.americandynamics.acc", 179 | "ami": "application/vnd.amiga.ami", 180 | "apk": "application/vnd.android.package-archive", 181 | "cii": "application/vnd.anser-web-certificate-issue-initiation", 182 | "fti": "application/vnd.anser-web-funds-transfer-initiation", 183 | "atx": "application/vnd.antix.game-component", 184 | "mpkg": "application/vnd.apple.installer+xml", 185 | "m3u8": "application/vnd.apple.mpegurl", 186 | "pkpass": "application/vnd.apple.pkpass", 187 | "swi": "application/vnd.aristanetworks.swi", 188 | "iota": "application/vnd.astraea-software.iota", 189 | "aep": "application/vnd.audiograph", 190 | "mpm": "application/vnd.blueice.multipass", 191 | "bmi": "application/vnd.bmi", 192 | "rep": "application/vnd.businessobjects", 193 | "cdxml": "application/vnd.chemdraw+xml", 194 | "mmd": "application/vnd.chipnuts.karaoke-mmd", 195 | "cdy": "application/vnd.cinderella", 196 | "cla": "application/vnd.claymore", 197 | "rp9": "application/vnd.cloanto.rp9", 198 | "c4g": "application/vnd.clonk.c4group", 199 | "c4d": "application/vnd.clonk.c4group", 200 | "c4f": "application/vnd.clonk.c4group", 201 | "c4p": "application/vnd.clonk.c4group", 202 | "c4u": "application/vnd.clonk.c4group", 203 | "c11amc": "application/vnd.cluetrust.cartomobile-config", 204 | "c11amz": "application/vnd.cluetrust.cartomobile-config-pkg", 205 | "csp": "application/vnd.commonspace", 206 | "cdbcmsg": "application/vnd.contact.cmsg", 207 | "cmc": "application/vnd.cosmocaller", 208 | "clkx": "application/vnd.crick.clicker", 209 | "clkk": "application/vnd.crick.clicker.keyboard", 210 | "clkp": "application/vnd.crick.clicker.palette", 211 | "clkt": "application/vnd.crick.clicker.template", 212 | "clkw": "application/vnd.crick.clicker.wordbank", 213 | "wbs": "application/vnd.criticaltools.wbs+xml", 214 | "pml": "application/vnd.ctc-posml", 215 | "ppd": "application/vnd.cups-ppd", 216 | "car": "application/vnd.curl.car", 217 | "pcurl": "application/vnd.curl.pcurl", 218 | "dart": "application/vnd.dart", 219 | "rdz": "application/vnd.data-vision.rdz", 220 | "uvf": "application/vnd.dece.data", 221 | "uvvf": "application/vnd.dece.data", 222 | "uvd": "application/vnd.dece.data", 223 | "uvvd": "application/vnd.dece.data", 224 | "uvt": "application/vnd.dece.ttml+xml", 225 | "uvvt": "application/vnd.dece.ttml+xml", 226 | "uvx": "application/vnd.dece.unspecified", 227 | "uvvx": "application/vnd.dece.unspecified", 228 | "uvz": "application/vnd.dece.zip", 229 | "uvvz": "application/vnd.dece.zip", 230 | "fe_launch": "application/vnd.denovo.fcselayout-link", 231 | "dna": "application/vnd.dna", 232 | "mlp": "application/vnd.dolby.mlp", 233 | "dpg": "application/vnd.dpgraph", 234 | "dfac": "application/vnd.dreamfactory", 235 | "kpxx": "application/vnd.ds-keypoint", 236 | "ait": "application/vnd.dvb.ait", 237 | "svc": "application/vnd.dvb.service", 238 | "geo": "application/vnd.dynageo", 239 | "mag": "application/vnd.ecowin.chart", 240 | "nml": "application/vnd.enliven", 241 | "esf": "application/vnd.epson.esf", 242 | "msf": "application/vnd.epson.msf", 243 | "qam": "application/vnd.epson.quickanime", 244 | "slt": "application/vnd.epson.salt", 245 | "ssf": "application/vnd.epson.ssf", 246 | "es3": "application/vnd.eszigno3+xml", 247 | "et3": "application/vnd.eszigno3+xml", 248 | "ez2": "application/vnd.ezpix-album", 249 | "ez3": "application/vnd.ezpix-package", 250 | "fdf": "application/vnd.fdf", 251 | "mseed": "application/vnd.fdsn.mseed", 252 | "seed": "application/vnd.fdsn.seed", 253 | "dataless": "application/vnd.fdsn.seed", 254 | "gph": "application/vnd.flographit", 255 | "ftc": "application/vnd.fluxtime.clip", 256 | "fm": "application/vnd.framemaker", 257 | "frame": "application/vnd.framemaker", 258 | "maker": "application/vnd.framemaker", 259 | "book": "application/vnd.framemaker", 260 | "fnc": "application/vnd.frogans.fnc", 261 | "ltf": "application/vnd.frogans.ltf", 262 | "fsc": "application/vnd.fsc.weblaunch", 263 | "oas": "application/vnd.fujitsu.oasys", 264 | "oa2": "application/vnd.fujitsu.oasys2", 265 | "oa3": "application/vnd.fujitsu.oasys3", 266 | "fg5": "application/vnd.fujitsu.oasysgp", 267 | "bh2": "application/vnd.fujitsu.oasysprs", 268 | "ddd": "application/vnd.fujixerox.ddd", 269 | "xdw": "application/vnd.fujixerox.docuworks", 270 | "xbd": "application/vnd.fujixerox.docuworks.binder", 271 | "fzs": "application/vnd.fuzzysheet", 272 | "txd": "application/vnd.genomatix.tuxedo", 273 | "ggb": "application/vnd.geogebra.file", 274 | "ggt": "application/vnd.geogebra.tool", 275 | "gex": "application/vnd.geometry-explorer", 276 | "gre": "application/vnd.geometry-explorer", 277 | "gxt": "application/vnd.geonext", 278 | "g2w": "application/vnd.geoplan", 279 | "g3w": "application/vnd.geospace", 280 | "gmx": "application/vnd.gmx", 281 | "gdoc": "application/vnd.google-apps.document", 282 | "gslides": "application/vnd.google-apps.presentation", 283 | "gsheet": "application/vnd.google-apps.spreadsheet", 284 | "kml": "application/vnd.google-earth.kml+xml", 285 | "kmz": "application/vnd.google-earth.kmz", 286 | "gqf": "application/vnd.grafeq", 287 | "gqs": "application/vnd.grafeq", 288 | "gac": "application/vnd.groove-account", 289 | "ghf": "application/vnd.groove-help", 290 | "gim": "application/vnd.groove-identity-message", 291 | "grv": "application/vnd.groove-injector", 292 | "gtm": "application/vnd.groove-tool-message", 293 | "tpl": "application/vnd.groove-tool-template", 294 | "vcg": "application/vnd.groove-vcard", 295 | "hal": "application/vnd.hal+xml", 296 | "zmm": "application/vnd.handheld-entertainment+xml", 297 | "hbci": "application/vnd.hbci", 298 | "les": "application/vnd.hhe.lesson-player", 299 | "hpgl": "application/vnd.hp-hpgl", 300 | "hpid": "application/vnd.hp-hpid", 301 | "hps": "application/vnd.hp-hps", 302 | "jlt": "application/vnd.hp-jlyt", 303 | "pcl": "application/vnd.hp-pcl", 304 | "pclxl": "application/vnd.hp-pclxl", 305 | "sfd-hdstx": "application/vnd.hydrostatix.sof-data", 306 | "mpy": "application/vnd.ibm.minipay", 307 | "afp": "application/vnd.ibm.modcap", 308 | "listafp": "application/vnd.ibm.modcap", 309 | "list3820": "application/vnd.ibm.modcap", 310 | "irm": "application/vnd.ibm.rights-management", 311 | "sc": "application/vnd.ibm.secure-container", 312 | "icc": "application/vnd.iccprofile", 313 | "icm": "application/vnd.iccprofile", 314 | "igl": "application/vnd.igloader", 315 | "ivp": "application/vnd.immervision-ivp", 316 | "ivu": "application/vnd.immervision-ivu", 317 | "igm": "application/vnd.insors.igm", 318 | "xpw": "application/vnd.intercon.formnet", 319 | "xpx": "application/vnd.intercon.formnet", 320 | "i2g": "application/vnd.intergeo", 321 | "qbo": "application/vnd.intu.qbo", 322 | "qfx": "application/vnd.intu.qfx", 323 | "rcprofile": "application/vnd.ipunplugged.rcprofile", 324 | "irp": "application/vnd.irepository.package+xml", 325 | "xpr": "application/vnd.is-xpr", 326 | "fcs": "application/vnd.isac.fcs", 327 | "jam": "application/vnd.jam", 328 | "rms": "application/vnd.jcp.javame.midlet-rms", 329 | "jisp": "application/vnd.jisp", 330 | "joda": "application/vnd.joost.joda-archive", 331 | "ktz": "application/vnd.kahootz", 332 | "ktr": "application/vnd.kahootz", 333 | "karbon": "application/vnd.kde.karbon", 334 | "chrt": "application/vnd.kde.kchart", 335 | "kfo": "application/vnd.kde.kformula", 336 | "flw": "application/vnd.kde.kivio", 337 | "kon": "application/vnd.kde.kontour", 338 | "kpr": "application/vnd.kde.kpresenter", 339 | "kpt": "application/vnd.kde.kpresenter", 340 | "ksp": "application/vnd.kde.kspread", 341 | "kwd": "application/vnd.kde.kword", 342 | "kwt": "application/vnd.kde.kword", 343 | "htke": "application/vnd.kenameaapp", 344 | "kia": "application/vnd.kidspiration", 345 | "kne": "application/vnd.kinar", 346 | "knp": "application/vnd.kinar", 347 | "skp": "application/vnd.koan", 348 | "skd": "application/vnd.koan", 349 | "skt": "application/vnd.koan", 350 | "skm": "application/vnd.koan", 351 | "sse": "application/vnd.kodak-descriptor", 352 | "lasxml": "application/vnd.las.las+xml", 353 | "lbd": "application/vnd.llamagraphics.life-balance.desktop", 354 | "lbe": "application/vnd.llamagraphics.life-balance.exchange+xml", 355 | "apr": "application/vnd.lotus-approach", 356 | "pre": "application/vnd.lotus-freelance", 357 | "nsf": "application/vnd.lotus-notes", 358 | "org": "application/vnd.lotus-organizer", 359 | "scm": "application/vnd.lotus-screencam", 360 | "lwp": "application/vnd.lotus-wordpro", 361 | "portpkg": "application/vnd.macports.portpkg", 362 | "mcd": "application/vnd.mcd", 363 | "mc1": "application/vnd.medcalcdata", 364 | "cdkey": "application/vnd.mediastation.cdkey", 365 | "mwf": "application/vnd.mfer", 366 | "mfm": "application/vnd.mfmp", 367 | "flo": "application/vnd.micrografx.flo", 368 | "igx": "application/vnd.micrografx.igx", 369 | "mif": "application/vnd.mif", 370 | "daf": "application/vnd.mobius.daf", 371 | "dis": "application/vnd.mobius.dis", 372 | "mbk": "application/vnd.mobius.mbk", 373 | "mqy": "application/vnd.mobius.mqy", 374 | "msl": "application/vnd.mobius.msl", 375 | "plc": "application/vnd.mobius.plc", 376 | "txf": "application/vnd.mobius.txf", 377 | "mpn": "application/vnd.mophun.application", 378 | "mpc": "application/vnd.mophun.certificate", 379 | "xul": "application/vnd.mozilla.xul+xml", 380 | "cil": "application/vnd.ms-artgalry", 381 | "cab": "application/vnd.ms-cab-compressed", 382 | "xls": "application/vnd.ms-excel", 383 | "xlm": "application/vnd.ms-excel", 384 | "xla": "application/vnd.ms-excel", 385 | "xlc": "application/vnd.ms-excel", 386 | "xlt": "application/vnd.ms-excel", 387 | "xlw": "application/vnd.ms-excel", 388 | "xlam": "application/vnd.ms-excel.addin.macroenabled.12", 389 | "xlsb": "application/vnd.ms-excel.sheet.binary.macroenabled.12", 390 | "xlsm": "application/vnd.ms-excel.sheet.macroenabled.12", 391 | "xltm": "application/vnd.ms-excel.template.macroenabled.12", 392 | "eot": "application/vnd.ms-fontobject", 393 | "chm": "application/vnd.ms-htmlhelp", 394 | "ims": "application/vnd.ms-ims", 395 | "lrm": "application/vnd.ms-lrm", 396 | "thmx": "application/vnd.ms-officetheme", 397 | "cat": "application/vnd.ms-pki.seccat", 398 | "stl": "application/vnd.ms-pki.stl", 399 | "ppt": "application/vnd.ms-powerpoint", 400 | "pps": "application/vnd.ms-powerpoint", 401 | "pot": "application/vnd.ms-powerpoint", 402 | "ppam": "application/vnd.ms-powerpoint.addin.macroenabled.12", 403 | "pptm": "application/vnd.ms-powerpoint.presentation.macroenabled.12", 404 | "sldm": "application/vnd.ms-powerpoint.slide.macroenabled.12", 405 | "ppsm": "application/vnd.ms-powerpoint.slideshow.macroenabled.12", 406 | "potm": "application/vnd.ms-powerpoint.template.macroenabled.12", 407 | "mpp": "application/vnd.ms-project", 408 | "mpt": "application/vnd.ms-project", 409 | "docm": "application/vnd.ms-word.document.macroenabled.12", 410 | "dotm": "application/vnd.ms-word.template.macroenabled.12", 411 | "wps": "application/vnd.ms-works", 412 | "wks": "application/vnd.ms-works", 413 | "wcm": "application/vnd.ms-works", 414 | "wdb": "application/vnd.ms-works", 415 | "wpl": "application/vnd.ms-wpl", 416 | "xps": "application/vnd.ms-xpsdocument", 417 | "mseq": "application/vnd.mseq", 418 | "mus": "application/vnd.musician", 419 | "msty": "application/vnd.muvee.style", 420 | "taglet": "application/vnd.mynfc", 421 | "nlu": "application/vnd.neurolanguage.nlu", 422 | "ntf": "application/vnd.nitf", 423 | "nitf": "application/vnd.nitf", 424 | "nnd": "application/vnd.noblenet-directory", 425 | "nns": "application/vnd.noblenet-sealer", 426 | "nnw": "application/vnd.noblenet-web", 427 | "ngdat": "application/vnd.nokia.n-gage.data", 428 | "n-gage": "application/vnd.nokia.n-gage.symbian.install", 429 | "rpst": "application/vnd.nokia.radio-preset", 430 | "rpss": "application/vnd.nokia.radio-presets", 431 | "edm": "application/vnd.novadigm.edm", 432 | "edx": "application/vnd.novadigm.edx", 433 | "ext": "application/vnd.novadigm.ext", 434 | "odc": "application/vnd.oasis.opendocument.chart", 435 | "otc": "application/vnd.oasis.opendocument.chart-template", 436 | "odb": "application/vnd.oasis.opendocument.database", 437 | "odf": "application/vnd.oasis.opendocument.formula", 438 | "odft": "application/vnd.oasis.opendocument.formula-template", 439 | "odg": "application/vnd.oasis.opendocument.graphics", 440 | "otg": "application/vnd.oasis.opendocument.graphics-template", 441 | "odi": "application/vnd.oasis.opendocument.image", 442 | "oti": "application/vnd.oasis.opendocument.image-template", 443 | "odp": "application/vnd.oasis.opendocument.presentation", 444 | "otp": "application/vnd.oasis.opendocument.presentation-template", 445 | "ods": "application/vnd.oasis.opendocument.spreadsheet", 446 | "ots": "application/vnd.oasis.opendocument.spreadsheet-template", 447 | "odt": "application/vnd.oasis.opendocument.text", 448 | "odm": "application/vnd.oasis.opendocument.text-master", 449 | "ott": "application/vnd.oasis.opendocument.text-template", 450 | "oth": "application/vnd.oasis.opendocument.text-web", 451 | "xo": "application/vnd.olpc-sugar", 452 | "dd2": "application/vnd.oma.dd2+xml", 453 | "oxt": "application/vnd.openofficeorg.extension", 454 | "pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation", 455 | "sldx": "application/vnd.openxmlformats-officedocument.presentationml.slide", 456 | "ppsx": "application/vnd.openxmlformats-officedocument.presentationml.slideshow", 457 | "potx": "application/vnd.openxmlformats-officedocument.presentationml.template", 458 | "xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", 459 | "xltx": "application/vnd.openxmlformats-officedocument.spreadsheetml.template", 460 | "docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", 461 | "dotx": "application/vnd.openxmlformats-officedocument.wordprocessingml.template", 462 | "mgp": "application/vnd.osgeo.mapguide.package", 463 | "dp": "application/vnd.osgi.dp", 464 | "esa": "application/vnd.osgi.subsystem", 465 | "pdb": "application/x-pilot", 466 | "pqa": "application/vnd.palm", 467 | "oprc": "application/vnd.palm", 468 | "paw": "application/vnd.pawaafile", 469 | "str": "application/vnd.pg.format", 470 | "ei6": "application/vnd.pg.osasli", 471 | "efif": "application/vnd.picsel", 472 | "wg": "application/vnd.pmi.widget", 473 | "plf": "application/vnd.pocketlearn", 474 | "pbd": "application/vnd.powerbuilder6", 475 | "box": "application/vnd.previewsystems.box", 476 | "mgz": "application/vnd.proteus.magazine", 477 | "qps": "application/vnd.publishare-delta-tree", 478 | "ptid": "application/vnd.pvi.ptid1", 479 | "qxd": "application/vnd.quark.quarkxpress", 480 | "qxt": "application/vnd.quark.quarkxpress", 481 | "qwd": "application/vnd.quark.quarkxpress", 482 | "qwt": "application/vnd.quark.quarkxpress", 483 | "qxl": "application/vnd.quark.quarkxpress", 484 | "qxb": "application/vnd.quark.quarkxpress", 485 | "bed": "application/vnd.realvnc.bed", 486 | "mxl": "application/vnd.recordare.musicxml", 487 | "musicxml": "application/vnd.recordare.musicxml+xml", 488 | "cryptonote": "application/vnd.rig.cryptonote", 489 | "cod": "application/vnd.rim.cod", 490 | "rm": "application/vnd.rn-realmedia", 491 | "rmvb": "application/vnd.rn-realmedia-vbr", 492 | "link66": "application/vnd.route66.link66+xml", 493 | "st": "application/vnd.sailingtracker.track", 494 | "see": "application/vnd.seemail", 495 | "sema": "application/vnd.sema", 496 | "semd": "application/vnd.semd", 497 | "semf": "application/vnd.semf", 498 | "ifm": "application/vnd.shana.informed.formdata", 499 | "itp": "application/vnd.shana.informed.formtemplate", 500 | "iif": "application/vnd.shana.informed.interchange", 501 | "ipk": "application/vnd.shana.informed.package", 502 | "twd": "application/vnd.simtech-mindmapper", 503 | "twds": "application/vnd.simtech-mindmapper", 504 | "mmf": "application/vnd.smaf", 505 | "teacher": "application/vnd.smart.teacher", 506 | "sdkm": "application/vnd.solent.sdkm+xml", 507 | "sdkd": "application/vnd.solent.sdkm+xml", 508 | "dxp": "application/vnd.spotfire.dxp", 509 | "sfs": "application/vnd.spotfire.sfs", 510 | "sdc": "application/vnd.stardivision.calc", 511 | "sda": "application/vnd.stardivision.draw", 512 | "sdd": "application/vnd.stardivision.impress", 513 | "smf": "application/vnd.stardivision.math", 514 | "sdw": "application/vnd.stardivision.writer", 515 | "vor": "application/vnd.stardivision.writer", 516 | "sgl": "application/vnd.stardivision.writer-global", 517 | "smzip": "application/vnd.stepmania.package", 518 | "sm": "application/vnd.stepmania.stepchart", 519 | "sxc": "application/vnd.sun.xml.calc", 520 | "stc": "application/vnd.sun.xml.calc.template", 521 | "sxd": "application/vnd.sun.xml.draw", 522 | "std": "application/vnd.sun.xml.draw.template", 523 | "sxi": "application/vnd.sun.xml.impress", 524 | "sti": "application/vnd.sun.xml.impress.template", 525 | "sxm": "application/vnd.sun.xml.math", 526 | "sxw": "application/vnd.sun.xml.writer", 527 | "sxg": "application/vnd.sun.xml.writer.global", 528 | "stw": "application/vnd.sun.xml.writer.template", 529 | "sus": "application/vnd.sus-calendar", 530 | "susp": "application/vnd.sus-calendar", 531 | "svd": "application/vnd.svd", 532 | "sis": "application/vnd.symbian.install", 533 | "sisx": "application/vnd.symbian.install", 534 | "xsm": "application/vnd.syncml+xml", 535 | "bdm": "application/vnd.syncml.dm+wbxml", 536 | "xdm": "application/vnd.syncml.dm+xml", 537 | "tao": "application/vnd.tao.intent-module-archive", 538 | "pcap": "application/vnd.tcpdump.pcap", 539 | "cap": "application/vnd.tcpdump.pcap", 540 | "dmp": "application/vnd.tcpdump.pcap", 541 | "tmo": "application/vnd.tmobile-livetv", 542 | "tpt": "application/vnd.trid.tpt", 543 | "mxs": "application/vnd.triscape.mxs", 544 | "tra": "application/vnd.trueapp", 545 | "ufd": "application/vnd.ufdl", 546 | "ufdl": "application/vnd.ufdl", 547 | "utz": "application/vnd.uiq.theme", 548 | "umj": "application/vnd.umajin", 549 | "unityweb": "application/vnd.unity", 550 | "uoml": "application/vnd.uoml+xml", 551 | "vcx": "application/vnd.vcx", 552 | "vsd": "application/vnd.visio", 553 | "vst": "application/vnd.visio", 554 | "vss": "application/vnd.visio", 555 | "vsw": "application/vnd.visio", 556 | "vis": "application/vnd.visionary", 557 | "vsf": "application/vnd.vsf", 558 | "wbxml": "application/vnd.wap.wbxml", 559 | "wmlc": "application/vnd.wap.wmlc", 560 | "wmlsc": "application/vnd.wap.wmlscriptc", 561 | "wtb": "application/vnd.webturbo", 562 | "nbp": "application/vnd.wolfram.player", 563 | "wpd": "application/vnd.wordperfect", 564 | "wqd": "application/vnd.wqd", 565 | "stf": "application/vnd.wt.stf", 566 | "xar": "application/vnd.xara", 567 | "xfdl": "application/vnd.xfdl", 568 | "hvd": "application/vnd.yamaha.hv-dic", 569 | "hvs": "application/vnd.yamaha.hv-script", 570 | "hvp": "application/vnd.yamaha.hv-voice", 571 | "osf": "application/vnd.yamaha.openscoreformat", 572 | "osfpvg": "application/vnd.yamaha.openscoreformat.osfpvg+xml", 573 | "saf": "application/vnd.yamaha.smaf-audio", 574 | "spf": "application/vnd.yamaha.smaf-phrase", 575 | "cmp": "application/vnd.yellowriver-custom-menu", 576 | "zir": "application/vnd.zul", 577 | "zirz": "application/vnd.zul", 578 | "zaz": "application/vnd.zzazz.deck+xml", 579 | "vxml": "application/voicexml+xml", 580 | "wgt": "application/widget", 581 | "hlp": "application/winhlp", 582 | "wsdl": "application/wsdl+xml", 583 | "wspolicy": "application/wspolicy+xml", 584 | "7z": "application/x-7z-compressed", 585 | "abw": "application/x-abiword", 586 | "ace": "application/x-ace-compressed", 587 | "aab": "application/x-authorware-bin", 588 | "x32": "application/x-authorware-bin", 589 | "u32": "application/x-authorware-bin", 590 | "vox": "application/x-authorware-bin", 591 | "aam": "application/x-authorware-map", 592 | "aas": "application/x-authorware-seg", 593 | "bcpio": "application/x-bcpio", 594 | "torrent": "application/x-bittorrent", 595 | "blb": "application/x-blorb", 596 | "blorb": "application/x-blorb", 597 | "bz": "application/x-bzip", 598 | "bz2": "application/x-bzip2", 599 | "boz": "application/x-bzip2", 600 | "cbr": "application/x-cbr", 601 | "cba": "application/x-cbr", 602 | "cbt": "application/x-cbr", 603 | "cbz": "application/x-cbr", 604 | "cb7": "application/x-cbr", 605 | "vcd": "application/x-cdlink", 606 | "cfs": "application/x-cfs-compressed", 607 | "chat": "application/x-chat", 608 | "pgn": "application/x-chess-pgn", 609 | "crx": "application/x-chrome-extension", 610 | "cco": "application/x-cocoa", 611 | "nsc": "application/x-conference", 612 | "cpio": "application/x-cpio", 613 | "csh": "application/x-csh", 614 | "udeb": "application/x-debian-package", 615 | "dgc": "application/x-dgc-compressed", 616 | "dir": "application/x-director", 617 | "dcr": "application/x-director", 618 | "dxr": "application/x-director", 619 | "cst": "application/x-director", 620 | "cct": "application/x-director", 621 | "cxt": "application/x-director", 622 | "w3d": "application/x-director", 623 | "fgd": "application/x-director", 624 | "swa": "application/x-director", 625 | "wad": "application/x-doom", 626 | "ncx": "application/x-dtbncx+xml", 627 | "dtb": "application/x-dtbook+xml", 628 | "res": "application/x-dtbresource+xml", 629 | "dvi": "application/x-dvi", 630 | "evy": "application/x-envoy", 631 | "eva": "application/x-eva", 632 | "bdf": "application/x-font-bdf", 633 | "gsf": "application/x-font-ghostscript", 634 | "psf": "application/x-font-linux-psf", 635 | "otf": "font/opentype", 636 | "pcf": "application/x-font-pcf", 637 | "snf": "application/x-font-snf", 638 | "ttf": "application/x-font-ttf", 639 | "ttc": "application/x-font-ttf", 640 | "pfa": "application/x-font-type1", 641 | "pfb": "application/x-font-type1", 642 | "pfm": "application/x-font-type1", 643 | "afm": "application/x-font-type1", 644 | "arc": "application/x-freearc", 645 | "spl": "application/x-futuresplash", 646 | "gca": "application/x-gca-compressed", 647 | "ulx": "application/x-glulx", 648 | "gnumeric": "application/x-gnumeric", 649 | "gramps": "application/x-gramps-xml", 650 | "gtar": "application/x-gtar", 651 | "hdf": "application/x-hdf", 652 | "php": "application/x-httpd-php", 653 | "install": "application/x-install-instructions", 654 | "jardiff": "application/x-java-archive-diff", 655 | "jnlp": "application/x-java-jnlp-file", 656 | "latex": "application/x-latex", 657 | "luac": "application/x-lua-bytecode", 658 | "lzh": "application/x-lzh-compressed", 659 | "lha": "application/x-lzh-compressed", 660 | "run": "application/x-makeself", 661 | "mie": "application/x-mie", 662 | "prc": "application/x-pilot", 663 | "mobi": "application/x-mobipocket-ebook", 664 | "application": "application/x-ms-application", 665 | "lnk": "application/x-ms-shortcut", 666 | "wmd": "application/x-ms-wmd", 667 | "wmz": "application/x-msmetafile", 668 | "xbap": "application/x-ms-xbap", 669 | "mdb": "application/x-msaccess", 670 | "obd": "application/x-msbinder", 671 | "crd": "application/x-mscardfile", 672 | "clp": "application/x-msclip", 673 | "com": "application/x-msdownload", 674 | "bat": "application/x-msdownload", 675 | "mvb": "application/x-msmediaview", 676 | "m13": "application/x-msmediaview", 677 | "m14": "application/x-msmediaview", 678 | "wmf": "application/x-msmetafile", 679 | "emf": "application/x-msmetafile", 680 | "emz": "application/x-msmetafile", 681 | "mny": "application/x-msmoney", 682 | "pub": "application/x-mspublisher", 683 | "scd": "application/x-msschedule", 684 | "trm": "application/x-msterminal", 685 | "wri": "application/x-mswrite", 686 | "nc": "application/x-netcdf", 687 | "cdf": "application/x-netcdf", 688 | "pac": "application/x-ns-proxy-autoconfig", 689 | "nzb": "application/x-nzb", 690 | "pl": "application/x-perl", 691 | "pm": "application/x-perl", 692 | "p12": "application/x-pkcs12", 693 | "pfx": "application/x-pkcs12", 694 | "p7b": "application/x-pkcs7-certificates", 695 | "spc": "application/x-pkcs7-certificates", 696 | "p7r": "application/x-pkcs7-certreqresp", 697 | "rar": "application/x-rar-compressed", 698 | "rpm": "application/x-redhat-package-manager", 699 | "ris": "application/x-research-info-systems", 700 | "sea": "application/x-sea", 701 | "sh": "application/x-sh", 702 | "shar": "application/x-shar", 703 | "swf": "application/x-shockwave-flash", 704 | "xap": "application/x-silverlight-app", 705 | "sql": "application/x-sql", 706 | "sit": "application/x-stuffit", 707 | "sitx": "application/x-stuffitx", 708 | "srt": "application/x-subrip", 709 | "sv4cpio": "application/x-sv4cpio", 710 | "sv4crc": "application/x-sv4crc", 711 | "t3": "application/x-t3vm-image", 712 | "gam": "application/x-tads", 713 | "tar": "application/x-tar", 714 | "tcl": "application/x-tcl", 715 | "tk": "application/x-tcl", 716 | "tex": "application/x-tex", 717 | "tfm": "application/x-tex-tfm", 718 | "texinfo": "application/x-texinfo", 719 | "texi": "application/x-texinfo", 720 | "obj": "application/x-tgif", 721 | "ustar": "application/x-ustar", 722 | "src": "application/x-wais-source", 723 | "webapp": "application/x-web-app-manifest+json", 724 | "der": "application/x-x509-ca-cert", 725 | "crt": "application/x-x509-ca-cert", 726 | "pem": "application/x-x509-ca-cert", 727 | "fig": "application/x-xfig", 728 | "xlf": "application/x-xliff+xml", 729 | "xpi": "application/x-xpinstall", 730 | "xz": "application/x-xz", 731 | "z1": "application/x-zmachine", 732 | "z2": "application/x-zmachine", 733 | "z3": "application/x-zmachine", 734 | "z4": "application/x-zmachine", 735 | "z5": "application/x-zmachine", 736 | "z6": "application/x-zmachine", 737 | "z7": "application/x-zmachine", 738 | "z8": "application/x-zmachine", 739 | "xaml": "application/xaml+xml", 740 | "xdf": "application/xcap-diff+xml", 741 | "xenc": "application/xenc+xml", 742 | "xhtml": "application/xhtml+xml", 743 | "xht": "application/xhtml+xml", 744 | "xml": "text/xml", 745 | "xsl": "application/xml", 746 | "xsd": "application/xml", 747 | "rng": "application/xml", 748 | "dtd": "application/xml-dtd", 749 | "xop": "application/xop+xml", 750 | "xpl": "application/xproc+xml", 751 | "xslt": "application/xslt+xml", 752 | "xspf": "application/xspf+xml", 753 | "mxml": "application/xv+xml", 754 | "xhvml": "application/xv+xml", 755 | "xvml": "application/xv+xml", 756 | "xvm": "application/xv+xml", 757 | "yang": "application/yang", 758 | "yin": "application/yin+xml", 759 | "zip": "application/zip", 760 | "3gpp": "video/3gpp", 761 | "adp": "audio/adpcm", 762 | "au": "audio/basic", 763 | "snd": "audio/basic", 764 | "mid": "audio/midi", 765 | "midi": "audio/midi", 766 | "kar": "audio/midi", 767 | "rmi": "audio/midi", 768 | "mp3": "audio/mpeg", 769 | "m4a": "audio/x-m4a", 770 | "mp4a": "audio/mp4", 771 | "mpga": "audio/mpeg", 772 | "mp2": "audio/mpeg", 773 | "mp2a": "audio/mpeg", 774 | "m2a": "audio/mpeg", 775 | "m3a": "audio/mpeg", 776 | "oga": "audio/ogg", 777 | "ogg": "audio/ogg", 778 | "spx": "audio/ogg", 779 | "s3m": "audio/s3m", 780 | "sil": "audio/silk", 781 | "uva": "audio/vnd.dece.audio", 782 | "uvva": "audio/vnd.dece.audio", 783 | "eol": "audio/vnd.digital-winds", 784 | "dra": "audio/vnd.dra", 785 | "dts": "audio/vnd.dts", 786 | "dtshd": "audio/vnd.dts.hd", 787 | "lvp": "audio/vnd.lucent.voice", 788 | "pya": "audio/vnd.ms-playready.media.pya", 789 | "ecelp4800": "audio/vnd.nuera.ecelp4800", 790 | "ecelp7470": "audio/vnd.nuera.ecelp7470", 791 | "ecelp9600": "audio/vnd.nuera.ecelp9600", 792 | "rip": "audio/vnd.rip", 793 | "wav": "audio/x-wav", 794 | "weba": "audio/webm", 795 | "aac": "audio/x-aac", 796 | "aif": "audio/x-aiff", 797 | "aiff": "audio/x-aiff", 798 | "aifc": "audio/x-aiff", 799 | "caf": "audio/x-caf", 800 | "flac": "audio/x-flac", 801 | "mka": "audio/x-matroska", 802 | "m3u": "audio/x-mpegurl", 803 | "wax": "audio/x-ms-wax", 804 | "wma": "audio/x-ms-wma", 805 | "ram": "audio/x-pn-realaudio", 806 | "ra": "audio/x-realaudio", 807 | "rmp": "audio/x-pn-realaudio-plugin", 808 | "xm": "audio/xm", 809 | "cdx": "chemical/x-cdx", 810 | "cif": "chemical/x-cif", 811 | "cmdf": "chemical/x-cmdf", 812 | "cml": "chemical/x-cml", 813 | "csml": "chemical/x-csml", 814 | "xyz": "chemical/x-xyz", 815 | "bmp": "image/x-ms-bmp", 816 | "cgm": "image/cgm", 817 | "g3": "image/g3fax", 818 | "gif": "image/gif", 819 | "ief": "image/ief", 820 | "jpeg": "image/jpeg", 821 | "jpg": "image/jpeg", 822 | "jpe": "image/jpeg", 823 | "ktx": "image/ktx", 824 | "png": "image/png", 825 | "btif": "image/prs.btif", 826 | "sgi": "image/sgi", 827 | "svg": "image/svg+xml", 828 | "svgz": "image/svg+xml", 829 | "tiff": "image/tiff", 830 | "tif": "image/tiff", 831 | "psd": "image/vnd.adobe.photoshop", 832 | "uvi": "image/vnd.dece.graphic", 833 | "uvvi": "image/vnd.dece.graphic", 834 | "uvg": "image/vnd.dece.graphic", 835 | "uvvg": "image/vnd.dece.graphic", 836 | "djvu": "image/vnd.djvu", 837 | "djv": "image/vnd.djvu", 838 | "sub": "text/vnd.dvb.subtitle", 839 | "dwg": "image/vnd.dwg", 840 | "dxf": "image/vnd.dxf", 841 | "fbs": "image/vnd.fastbidsheet", 842 | "fpx": "image/vnd.fpx", 843 | "fst": "image/vnd.fst", 844 | "mmr": "image/vnd.fujixerox.edmics-mmr", 845 | "rlc": "image/vnd.fujixerox.edmics-rlc", 846 | "mdi": "image/vnd.ms-modi", 847 | "wdp": "image/vnd.ms-photo", 848 | "npx": "image/vnd.net-fpx", 849 | "wbmp": "image/vnd.wap.wbmp", 850 | "xif": "image/vnd.xiff", 851 | "webp": "image/webp", 852 | "3ds": "image/x-3ds", 853 | "ras": "image/x-cmu-raster", 854 | "cmx": "image/x-cmx", 855 | "fh": "image/x-freehand", 856 | "fhc": "image/x-freehand", 857 | "fh4": "image/x-freehand", 858 | "fh5": "image/x-freehand", 859 | "fh7": "image/x-freehand", 860 | "ico": "image/x-icon", 861 | "jng": "image/x-jng", 862 | "sid": "image/x-mrsid-image", 863 | "pcx": "image/x-pcx", 864 | "pic": "image/x-pict", 865 | "pct": "image/x-pict", 866 | "pnm": "image/x-portable-anymap", 867 | "pbm": "image/x-portable-bitmap", 868 | "pgm": "image/x-portable-graymap", 869 | "ppm": "image/x-portable-pixmap", 870 | "rgb": "image/x-rgb", 871 | "tga": "image/x-tga", 872 | "xbm": "image/x-xbitmap", 873 | "xpm": "image/x-xpixmap", 874 | "xwd": "image/x-xwindowdump", 875 | "eml": "message/rfc822", 876 | "mime": "message/rfc822", 877 | "igs": "model/iges", 878 | "iges": "model/iges", 879 | "msh": "model/mesh", 880 | "mesh": "model/mesh", 881 | "silo": "model/mesh", 882 | "dae": "model/vnd.collada+xml", 883 | "dwf": "model/vnd.dwf", 884 | "gdl": "model/vnd.gdl", 885 | "gtw": "model/vnd.gtw", 886 | "mts": "model/vnd.mts", 887 | "vtu": "model/vnd.vtu", 888 | "wrl": "model/vrml", 889 | "vrml": "model/vrml", 890 | "x3db": "model/x3d+binary", 891 | "x3dbz": "model/x3d+binary", 892 | "x3dv": "model/x3d+vrml", 893 | "x3dvz": "model/x3d+vrml", 894 | "x3d": "model/x3d+xml", 895 | "x3dz": "model/x3d+xml", 896 | "appcache": "text/cache-manifest", 897 | "manifest": "text/cache-manifest", 898 | "ics": "text/calendar", 899 | "ifb": "text/calendar", 900 | "coffee": "text/coffeescript", 901 | "litcoffee": "text/coffeescript", 902 | "css": "text/css", 903 | "csv": "text/csv", 904 | "hjson": "text/hjson", 905 | "html": "text/html", 906 | "htm": "text/html", 907 | "shtml": "text/html", 908 | "jade": "text/jade", 909 | "jsx": "text/jsx", 910 | "less": "text/less", 911 | "mml": "text/mathml", 912 | "n3": "text/n3", 913 | "txt": "text/plain", 914 | "text": "text/plain", 915 | "conf": "text/plain", 916 | "def": "text/plain", 917 | "list": "text/plain", 918 | "log": "text/plain", 919 | "in": "text/plain", 920 | "ini": "text/plain", 921 | "dsc": "text/prs.lines.tag", 922 | "rtx": "text/richtext", 923 | "sgml": "text/sgml", 924 | "sgm": "text/sgml", 925 | "slim": "text/slim", 926 | "slm": "text/slim", 927 | "stylus": "text/stylus", 928 | "styl": "text/stylus", 929 | "tsv": "text/tab-separated-values", 930 | "t": "text/troff", 931 | "tr": "text/troff", 932 | "roff": "text/troff", 933 | "man": "text/troff", 934 | "me": "text/troff", 935 | "ms": "text/troff", 936 | "ttl": "text/turtle", 937 | "uri": "text/uri-list", 938 | "uris": "text/uri-list", 939 | "urls": "text/uri-list", 940 | "vcard": "text/vcard", 941 | "curl": "text/vnd.curl", 942 | "dcurl": "text/vnd.curl.dcurl", 943 | "mcurl": "text/vnd.curl.mcurl", 944 | "scurl": "text/vnd.curl.scurl", 945 | "fly": "text/vnd.fly", 946 | "flx": "text/vnd.fmi.flexstor", 947 | "gv": "text/vnd.graphviz", 948 | "3dml": "text/vnd.in3d.3dml", 949 | "spot": "text/vnd.in3d.spot", 950 | "jad": "text/vnd.sun.j2me.app-descriptor", 951 | "wml": "text/vnd.wap.wml", 952 | "wmls": "text/vnd.wap.wmlscript", 953 | "vtt": "text/vtt", 954 | "s": "text/x-asm", 955 | "asm": "text/x-asm", 956 | "c": "text/x-c", 957 | "cc": "text/x-c", 958 | "cxx": "text/x-c", 959 | "cpp": "text/x-c", 960 | "h": "text/x-c", 961 | "hh": "text/x-c", 962 | "dic": "text/x-c", 963 | "htc": "text/x-component", 964 | "f": "text/x-fortran", 965 | "for": "text/x-fortran", 966 | "f77": "text/x-fortran", 967 | "f90": "text/x-fortran", 968 | "hbs": "text/x-handlebars-template", 969 | "java": "text/x-java-source", 970 | "lua": "text/x-lua", 971 | "markdown": "text/x-markdown", 972 | "md": "text/x-markdown", 973 | "mkd": "text/x-markdown", 974 | "nfo": "text/x-nfo", 975 | "opml": "text/x-opml", 976 | "p": "text/x-pascal", 977 | "pas": "text/x-pascal", 978 | "pde": "text/x-processing", 979 | "sass": "text/x-sass", 980 | "scss": "text/x-scss", 981 | "etx": "text/x-setext", 982 | "sfv": "text/x-sfv", 983 | "ymp": "text/x-suse-ymp", 984 | "uu": "text/x-uuencode", 985 | "vcs": "text/x-vcalendar", 986 | "vcf": "text/x-vcard", 987 | "yaml": "text/yaml", 988 | "yml": "text/yaml", 989 | "3gp": "video/3gpp", 990 | "3g2": "video/3gpp2", 991 | "h261": "video/h261", 992 | "h263": "video/h263", 993 | "h264": "video/h264", 994 | "jpgv": "video/jpeg", 995 | "jpm": "video/jpm", 996 | "jpgm": "video/jpm", 997 | "mj2": "video/mj2", 998 | "mjp2": "video/mj2", 999 | "ts": "video/mp2t", 1000 | "mp4": "video/mp4", 1001 | "mp4v": "video/mp4", 1002 | "mpg4": "video/mp4", 1003 | "mpeg": "video/mpeg", 1004 | "mpg": "video/mpeg", 1005 | "mpe": "video/mpeg", 1006 | "m1v": "video/mpeg", 1007 | "m2v": "video/mpeg", 1008 | "ogv": "video/ogg", 1009 | "qt": "video/quicktime", 1010 | "mov": "video/quicktime", 1011 | "uvh": "video/vnd.dece.hd", 1012 | "uvvh": "video/vnd.dece.hd", 1013 | "uvm": "video/vnd.dece.mobile", 1014 | "uvvm": "video/vnd.dece.mobile", 1015 | "uvp": "video/vnd.dece.pd", 1016 | "uvvp": "video/vnd.dece.pd", 1017 | "uvs": "video/vnd.dece.sd", 1018 | "uvvs": "video/vnd.dece.sd", 1019 | "uvv": "video/vnd.dece.video", 1020 | "uvvv": "video/vnd.dece.video", 1021 | "dvb": "video/vnd.dvb.file", 1022 | "fvt": "video/vnd.fvt", 1023 | "mxu": "video/vnd.mpegurl", 1024 | "m4u": "video/vnd.mpegurl", 1025 | "pyv": "video/vnd.ms-playready.media.pyv", 1026 | "uvu": "video/vnd.uvvu.mp4", 1027 | "uvvu": "video/vnd.uvvu.mp4", 1028 | "viv": "video/vnd.vivo", 1029 | "webm": "video/webm", 1030 | "f4v": "video/x-f4v", 1031 | "fli": "video/x-fli", 1032 | "flv": "video/x-flv", 1033 | "m4v": "video/x-m4v", 1034 | "mkv": "video/x-matroska", 1035 | "mk3d": "video/x-matroska", 1036 | "mks": "video/x-matroska", 1037 | "mng": "video/x-mng", 1038 | "asf": "video/x-ms-asf", 1039 | "asx": "video/x-ms-asf", 1040 | "vob": "video/x-ms-vob", 1041 | "wm": "video/x-ms-wm", 1042 | "wmv": "video/x-ms-wmv", 1043 | "wmx": "video/x-ms-wmx", 1044 | "wvx": "video/x-ms-wvx", 1045 | "avi": "video/x-msvideo", 1046 | "movie": "video/x-sgi-movie", 1047 | "smv": "video/x-smv", 1048 | "ice": "x-conference/x-cooltalk" 1049 | } 1050 | --------------------------------------------------------------------------------