pax_global_header00006660000000000000000000000064124121655430014515gustar00rootroot0000000000000052 comment=53b2d3f2c0177ac89576055d327d543291d36879 type-is-1.5.2/000077500000000000000000000000001241216554300131145ustar00rootroot00000000000000type-is-1.5.2/.gitignore000066400000000000000000000000631241216554300151030ustar00rootroot00000000000000.DS_Store* *.log *.gz node_modules coverage cache type-is-1.5.2/.travis.yml000066400000000000000000000006071241216554300152300ustar00rootroot00000000000000language: node_js node_js: - "0.6" - "0.8" - "0.10" - "0.11" matrix: allow_failures: - node_js: "0.11" fast_finish: true script: - "test $TRAVIS_NODE_VERSION != '0.6' || npm test" - "test $TRAVIS_NODE_VERSION = '0.6' || npm run-script test-travis" after_script: - "test $TRAVIS_NODE_VERSION = '0.10' && npm install coveralls@2 && cat ./coverage/lcov.info | coveralls" type-is-1.5.2/HISTORY.md000066400000000000000000000025351241216554300146040ustar00rootroot000000000000001.5.2 / 2014-09-28 ================== * deps: mime-types@~2.0.2 - Add new mime types - deps: mime-db@~1.1.0 1.5.1 / 2014-09-07 ================== * Support Node.js 0.6 * deps: media-typer@0.3.0 * deps: mime-types@~2.0.1 - Support Node.js 0.6 1.5.0 / 2014-09-05 ================== * fix `hasbody` to be true for `content-length: 0` 1.4.0 / 2014-09-02 ================== * update mime-types 1.3.2 / 2014-06-24 ================== * use `~` range on mime-types 1.3.1 / 2014-06-19 ================== * fix global variable leak 1.3.0 / 2014-06-19 ================== * improve type parsing - invalid media type never matches - media type not case-sensitive - extra LWS does not affect results 1.2.2 / 2014-06-19 ================== * fix behavior on unknown type argument 1.2.1 / 2014-06-03 ================== * switch dependency from `mime` to `mime-types@1.0.0` 1.2.0 / 2014-05-11 ================== * support suffix matching: - `+json` matches `application/vnd+json` - `*/vnd+json` matches `application/vnd+json` - `application/*+json` matches `application/vnd+json` 1.1.0 / 2014-04-12 ================== * add non-array values support * expose internal utilities: - `.is()` - `.hasBody()` - `.normalize()` - `.match()` 1.0.1 / 2014-03-30 ================== * add `multipart` as a shorthand type-is-1.5.2/LICENSE000066400000000000000000000021121241216554300141150ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2014 Jonathan Ong me@jongleberry.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. type-is-1.5.2/README.md000066400000000000000000000052551241216554300144020ustar00rootroot00000000000000# type-is [![NPM Version][npm-image]][npm-url] [![NPM Downloads][downloads-image]][downloads-url] [![Node.js Version][node-version-image]][node-version-url] [![Build Status][travis-image]][travis-url] [![Test Coverage][coveralls-image]][coveralls-url] Infer the content-type of a request. ### Install ```sh $ npm install type-is ``` ## API ```js var http = require('http') var is = require('type-is') http.createServer(function (req, res) { var istext = is(req, ['text/*']) res.end('you ' + (istext ? 'sent' : 'did not send') + ' me text') }) ``` ### type = is(request, types) `request` is the node HTTP request. `types` is an array of types. ```js // req.headers.content-type = 'application/json' is(req, ['json']) // 'json' is(req, ['html', 'json']) // 'json' is(req, ['application/*']) // 'application/json' is(req, ['application/json']) // 'application/json' is(req, ['html']) // false ``` #### Each type can be: - An extension name such as `json`. This name will be returned if matched. - A mime type such as `application/json`. - A mime type with a wildcard such as `*/json` or `application/*`. The full mime type will be returned if matched - A suffix such as `+json`. This can be combined with a wildcard such as `*/vnd+json` or `application/*+json`. The full mime type will be returned if matched. `false` will be returned if no type matches. ## Examples #### Example body parser ```js var is = require('type-is'); function bodyParser(req, res, next) { if (!is.hasBody(req)) { return next() } switch (is(req, ['urlencoded', 'json', 'multipart'])) { case 'urlencoded': // parse urlencoded body throw new Error('implement urlencoded body parsing') break case 'json': // parse json body throw new Error('implement json body parsing') break case 'multipart': // parse multipart body throw new Error('implement multipart body parsing') break default: // 415 error code res.statusCode = 415 res.end() return } } ``` ## License [MIT](LICENSE) [npm-image]: https://img.shields.io/npm/v/type-is.svg?style=flat [npm-url]: https://npmjs.org/package/type-is [node-version-image]: https://img.shields.io/node/v/type-is.svg?style=flat [node-version-url]: http://nodejs.org/download/ [travis-image]: https://img.shields.io/travis/jshttp/type-is.svg?style=flat [travis-url]: https://travis-ci.org/jshttp/type-is [coveralls-image]: https://img.shields.io/coveralls/jshttp/type-is.svg?style=flat [coveralls-url]: https://coveralls.io/r/jshttp/type-is?branch=master [downloads-image]: https://img.shields.io/npm/dm/type-is.svg?style=flat [downloads-url]: https://npmjs.org/package/type-is type-is-1.5.2/index.js000066400000000000000000000117231241216554300145650ustar00rootroot00000000000000 var typer = require('media-typer') var mime = require('mime-types') module.exports = typeofrequest; typeofrequest.is = typeis; typeofrequest.hasBody = hasbody; typeofrequest.normalize = normalize; typeofrequest.match = mimeMatch; /** * Compare a `value` content-type with `types`. * Each `type` can be an extension like `html`, * a special shortcut like `multipart` or `urlencoded`, * or a mime type. * * If no types match, `false` is returned. * Otherwise, the first `type` that matches is returned. * * @param {String} value * @param {Array} types * @return String */ function typeis(value, types_) { var i var types = types_ // remove parameters and normalize value = typenormalize(value) // no type or invalid if (!value) { return false } // support flattened arguments if (types && !Array.isArray(types)) { types = new Array(arguments.length - 1) for (i = 0; i < types.length; i++) { types[i] = arguments[i + 1] } } // no types, return the content type if (!types || !types.length) return value; var type for (i = 0; i < types.length; i++) { if (mimeMatch(normalize(type = types[i]), value)) { return type[0] === '+' || ~type.indexOf('*') ? value : type } } // no matches return false; } /** * Check if a request has a request body. * A request with a body __must__ either have `transfer-encoding` * or `content-length` headers set. * http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.3 * * @param {Object} request * @return {Boolean} * @api public */ function hasbody(req) { var headers = req.headers; if ('transfer-encoding' in headers) return true; return !isNaN(headers['content-length']); } /** * Check if the incoming request contains the "Content-Type" * header field, and it contains any of the give mime `type`s. * If there is no request body, `null` is returned. * If there is no content type, `false` is returned. * Otherwise, it returns the first `type` that matches. * * Examples: * * // With Content-Type: text/html; charset=utf-8 * this.is('html'); // => 'html' * this.is('text/html'); // => 'text/html' * this.is('text/*', 'application/json'); // => 'text/html' * * // When Content-Type is application/json * this.is('json', 'urlencoded'); // => 'json' * this.is('application/json'); // => 'application/json' * this.is('html', 'application/*'); // => 'application/json' * * this.is('html'); // => false * * @param {String|Array} types... * @return {String|false|null} * @api public */ function typeofrequest(req, types_) { var types = types_ // no body if (!hasbody(req)) { return null } // support flattened arguments if (arguments.length > 2) { types = new Array(arguments.length - 1) for (var i = 0; i < types.length; i++) { types[i] = arguments[i + 1] } } // request content type var value = req.headers['content-type'] return typeis(value, types); } /** * Normalize a mime type. * If it's a shorthand, expand it to a valid mime type. * * In general, you probably want: * * var type = is(req, ['urlencoded', 'json', 'multipart']); * * Then use the appropriate body parsers. * These three are the most common request body types * and are thus ensured to work. * * @param {String} type * @api private */ function normalize(type) { switch (type) { case 'urlencoded': return 'application/x-www-form-urlencoded'; case 'multipart': type = 'multipart/*'; break; } return type[0] === '+' || ~type.indexOf('/') ? type : mime.lookup(type) } /** * Check if `exected` mime type * matches `actual` mime type with * wildcard and +suffix support. * * @param {String} expected * @param {String} actual * @return {Boolean} * @api private */ function mimeMatch(expected, actual) { // invalid type if (expected === false) { return false } // exact match if (expected === actual) { return true } actual = actual.split('/'); if (expected[0] === '+') { // support +suffix return Boolean(actual[1]) && expected.length <= actual[1].length && expected === actual[1].substr(0 - expected.length) } if (!~expected.indexOf('*')) return false; expected = expected.split('/'); if (expected[0] === '*') { // support */yyy return expected[1] === actual[1] } if (expected[1] === '*') { // support xxx/* return expected[0] === actual[0] } if (expected[1][0] === '*' && expected[1][1] === '+') { // support xxx/*+zzz return expected[0] === actual[0] && expected[1].length <= actual[1].length + 1 && expected[1].substr(1) === actual[1].substr(1 - expected[1].length) } return false } /** * Normalize a type and remove parameters. * * @param {string} value * @return {string} * @api private */ function typenormalize(value) { try { var type = typer.parse(value) delete type.parameters return typer.format(type) } catch (err) { return null } } type-is-1.5.2/package.json000066400000000000000000000016601241216554300154050ustar00rootroot00000000000000{ "name": "type-is", "description": "Infer the content-type of a request.", "version": "1.5.2", "author": "Jonathan Ong (http://jongleberry.com)", "contributors": [ "Douglas Christopher Wilson " ], "license": "MIT", "repository": "jshttp/type-is", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.0.2" }, "devDependencies": { "istanbul": "~0.3.0", "mocha": "1" }, "engines": { "node": ">= 0.6" }, "files": [ "LICENSE", "HISTORY.md", "index.js" ], "scripts": { "test": "mocha --reporter spec --check-leaks --bail test/", "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/", "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/" }, "keywords": [ "content", "type", "checking" ] } type-is-1.5.2/test/000077500000000000000000000000001241216554300140735ustar00rootroot00000000000000type-is-1.5.2/test/test.js000066400000000000000000000125421241216554300154140ustar00rootroot00000000000000 var assert = require('assert') var typeis = require('..') describe('typeis(req, type)', function(){ it('should ignore params', function(){ var req = createRequest('text/html; charset=utf-8') assert.equal(typeis(req, ['text/*']), 'text/html') }) it('should ignore params LWS', function(){ var req = createRequest('text/html ; charset=utf-8') assert.equal(typeis(req, ['text/*']), 'text/html') }) it('should ignore casing', function(){ var req = createRequest('text/HTML') assert.equal(typeis(req, ['text/*']), 'text/html') }) it('should fail invalid type', function(){ var req = createRequest('text/html**') assert.strictEqual(typeis(req, ['text/*']), false) }) describe('when no body is given', function(){ it('should return null', function(){ var req = {headers: {}} assert(null == typeis(req)); assert(null == typeis(req, ['image/*'])); assert(null == typeis(req, 'image/*', 'text/*')); }) }) describe('when no content type is given', function(){ it('should return false', function(){ var req = createRequest() assert.strictEqual(typeis(req), false) assert.strictEqual(typeis(req, ['image/*']), false) assert.strictEqual(typeis(req, ['text/*', 'image/*']), false) }) }) describe('give no types', function(){ it('should return the mime type', function(){ var req = createRequest('image/png') assert.equal(typeis(req), 'image/png') }) }) describe('given one type', function(){ it('should return the type or false', function(){ var req = createRequest('image/png') assert.equal(typeis(req, ['png']), 'png') assert.equal(typeis(req, ['.png']), '.png') assert.equal(typeis(req, ['image/png']), 'image/png') assert.equal(typeis(req, ['image/*']), 'image/png') assert.equal(typeis(req, ['*/png']), 'image/png') assert.strictEqual(typeis(req, ['jpeg']), false) assert.strictEqual(typeis(req, ['.jpeg']), false) assert.strictEqual(typeis(req, ['image/jpeg']), false) assert.strictEqual(typeis(req, ['text/*']), false) assert.strictEqual(typeis(req, ['*/jpeg']), false) assert.strictEqual(typeis(req, ['bogus']), false) assert.strictEqual(typeis(req, ['something/bogus*']), false) }) }) describe('given multiple types', function(){ it('should return the first match or false', function(){ var req = createRequest('image/png') assert.equal(typeis(req, ['png']), 'png') assert.equal(typeis(req, '.png'), '.png') assert.equal(typeis(req, ['text/*', 'image/*']), 'image/png') assert.equal(typeis(req, ['image/*', 'text/*']), 'image/png') assert.equal(typeis(req, ['image/*', 'image/png']), 'image/png') assert.equal(typeis(req, 'image/png', 'image/*'), 'image/png') assert.strictEqual(typeis(req, ['jpeg']), false) assert.strictEqual(typeis(req, ['.jpeg']), false) assert.strictEqual(typeis(req, ['text/*', 'application/*']), false) assert.strictEqual(typeis(req, ['text/html', 'text/plain', 'application/json']), false) }) }) describe('given +suffix', function(){ it('should match suffix types', function(){ var req = createRequest('application/vnd+json') assert.equal(typeis(req, '+json'), 'application/vnd+json') assert.equal(typeis(req, 'application/vnd+json'), 'application/vnd+json') assert.equal(typeis(req, 'application/*+json'), 'application/vnd+json') assert.equal(typeis(req, '*/vnd+json'), 'application/vnd+json') assert.strictEqual(typeis(req, 'application/json'), false) assert.strictEqual(typeis(req, 'text/*+json'), false) }) }) describe('when Content-Type: application/x-www-form-urlencoded', function(){ it('should match "urlencoded"', function(){ var req = createRequest('application/x-www-form-urlencoded') assert.equal(typeis(req, ['urlencoded']), 'urlencoded') assert.equal(typeis(req, ['json', 'urlencoded']), 'urlencoded') assert.equal(typeis(req, ['urlencoded', 'json']), 'urlencoded') }) }) describe('when Content-Type: multipart/form-data', function(){ it('should match "multipart/*"', function(){ var req = createRequest('multipart/form-data'); assert.equal(typeis(req, ['multipart/*']), 'multipart/form-data') }) it('should match "multipart"', function(){ var req = createRequest('multipart/form-data'); assert.equal(typeis(req, ['multipart']), 'multipart') }) }) }) describe('typeis.hasBody(req)', function(){ describe('content-length', function(){ it('should indicate body', function(){ var req = {headers: {'content-length': '1'}} assert.strictEqual(typeis.hasBody(req), true) }) it('should be true when 0', function(){ var req = {headers: {'content-length': '0'}} assert.strictEqual(typeis.hasBody(req), true) }) it('should be false when bogus', function(){ var req = {headers: {'content-length': 'bogus'}} assert.strictEqual(typeis.hasBody(req), false) }) }) describe('transfer-encoding', function(){ it('should indicate body', function(){ var req = {headers: {'transfer-encoding': 'chunked'}} assert.strictEqual(typeis.hasBody(req), true) }) }) }) function createRequest(type) { return { headers: { 'content-type': type || '', 'transfer-encoding': 'chunked' } } }