-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 3126696
Showing
9 changed files
with
595 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
coverage/ | ||
node_modules/ | ||
npm-debug.log |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
language: 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-ci" | ||
after_script: | ||
- "test $TRAVIS_NODE_VERSION = '0.10' && npm install coveralls@2 && cat ./coverage/lcov.info | coveralls" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
1.0.0 / 2015-02-01 | ||
================== | ||
|
||
* Initial implementation, derived from `media-typer@0.3.0` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
(The MIT License) | ||
|
||
Copyright (c) 2015 Douglas Christopher Wilson | ||
|
||
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
# content-type | ||
|
||
[![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] | ||
|
||
Create and parse HTTP Content-Type header according to RFC 7231 | ||
|
||
## Installation | ||
|
||
```sh | ||
$ npm install content-type | ||
``` | ||
|
||
## API | ||
|
||
```js | ||
var contentType = require('content-type') | ||
``` | ||
|
||
### contentType.parse(string) | ||
|
||
```js | ||
var obj = contentType.parse('image/svg+xml; charset=utf-8') | ||
``` | ||
|
||
Parse a content type string. This will return an object with the following | ||
properties (examples are shown for the string `'image/svg+xml; charset=utf-8'`): | ||
|
||
- `type`: The media type (the type and subtype, always lower case). | ||
Example: `'image/svg+xml'` | ||
|
||
- `parameters`: An object of the parameters in the media type (name of parameter | ||
always lower case). Example: `{charset: 'utf-8'}` | ||
|
||
### contentType.parse(req) | ||
|
||
```js | ||
var obj = contentType.parse(req) | ||
``` | ||
|
||
Parse the `content-type` header from the given `req`. Short-cut for | ||
`contentType.parse(req.headers['content-type'])`. | ||
|
||
### contentType.parse(res) | ||
|
||
```js | ||
var obj = contentType.parse(res) | ||
``` | ||
|
||
Parse the `content-type` header set on the given `res`. Short-cut for | ||
`contentType.parse(res.getHeader('content-type'))`. | ||
|
||
### contentType.format(obj) | ||
|
||
```js | ||
var str = contentType.format({type: 'image/svg+xml'}) | ||
``` | ||
|
||
Format an object into a content type string. This will return a string of the | ||
content type for the given object with the following properties (examples are | ||
shown that produce the string `'image/svg+xml; charset=utf-8'`): | ||
|
||
- `type`: The media type (will be lower-cased). Example: `'image/svg+xml'` | ||
|
||
- `parameters`: An object of the parameters in the media type (name of the | ||
parameter will be lower-cased). Example: `{charset: 'utf-8'}` | ||
|
||
## License | ||
|
||
[MIT](LICENSE) | ||
|
||
[npm-image]: https://img.shields.io/npm/v/content-type.svg | ||
[npm-url]: https://npmjs.org/package/content-type | ||
[node-version-image]: https://img.shields.io/node/v/content-type.svg | ||
[node-version-url]: http://nodejs.org/download/ | ||
[travis-image]: https://img.shields.io/travis/jshttp/content-type/master.svg | ||
[travis-url]: https://travis-ci.org/jshttp/content-type | ||
[coveralls-image]: https://img.shields.io/coveralls/jshttp/content-type/master.svg | ||
[coveralls-url]: https://coveralls.io/r/jshttp/content-type | ||
[downloads-image]: https://img.shields.io/npm/dm/content-type.svg | ||
[downloads-url]: https://npmjs.org/package/content-type |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,210 @@ | ||
/*! | ||
* content-type | ||
* Copyright(c) 2015 Douglas Christopher Wilson | ||
* MIT Licensed | ||
*/ | ||
|
||
/** | ||
* RegExp to match *( ";" parameter ) in RFC 7231 sec 3.1.1.1 | ||
* | ||
* parameter = token "=" ( token / quoted-string ) | ||
* token = 1*tchar | ||
* tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" | ||
* / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" | ||
* / DIGIT / ALPHA | ||
* ; any VCHAR, except delimiters | ||
* quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE | ||
* qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text | ||
* obs-text = %x80-FF | ||
* quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text ) | ||
*/ | ||
var paramRegExp = /; *([!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+) *= *("(?:[\u000b\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u000b\u0020-\u00ff])*"|[!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+) */g | ||
var textRegExp = /^[\u000b\u0020-\u007e\u0080-\u00ff]+$/ | ||
var tokenRegExp = /^[!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+$/ | ||
|
||
/** | ||
* RegExp to match quoted-pair in RFC 7230 sec 3.2.6 | ||
* | ||
* quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text ) | ||
* obs-text = %x80-FF | ||
*/ | ||
var qescRegExp = /\\([\u000b\u0020-\u00ff])/g | ||
|
||
/** | ||
* RegExp to match chars that must be quoted-pair in RFC 7230 sec 3.2.6 | ||
*/ | ||
var quoteRegExp = /([\\"])/g | ||
|
||
/** | ||
* RegExp to match type in RFC 6838 | ||
* | ||
* media-type = type "/" subtype | ||
* type = token | ||
* subtype = token | ||
*/ | ||
var typeRegExp = /^[!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+\/[!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+$/ | ||
|
||
/** | ||
* Module exports. | ||
* @public | ||
*/ | ||
|
||
exports.format = format | ||
exports.parse = parse | ||
|
||
/** | ||
* Format object to media type. | ||
* | ||
* @param {object} obj | ||
* @return {string} | ||
* @public | ||
*/ | ||
|
||
function format(obj) { | ||
if (!obj || typeof obj !== 'object') { | ||
throw new TypeError('argument obj is required') | ||
} | ||
|
||
var parameters = obj.parameters | ||
var type = obj.type | ||
|
||
if (!type || !typeRegExp.test(type)) { | ||
throw new TypeError('invalid type') | ||
} | ||
|
||
var string = type | ||
|
||
// append parameters | ||
if (parameters && typeof parameters === 'object') { | ||
var param | ||
var params = Object.keys(parameters).sort() | ||
|
||
for (var i = 0; i < params.length; i++) { | ||
param = params[i] | ||
|
||
if (!tokenRegExp.test(param)) { | ||
throw new TypeError('invalid parameter name') | ||
} | ||
|
||
string += '; ' + param + '=' + qstring(parameters[param]) | ||
} | ||
} | ||
|
||
return string | ||
} | ||
|
||
/** | ||
* Parse media type to object. | ||
* | ||
* @param {string|object} string | ||
* @return {Object} | ||
* @public | ||
*/ | ||
|
||
function parse(string) { | ||
if (!string) { | ||
throw new TypeError('argument string is required') | ||
} | ||
|
||
// support req/res-like objects as argument | ||
if (typeof string === 'object') { | ||
string = getcontenttype(string) | ||
} | ||
|
||
if (typeof string !== 'string') { | ||
throw new TypeError('argument string is required to be a string') | ||
} | ||
|
||
var index = string.indexOf(';') | ||
var type = index !== -1 | ||
? string.substr(0, index).trim() | ||
: string.trim() | ||
|
||
if (!typeRegExp.test(type)) { | ||
throw new TypeError('invalid media type') | ||
} | ||
|
||
var key | ||
var match | ||
var obj = new ContentType(type.toLowerCase()) | ||
var value | ||
|
||
paramRegExp.lastIndex = index | ||
|
||
while (match = paramRegExp.exec(string)) { | ||
if (match.index !== index) { | ||
throw new TypeError('invalid parameter format') | ||
} | ||
|
||
index += match[0].length | ||
key = match[1].toLowerCase() | ||
value = match[2] | ||
|
||
if (value[0] === '"') { | ||
// remove quotes and escapes | ||
value = value | ||
.substr(1, value.length - 2) | ||
.replace(qescRegExp, '$1') | ||
} | ||
|
||
obj.parameters[key] = value | ||
} | ||
|
||
if (index !== -1 && index !== string.length) { | ||
throw new TypeError('invalid parameter format') | ||
} | ||
|
||
return obj | ||
} | ||
|
||
/** | ||
* Get content-type from req/res objects. | ||
* | ||
* @param {object} | ||
* @return {Object} | ||
* @private | ||
*/ | ||
|
||
function getcontenttype(obj) { | ||
if (typeof obj.getHeader === 'function') { | ||
// res-like | ||
return obj.getHeader('content-type') | ||
} | ||
|
||
if (typeof obj.headers === 'object') { | ||
// req-like | ||
return obj.headers && obj.headers['content-type'] | ||
} | ||
} | ||
|
||
/** | ||
* Quote a string if necessary. | ||
* | ||
* @param {string} val | ||
* @return {string} | ||
* @private | ||
*/ | ||
|
||
function qstring(val) { | ||
var str = String(val) | ||
|
||
// no need to quote tokens | ||
if (tokenRegExp.test(str)) { | ||
return str | ||
} | ||
|
||
if (str.length > 0 && !textRegExp.test(str)) { | ||
throw new TypeError('invalid parameter value') | ||
} | ||
|
||
return '"' + str.replace(quoteRegExp, '\\$1') + '"' | ||
} | ||
|
||
/** | ||
* Class to represent a content type. | ||
* @private | ||
*/ | ||
function ContentType(type) { | ||
this.parameters = Object.create(null) | ||
this.type = type | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
{ | ||
"name": "content-type", | ||
"description": "Create and parse HTTP Content-Type header", | ||
"version": "1.0.0", | ||
"author": "Douglas Christopher Wilson <doug@somethingdoug.com>", | ||
"license": "MIT", | ||
"keywords": [ | ||
"content-type", | ||
"http", | ||
"req", | ||
"res", | ||
"rfc7231" | ||
], | ||
"repository": "jshttp/content-type", | ||
"devDependencies": { | ||
"istanbul": "0.3.5", | ||
"mocha": "~1.21.5" | ||
}, | ||
"files": [ | ||
"LICENSE", | ||
"HISTORY.md", | ||
"README.md", | ||
"index.js" | ||
], | ||
"engines": { | ||
"node": ">= 0.6" | ||
}, | ||
"scripts": { | ||
"test": "mocha --reporter spec --check-leaks --bail test/", | ||
"test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/", | ||
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/" | ||
} | ||
} |
Oops, something went wrong.