Commit 60888af8 authored by Leo Iannacone's avatar Leo Iannacone

added other missing modules

parent 8b790407
1.0.1 / 2014-04-29
==================
* Clean up error CSS
* Do not respond after headers sent
1.0.0 / 2014-03-03
==================
* Genesis from `connect`
# Error Handler
Previously `connect.errorHandler()`.
[![Build Status](https://travis-ci.org/expressjs/errorhandler.svg?branch=master)](https://travis-ci.org/expressjs/errorhandler)
Usage:
```js
var app = require('connect');
app.use(require('errorhandler')())
```
## License
The 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.
/*!
* Connect - errorHandler
* Copyright(c) 2010 Sencha Inc.
* Copyright(c) 2011 TJ Holowaychuk
* MIT Licensed
*/
/**
* Module dependencies.
*/
var fs;
try {
fs = require('graceful-fs');
} catch (_) {
fs = require('fs');
}
// environment
var env = process.env.NODE_ENV || 'development';
/**
* Error handler:
*
* Development error handler, providing stack traces
* and error message responses for requests accepting text, html,
* or json.
*
* Text:
*
* By default, and when _text/plain_ is accepted a simple stack trace
* or error message will be returned.
*
* JSON:
*
* When _application/json_ is accepted, connect will respond with
* an object in the form of `{ "error": error }`.
*
* HTML:
*
* When accepted connect will output a nice html stack trace.
*
* @return {Function}
* @api public
*/
exports = module.exports = function errorHandler(){
return function errorHandler(err, req, res, next){
if (err.status) res.statusCode = err.status;
if (res.statusCode < 400) res.statusCode = 500;
if ('test' != env) console.error(err.stack);
if (res._header) return;
var accept = req.headers.accept || '';
// html
if (~accept.indexOf('html')) {
fs.readFile(__dirname + '/public/style.css', 'utf8', function(e, style){
fs.readFile(__dirname + '/public/error.html', 'utf8', function(e, html){
var stack = (err.stack || '')
.split('\n').slice(1)
.map(function(v){ return '<li>' + v + '</li>'; }).join('');
html = html
.replace('{style}', style)
.replace('{stack}', stack)
.replace('{title}', exports.title)
.replace('{statusCode}', res.statusCode)
.replace(/\{error\}/g, escapeHTML(err.toString().replace(/\n/g, '<br/>')));
res.setHeader('Content-Type', 'text/html; charset=utf-8');
res.end(html);
});
});
// json
} else if (~accept.indexOf('json')) {
var error = { message: err.message, stack: err.stack };
for (var prop in err) error[prop] = err[prop];
var json = JSON.stringify({ error: error });
res.setHeader('Content-Type', 'application/json');
res.end(json);
// plain text
} else {
res.setHeader('Content-Type', 'text/plain');
res.end(err.stack);
}
};
};
/**
* Template title, framework authors may override this value.
*/
exports.title = 'Connect';
/**
* Escape the given string of `html`.
*
* @param {String} html
* @return {String}
* @api private
*/
function escapeHTML(html){
return String(html)
.replace(/&(?!\w+;)/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
};
\ No newline at end of file
{
"name": "errorhandler",
"description": "connect's default error handler page",
"version": "1.0.1",
"author": {
"name": "Jonathan Ong",
"email": "me@jongleberry.com",
"url": "http://jongleberry.com"
},
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/expressjs/errorhandler.git"
},
"bugs": {
"url": "https://github.com/expressjs/errorhandler/issues"
},
"devDependencies": {
"mocha": ">= 1.17.0 < 2",
"should": ">= 3.0.0 < 4",
"supertest": "*",
"connect": "*"
},
"engines": {
"node": ">= 0.8"
},
"scripts": {
"test": "mocha --reporter spec --require should"
},
"readme": "# Error Handler\n\nPreviously `connect.errorHandler()`.\n\n[![Build Status](https://travis-ci.org/expressjs/errorhandler.svg?branch=master)](https://travis-ci.org/expressjs/errorhandler)\n\nUsage:\n\n```js\nvar app = require('connect');\napp.use(require('errorhandler')())\n```\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2014 Jonathan Ong me@jongleberry.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n",
"readmeFilename": "README.md",
"_id": "errorhandler@1.0.1",
"dist": {
"shasum": "b080f545d915536eef71d75e292a4efcdd3f2540"
},
"_from": "errorhandler @*",
"_resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.0.1.tgz"
}
<html>
<head>
<meta charset='utf-8'>
<title>{error}</title>
<style>{style}</style>
</head>
<body>
<div id="wrapper">
<h1>{title}</h1>
<h2><em>{statusCode}</em> {error}</h2>
<ul id="stacktrace">{stack}</ul>
</div>
</body>
</html>
* {
margin: 0;
padding: 0;
outline: 0;
}
body {
padding: 80px 100px;
font: 13px "Helvetica Neue", "Lucida Grande", "Arial";
background: #ECE9E9 -webkit-gradient(linear, 0% 0%, 0% 100%, from(#fff), to(#ECE9E9));
background: #ECE9E9 -moz-linear-gradient(top, #fff, #ECE9E9);
background-repeat: no-repeat;
color: #555;
-webkit-font-smoothing: antialiased;
}
h1, h2 {
font-size: 22px;
color: #343434;
}
h1 em, h2 em {
padding: 0 5px;
font-weight: normal;
}
h1 {
font-size: 60px;
}
h2 {
margin-top: 10px;
}
ul li {
list-style: none;
}
#stacktrace {
margin-left: 60px;
}
/**
* Initialization middleware, exposing the
* request and response to eachother, as well
* as defaulting the X-Powered-By header field.
*
* @param {Function} app
* @return {Function}
* @api private
*/
exports.init = function(app){
return function expressInit(req, res, next){
if (app.enabled('x-powered-by')) res.setHeader('X-Powered-By', 'Express');
req.res = res;
res.req = req;
req.next = next;
req.__proto__ = app.request;
res.__proto__ = app.response;
res.locals = res.locals || Object.create(null);
next();
};
};
/**
* Module dependencies.
*/
var qs = require('qs');
var parseUrl = require('parseurl');
/**
* Query:
*
* Automatically parse the query-string when available,
* populating the `req.query` object using
* [qs](https://github.com/visionmedia/node-querystring).
*
* Examples:
*
* .use(connect.query())
* .use(function(req, res){
* res.end(JSON.stringify(req.query));
* });
*
* The `options` passed are provided to qs.parse function.
*
* @param {Object} options
* @return {Function}
* @api public
*/
module.exports = function query(options){
return function query(req, res, next){
if (!req.query) {
req.query = ~req.url.indexOf('?')
? qs.parse(parseUrl(req).query, options)
: {};
}
next();
};
};
/**
* Module dependencies.
*/
var pathRegexp = require('path-to-regexp');
var debug = require('debug')('express:router:layer');
/**
* Expose `Layer`.
*/
module.exports = Layer;
function Layer(path, options, fn) {
if (!(this instanceof Layer)) {
return new Layer(path, options, fn);
}
debug('new %s', path);
options = options || {};
this.regexp = pathRegexp(path, this.keys = [], options);
this.handle = fn;
}
/**
* Check if this route matches `path`, if so
* populate `.params`.
*
* @param {String} path
* @return {Boolean}
* @api private
*/
Layer.prototype.match = function(path){
var keys = this.keys;
var params = this.params = {};
var m = this.regexp.exec(path);
var n = 0;
var key;
var val;
if (!m) return false;
this.path = m[0];
for (var i = 1, len = m.length; i < len; ++i) {
key = keys[i - 1];
try {
val = 'string' == typeof m[i]
? decodeURIComponent(m[i])
: m[i];
} catch(e) {
var err = new Error("Failed to decode param '" + m[i] + "'");
err.status = 400;
throw err;
}
if (key) {
params[key.name] = val;
} else {
params[n++] = val;
}
}
return true;
};
1.0.2 / 2014-05-29
==================
* Fix interpretation when header not in request
* deps: pin negotiator@0.4.5
1.0.1 / 2014-01-18
==================
* Identity encoding isn't always acceptable
* deps: negotiator@~0.4.0
1.0.0 / 2013-12-27
==================
* Genesis
# Accepts
[![NPM version](https://badge.fury.io/js/accepts.svg)](http://badge.fury.io/js/accepts)
[![Build Status](https://travis-ci.org/expressjs/accepts.svg?branch=master)](https://travis-ci.org/expressjs/accepts)
Higher level content negotation based on [negotiator](https://github.com/federomero/negotiator). Extracted from [koa](https://github.com/koajs/koa) for general use.
In addition to negotatior, it allows:
- Allows types as an array or arguments list, ie `(['text/html', 'application/json'])` as well as `('text/html', 'application/json')`.
- Allows type shorthands such as `json`.
- Returns `false` when no types match
- Treats non-existent headers as `*`
## API
### var accept = new Accepts(req)
```js
var accepts = require('accepts')
http.createServer(function (req, res) {
var accept = accepts(req)
})
```
### accept\[property\]\(\)
Returns all the explicitly accepted content property as an array in descending priority.
- `accept.types()`
- `accept.encodings()`
- `accept.charsets()`
- `accept.languages()`
They are also aliased in singular form such as `accept.type()`. `accept.languages()` is also aliased as `accept.langs()`, etc.
Note: you should almost never do this in a real app as it defeats the purpose of content negotiation.
Example:
```js
// in Google Chrome
var encodings = accept.encodings() // -> ['sdch', 'gzip', 'deflate']
```
Since you probably don't support `sdch`, you should just supply the encodings you support:
```js
var encoding = accept.encodings('gzip', 'deflate') // -> 'gzip', probably
```
### accept\[property\]\(values, ...\)
You can either have `values` be an array or have an argument list of values.
If the client does not accept any `values`, `false` will be returned.
If the client accepts any `values`, the preferred `value` will be return.
For `accept.types()`, shorthand mime types are allowed.
Example:
```js
// req.headers.accept = 'application/json'
accept.types('json') // -> 'json'
accept.types('html', 'json') // -> 'json'
accept.types('html') // -> false
// req.headers.accept = ''
// which is equivalent to `*`
accept.types() // -> [], no explicit types
accept.types('text/html', 'text/json') // -> 'text/html', since it was first
```
## License
The MIT License (MIT)
Copyright (c) 2013 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.
\ No newline at end of file
var Negotiator = require('negotiator')
var mime = require('mime')
var slice = [].slice
module.exports = Accepts
function Accepts(req) {
if (!(this instanceof Accepts))
return new Accepts(req)
this.headers = req.headers
this.negotiator = Negotiator(req)
}
/**
* Check if the given `type(s)` is acceptable, returning
* the best match when true, otherwise `undefined`, in which
* case you should respond with 406 "Not Acceptable".
*
* The `type` value may be a single mime type string
* such as "application/json", the extension name
* such as "json" or an array `["json", "html", "text/plain"]`. When a list
* or array is given the _best_ match, if any is returned.
*
* Examples:
*
* // Accept: text/html
* this.types('html');
* // => "html"
*
* // Accept: text/*, application/json
* this.types('html');
* // => "html"
* this.types('text/html');
* // => "text/html"
* this.types('json', 'text');
* // => "json"
* this.types('application/json');
* // => "application/json"
*
* // Accept: text/*, application/json
* this.types('image/png');
* this.types('png');
* // => undefined
*
* // Accept: text/*;q=.5, application/json
* this.types(['html', 'json']);
* this.types('html', 'json');
* // => "json"
*
* @param {String|Array} type(s)...
* @return {String|Array|Boolean}
* @api public
*/
Accepts.prototype.type =
Accepts.prototype.types = function (types) {
if (!Array.isArray(types)) types = slice.call(arguments);
var n = this.negotiator;
if (!types.length) return n.mediaTypes();
if (!this.headers.accept) return types[0];
var mimes = types.map(extToMime);
var accepts = n.mediaTypes(mimes);
var first = accepts[0];
if (!first) return false;
return types[mimes.indexOf(first)];
}
/**
* Return accepted encodings or best fit based on `encodings`.
*
* Given `Accept-Encoding: gzip, deflate`
* an array sorted by quality is returned:
*
* ['gzip', 'deflate']
*
* @param {String|Array} encoding(s)...
* @return {String|Array}
* @api public
*/
Accepts.prototype.encoding =
Accepts.prototype.encodings = function (encodings) {
if (!Array.isArray(encodings)) encodings = slice.call(arguments);
var n = this.negotiator;
if (!encodings.length) return n.encodings();
return n.encodings(encodings)[0] || false;
}
/**
* Return accepted charsets or best fit based on `charsets`.
*
* Given `Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5`
* an array sorted by quality is returned:
*
* ['utf-8', 'utf-7', 'iso-8859-1']
*
* @param {String|Array} charset(s)...
* @return {String|Array}
* @api public
*/
Accepts.prototype.charset =
Accepts.prototype.charsets = function (charsets) {
if (!Array.isArray(charsets)) charsets = [].slice.call(arguments);
var n = this.negotiator;
if (!charsets.length) return n.charsets();
if (!this.headers['accept-charset']) return charsets[0];
return n.charsets(charsets)[0] || false;
}
/**
* Return accepted languages or best fit based on `langs`.
*
* Given `Accept-Language: en;q=0.8, es, pt`
* an array sorted by quality is returned:
*
* ['es', 'pt', 'en']
*
* @param {String|Array} lang(s)...
* @return {Array|String}
* @api public
*/
Accepts.prototype.lang =
Accepts.prototype.langs =
Accepts.prototype.language =
Accepts.prototype.languages = function (langs) {
if (!Array.isArray(langs)) langs = slice.call(arguments);
var n = this.negotiator;
if (!langs.length) return n.languages();
if (!this.headers['accept-language']) return langs[0];
return n.languages(langs)[0] || false;
}
/**
* Convert extnames to mime.
*
* @param {String} type
* @return {String}
* @api private
*/
function extToMime(type) {
if (~type.indexOf('/')) return type;
return mime.lookup(type);
}
Copyright (c) 2010 Benjamin Thomas, Robert Kieffer
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.
# mime
Comprehensive MIME type mapping API. Includes all 600+ types and 800+ extensions defined by the Apache project, plus additional types submitted by the node.js community.
## Install
Install with [npm](http://github.com/isaacs/npm):
npm install mime
## API - Queries
### mime.lookup(path)
Get the mime type associated with a file, if no mime type is found `application/octet-stream` is returned. Performs a case-insensitive lookup using the extension in `path` (the substring after the last '/' or '.'). E.g.
var mime = require('mime');
mime.lookup('/path/to/file.txt'); // => 'text/plain'
mime.lookup('file.txt'); // => 'text/plain'
mime.lookup('.TXT'); // => 'text/plain'
mime.lookup('htm'); // => 'text/html'
### mime.default_type
Sets the mime type returned when `mime.lookup` fails to find the extension searched for. (Default is `application/octet-stream`.)
### mime.extension(type)
Get the default extension for `type`
mime.extension('text/html'); // => 'html'
mime.extension('application/octet-stream'); // => 'bin'
### mime.charsets.lookup()
Map mime-type to charset
mime.charsets.lookup('text/plain'); // => 'UTF-8'
(The logic for charset lookups is pretty rudimentary. Feel free to suggest improvements.)
## API - Defining Custom Types
The following APIs allow you to add your own type mappings within your project. If you feel a type should be included as part of node-mime, see [requesting new types](https://github.com/broofa/node-mime/wiki/Requesting-New-Types).
### mime.define()
Add custom mime/extension mappings
mime.define({
'text/x-some-format': ['x-sf', 'x-sft', 'x-sfml'],
'application/x-my-type': ['x-mt', 'x-mtt'],
// etc ...
});
mime.lookup('x-sft'); // => 'text/x-some-format'
The first entry in the extensions array is returned by `mime.extension()`. E.g.
mime.extension('text/x-some-format'); // => 'x-sf'
### mime.load(filepath)
Load mappings from an Apache ".types" format file
mime.load('./my_project.types');
The .types file format is simple - See the `types` dir for examples.
var path = require('path');
var fs = require('fs');
function Mime() {
// Map of extension -> mime type
this.types = Object.create(null);
// Map of mime type -> extension
this.extensions = Object.create(null);
}
/**
* Define mimetype -> extension mappings. Each key is a mime-type that maps
* to an array of extensions associated with the type. The first extension is
* used as the default extension for the type.
*
* e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']});
*
* @param map (Object) type definitions
*/
Mime.prototype.define = function (map) {
for (var type in map) {
var exts = map[type];
for (var i = 0; i < exts.length; i++) {
if (process.env.DEBUG_MIME && this.types[exts]) {
console.warn(this._loading.replace(/.*\//, ''), 'changes "' + exts[i] + '" extension type from ' +
this.types[exts] + ' to ' + type);
}
this.types[exts[i]] = type;
}
// Default extension is the first one we encounter
if (!this.extensions[type]) {
this.extensions[type] = exts[0];
}
}
};
/**
* Load an Apache2-style ".types" file
*
* This may be called multiple times (it's expected). Where files declare
* overlapping types/extensions, the last file wins.
*
* @param file (String) path of file to load.
*/
Mime.prototype.load = function(file) {
this._loading = file;
// Read file and split into lines
var map = {},
content = fs.readFileSync(file, 'ascii'),
lines = content.split(/[\r\n]+/);
lines.forEach(function(line) {
// Clean up whitespace/comments, and split into fields
var fields = line.replace(/\s*#.*|^\s*|\s*$/g, '').split(/\s+/);
map[fields.shift()] = fields;
});
this.define(map);
this._loading = null;
};
/**
* Lookup a mime type based on extension
*/
Mime.prototype.lookup = function(path, fallback) {
var ext = path.replace(/.*[\.\/\\]/, '').toLowerCase();
return this.types[ext] || fallback || this.default_type;
};
/**
* Return file extension associated with a mime type
*/
Mime.prototype.extension = function(mimeType) {
var type = mimeType.match(/^\s*([^;\s]*)(?:;|\s|$)/)[1].toLowerCase();
return this.extensions[type];
};
// Default instance
var mime = new Mime();
// Load local copy of
// http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
mime.load(path.join(__dirname, 'types/mime.types'));
// Load additional types from node.js community
mime.load(path.join(__dirname, 'types/node.types'));
// Default type
mime.default_type = mime.lookup('bin');
//
// Additional API specific to the default instance
//
mime.Mime = Mime;
/**
* Lookup a charset based on mime type.
*/
mime.charsets = {
lookup: function(mimeType, fallback) {
// Assume text types are utf8
return (/^text\//).test(mimeType) ? 'UTF-8' : fallback;
}
};
module.exports = mime;
{
"author": {
"name": "Robert Kieffer",
"email": "robert@broofa.com",
"url": "http://github.com/broofa"
},
"contributors": [
{
"name": "Benjamin Thomas",
"email": "benjamin@benjaminthomas.org",
"url": "http://github.com/bentomas"
}
],
"dependencies": {},
"description": "A comprehensive library for mime-type mapping",
"devDependencies": {},
"keywords": [
"util",
"mime"
],
"main": "mime.js",
"name": "mime",
"repository": {
"url": "https://github.com/broofa/node-mime",
"type": "git"
},
"version": "1.2.11",
"readme": "# mime\n\nComprehensive MIME type mapping API. Includes all 600+ types and 800+ extensions defined by the Apache project, plus additional types submitted by the node.js community.\n\n## Install\n\nInstall with [npm](http://github.com/isaacs/npm):\n\n npm install mime\n\n## API - Queries\n\n### mime.lookup(path)\nGet the mime type associated with a file, if no mime type is found `application/octet-stream` is returned. Performs a case-insensitive lookup using the extension in `path` (the substring after the last '/' or '.'). E.g.\n\n var mime = require('mime');\n\n mime.lookup('/path/to/file.txt'); // => 'text/plain'\n mime.lookup('file.txt'); // => 'text/plain'\n mime.lookup('.TXT'); // => 'text/plain'\n mime.lookup('htm'); // => 'text/html'\n\n### mime.default_type\nSets the mime type returned when `mime.lookup` fails to find the extension searched for. (Default is `application/octet-stream`.)\n\n### mime.extension(type)\nGet the default extension for `type`\n\n mime.extension('text/html'); // => 'html'\n mime.extension('application/octet-stream'); // => 'bin'\n\n### mime.charsets.lookup()\n\nMap mime-type to charset\n\n mime.charsets.lookup('text/plain'); // => 'UTF-8'\n\n(The logic for charset lookups is pretty rudimentary. Feel free to suggest improvements.)\n\n## API - Defining Custom Types\n\nThe following APIs allow you to add your own type mappings within your project. If you feel a type should be included as part of node-mime, see [requesting new types](https://github.com/broofa/node-mime/wiki/Requesting-New-Types).\n\n### mime.define()\n\nAdd custom mime/extension mappings\n\n mime.define({\n 'text/x-some-format': ['x-sf', 'x-sft', 'x-sfml'],\n 'application/x-my-type': ['x-mt', 'x-mtt'],\n // etc ...\n });\n\n mime.lookup('x-sft'); // => 'text/x-some-format'\n\nThe first entry in the extensions array is returned by `mime.extension()`. E.g.\n\n mime.extension('text/x-some-format'); // => 'x-sf'\n\n### mime.load(filepath)\n\nLoad mappings from an Apache \".types\" format file\n\n mime.load('./my_project.types');\n\nThe .types file format is simple - See the `types` dir for examples.\n",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/broofa/node-mime/issues"
},
"_id": "mime@1.2.11",
"_from": "mime@~1.2.11"
}
/**
* Usage: node test.js
*/
var mime = require('./mime');
var assert = require('assert');
var path = require('path');
function eq(a, b) {
console.log('Test: ' + a + ' === ' + b);
assert.strictEqual.apply(null, arguments);
}
console.log(Object.keys(mime.extensions).length + ' types');
console.log(Object.keys(mime.types).length + ' extensions\n');
//
// Test mime lookups
//
eq('text/plain', mime.lookup('text.txt')); // normal file
eq('text/plain', mime.lookup('TEXT.TXT')); // uppercase
eq('text/plain', mime.lookup('dir/text.txt')); // dir + file
eq('text/plain', mime.lookup('.text.txt')); // hidden file
eq('text/plain', mime.lookup('.txt')); // nameless
eq('text/plain', mime.lookup('txt')); // extension-only
eq('text/plain', mime.lookup('/txt')); // extension-less ()
eq('text/plain', mime.lookup('\\txt')); // Windows, extension-less
eq('application/octet-stream', mime.lookup('text.nope')); // unrecognized
eq('fallback', mime.lookup('text.fallback', 'fallback')); // alternate default
//
// Test extensions
//
eq('txt', mime.extension(mime.types.text));
eq('html', mime.extension(mime.types.htm));
eq('bin', mime.extension('application/octet-stream'));
eq('bin', mime.extension('application/octet-stream '));
eq('html', mime.extension(' text/html; charset=UTF-8'));
eq('html', mime.extension('text/html; charset=UTF-8 '));
eq('html', mime.extension('text/html; charset=UTF-8'));
eq('html', mime.extension('text/html ; charset=UTF-8'));
eq('html', mime.extension('text/html;charset=UTF-8'));
eq('html', mime.extension('text/Html;charset=UTF-8'));
eq(undefined, mime.extension('unrecognized'));
//
// Test node.types lookups
//
eq('application/font-woff', mime.lookup('file.woff'));
eq('application/octet-stream', mime.lookup('file.buffer'));
eq('audio/mp4', mime.lookup('file.m4a'));
eq('font/opentype', mime.lookup('file.otf'));
//
// Test charsets
//
eq('UTF-8', mime.charsets.lookup('text/plain'));
eq(undefined, mime.charsets.lookup(mime.types.js));
eq('fallback', mime.charsets.lookup('application/octet-stream', 'fallback'));
//
// Test for overlaps between mime.types and node.types
//
var apacheTypes = new mime.Mime(), nodeTypes = new mime.Mime();
apacheTypes.load(path.join(__dirname, 'types/mime.types'));
nodeTypes.load(path.join(__dirname, 'types/node.types'));
var keys = [].concat(Object.keys(apacheTypes.types))
.concat(Object.keys(nodeTypes.types));
keys.sort();
for (var i = 1; i < keys.length; i++) {
if (keys[i] == keys[i-1]) {
console.warn('Warning: ' +
'node.types defines ' + keys[i] + '->' + nodeTypes.types[keys[i]] +
', mime.types defines ' + keys[i] + '->' + apacheTypes.types[keys[i]]);
}
}
console.log('\nOK');
# What: WebVTT
# Why: To allow formats intended for marking up external text track resources.
# http://dev.w3.org/html5/webvtt/
# Added by: niftylettuce
text/vtt vtt
# What: Google Chrome Extension
# Why: To allow apps to (work) be served with the right content type header.
# http://codereview.chromium.org/2830017
# Added by: niftylettuce
application/x-chrome-extension crx
# What: HTC support
# Why: To properly render .htc files such as CSS3PIE
# Added by: niftylettuce
text/x-component htc
# What: HTML5 application cache manifes ('.manifest' extension)
# Why: De-facto standard. Required by Mozilla browser when serving HTML5 apps
# per https://developer.mozilla.org/en/offline_resources_in_firefox
# Added by: louisremi
text/cache-manifest manifest
# What: node binary buffer format
# Why: semi-standard extension w/in the node community
# Added by: tootallnate
application/octet-stream buffer
# What: The "protected" MP-4 formats used by iTunes.
# Why: Required for streaming music to browsers (?)
# Added by: broofa
application/mp4 m4p
audio/mp4 m4a
# What: Video format, Part of RFC1890
# Why: See https://github.com/bentomas/node-mime/pull/6
# Added by: mjrusso
video/MP2T ts
# What: EventSource mime type
# Why: mime type of Server-Sent Events stream
# http://www.w3.org/TR/eventsource/#text-event-stream
# Added by: francois2metz
text/event-stream event-stream
# What: Mozilla App manifest mime type
# Why: https://developer.mozilla.org/en/Apps/Manifest#Serving_manifests
# Added by: ednapiranha
application/x-web-app-manifest+json webapp
# What: Lua file types
# Why: Googling around shows de-facto consensus on these
# Added by: creationix (Issue #45)
text/x-lua lua
application/x-lua-bytecode luac
# What: Markdown files, as per http://daringfireball.net/projects/markdown/syntax
# Why: http://stackoverflow.com/questions/10701983/what-is-the-mime-type-for-markdown
# Added by: avoidwork
text/x-markdown markdown md mkd
# What: ini files
# Why: because they're just text files
# Added by: Matthew Kastor
text/plain ini
# What: DASH Adaptive Streaming manifest
# Why: https://developer.mozilla.org/en-US/docs/DASH_Adaptive_Streaming_for_HTML_5_Video
# Added by: eelcocramer
application/dash+xml mdp
# What: OpenType font files - http://www.microsoft.com/typography/otspec/
# Why: Browsers usually ignore the font MIME types and sniff the content,
# but Chrome, shows a warning if OpenType fonts aren't served with
# the `font/opentype` MIME type: http://i.imgur.com/8c5RN8M.png.
# Added by: alrra
font/opentype otf
Original "Negotiator" program Copyright Federico Romero
Port to JavaScript Copyright Isaac Z. Schlueter
All rights reserved.
MIT License
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.
module.exports = preferredCharsets;
preferredCharsets.preferredCharsets = preferredCharsets;
function parseAcceptCharset(accept) {
return accept.split(',').map(function(e) {
return parseCharset(e.trim());
}).filter(function(e) {
return e;
});
}
function parseCharset(s) {
var match = s.match(/^\s*(\S+?)\s*(?:;(.*))?$/);
if (!match) return null;
var charset = match[1];
var q = 1;
if (match[2]) {
var params = match[2].split(';')
for (var i = 0; i < params.length; i ++) {
var p = params[i].trim().split('=');
if (p[0] === 'q') {
q = parseFloat(p[1]);
break;
}
}
}
return {
charset: charset,
q: q
};
}
function getCharsetPriority(charset, accepted) {
return (accepted.filter(function(a) {
return specify(charset, a);
}).sort(function (a, b) {
// revsort
return a.s > b.s ? -1 : 1;
})[0] || {q:0}).q;
}
function specify(charset, spec) {
var s = 0;
if(spec.charset === charset){
s |= 1;
} else if (spec.charset !== '*' ) {
return null
}
return {
s: s,
q: spec.q,
}
}
function preferredCharsets(accept, provided) {
// RFC 2616 sec 14.2: no header = *
accept = parseAcceptCharset(accept === undefined ? '*' : accept || '');
if (provided) {
return provided.map(function(type) {
return [type, getCharsetPriority(type, accept)];
}).filter(function(pair) {
return pair[1] > 0;
}).sort(function(a, b) {
// revsort
return a[1] > b[1] ? -1 : 1;
}).map(function(pair) {
return pair[0];
});
} else {
return accept.sort(function (a, b) {
// revsort
return a.q < b.q ? 1 : -1;
}).filter(function(type) {
return type.q > 0;
}).map(function(type) {
return type.charset;
});
}
}
module.exports = preferredEncodings;
preferredEncodings.preferredEncodings = preferredEncodings;
function parseAcceptEncoding(accept) {
var acceptableEncodings;
if (accept) {
acceptableEncodings = accept.split(',').map(function(e) {
return parseEncoding(e.trim());
});
} else {
acceptableEncodings = [];
}
if (!acceptableEncodings.some(function(e) {
return e && specify('identity', e);
})) {
/*
* If identity doesn't explicitly appear in the accept-encoding header,
* it's added to the list of acceptable encoding with the lowest q
*
*/
var lowestQ = 1;
for(var i = 0; i < acceptableEncodings.length; i++){
var e = acceptableEncodings[i];
if(e && e.q < lowestQ){
lowestQ = e.q;
}
}
acceptableEncodings.push({
encoding: 'identity',
q: lowestQ / 2,
});
}
return acceptableEncodings.filter(function(e) {
return e;
});
}
function parseEncoding(s) {
var match = s.match(/^\s*(\S+?)\s*(?:;(.*))?$/);
if (!match) return null;
var encoding = match[1];
var q = 1;
if (match[2]) {
var params = match[2].split(';');
for (var i = 0; i < params.length; i ++) {
var p = params[i].trim().split('=');
if (p[0] === 'q') {
q = parseFloat(p[1]);
break;
}
}
}
return {
encoding: encoding,
q: q
};
}
function getEncodingPriority(encoding, accepted) {
return (accepted.map(function(a) {
return specify(encoding, a);
}).filter(function(a){
return a;
}).sort(function (a, b) {
// revsort
return a.s > b.s ? -1 : 1;
})[0] || {q:0}).q;
}
function specify(encoding, spec) {
var s = 0;
if(spec.encoding === encoding){
s |= 1;
} else if (spec.encoding !== '*' ) {
return null
}
return {
s: s,
q: spec.q,
}
};
function preferredEncodings(accept, provided) {
accept = parseAcceptEncoding(accept || '');
if (provided) {
return provided.map(function(type) {
return [type, getEncodingPriority(type, accept)];
}).filter(function(pair) {
return pair[1] > 0;
}).sort(function(a, b) {
// revsort
return a[1] === b[1] ? 0 : a[1] > b[1] ? -1 : 1;
}).map(function(pair) {
return pair[0];
});
} else {
return accept.sort(function (a, b) {
// revsort
return a.q < b.q ? 1 : -1;
}).filter(function(type){
return type.q > 0;
}).map(function(type) {
return type.encoding;
});
}
}
module.exports = preferredLanguages;
preferredLanguages.preferredLanguages = preferredLanguages;
function parseAcceptLanguage(accept) {
return accept.split(',').map(function(e) {
return parseLanguage(e.trim());
}).filter(function(e) {
return e;
});
}
function parseLanguage(s) {
var match = s.match(/^\s*(\S+?)(?:-(\S+?))?\s*(?:;(.*))?$/);
if (!match) return null;
var prefix = match[1],
suffix = match[2],
full = prefix;
if (suffix) full += "-" + suffix;
var q = 1;
if (match[3]) {
var params = match[3].split(';')
for (var i = 0; i < params.length; i ++) {
var p = params[i].split('=');
if (p[0] === 'q') q = parseFloat(p[1]);
}
}
return {
prefix: prefix,
suffix: suffix,
q: q,
full: full
};
}
function getLanguagePriority(language, accepted) {
return (accepted.map(function(a){
return specify(language, a);
}).filter(function(a){
return a;
}).sort(function(a, b){
// revsort
return a.s > b.s ? -1 : 1;
})[0] || {q:0}).q;
}
function specify(language, spec) {
var p = parseLanguage(language)
var s = 0;
if(spec.full === p.full){
s |= 4;
} else if (spec.prefix === p.full) {
s |= 2;
} else if (spec.full === p.prefix) {
s |= 1;
} else if (spec.full !== '*' ) {
return null
}
return {
s: s,
q: spec.q,
}
};
function preferredLanguages(accept, provided) {
// RFC 2616 sec 14.4: no header = *
accept = parseAcceptLanguage(accept === undefined ? '*' : accept || '');
if (provided) {
var ret = provided.map(function(type) {
return [type, getLanguagePriority(type, accept)];
}).filter(function(pair) {
return pair[1] > 0;
}).sort(function(a, b) {
// revsort
return a[1] === b[1] ? 0 : a[1] > b[1] ? -1 : 1;
}).map(function(pair) {
return pair[0];
});
return ret;
} else {
return accept.sort(function (a, b) {
// revsort
return a.q < b.q ? 1 : -1;
}).filter(function(type) {
return type.q > 0;
}).map(function(type) {
return type.full;
});
}
}
module.exports = preferredMediaTypes;
preferredMediaTypes.preferredMediaTypes = preferredMediaTypes;
function parseAccept(accept) {
return accept.split(',').map(function(e) {
return parseMediaType(e.trim());
}).filter(function(e) {
return e;
});
};
function parseMediaType(s) {
var match = s.match(/\s*(\S+?)\/([^;\s]+)\s*(?:;(.*))?/);
if (!match) return null;
var type = match[1],
subtype = match[2],
full = "" + type + "/" + subtype,
params = {},
q = 1;
if (match[3]) {
params = match[3].split(';').map(function(s) {
return s.trim().split('=');
}).reduce(function (set, p) {
set[p[0]] = p[1];
return set
}, params);
if (params.q != null) {
q = parseFloat(params.q);
delete params.q;
}
}
return {
type: type,
subtype: subtype,
params: params,
q: q,
full: full
};
}
function getMediaTypePriority(type, accepted) {
return (accepted.map(function(a) {
return specify(type, a);
}).filter(Boolean).sort(function (a, b) {
// revsort
return a.s > b.s ? -1 : 1;
})[0] || {q:0}).q;
}
function specify(type, spec) {
var p = parseMediaType(type);
var s = 0;
if(spec.type == p.type) {
s |= 4
} else if(spec.type != '*') {
return null;
}
if(spec.subtype == p.subtype) {
s |= 2
} else if(spec.subtype != '*') {
return null;
}
var keys = Object.keys(spec.params);
if (keys.length > 0) {
if (keys.every(function (k) {
return spec.params[k] == '*' || spec.params[k] == p.params[k];
})) {
s |= 1
} else {
return null
}
}
return {
q: spec.q,
s: s,
}
}
function preferredMediaTypes(accept, provided) {
// RFC 2616 sec 14.2: no header = */*
accept = parseAccept(accept === undefined ? '*/*' : accept || '');
if (provided) {
return provided.map(function(type) {
return [type, getMediaTypePriority(type, accept)];
}).filter(function(pair) {
return pair[1] > 0;
}).sort(function(a, b) {
// revsort
return a[1] === b[1] ? 0 : a[1] > b[1] ? -1 : 1;
}).map(function(pair) {
return pair[0];
});
} else {
return accept.sort(function (a, b) {
// revsort
return a.q < b.q ? 1 : -1;
}).filter(function(type) {
return type.q > 0;
}).map(function(type) {
return type.full;
});
}
}
module.exports = Negotiator;
Negotiator.Negotiator = Negotiator;
function Negotiator(request) {
if (!(this instanceof Negotiator)) return new Negotiator(request);
this.request = request;
}
var set = { charset: 'accept-charset',
encoding: 'accept-encoding',
language: 'accept-language',
mediaType: 'accept' };
function capitalize(string){
return string.charAt(0).toUpperCase() + string.slice(1);
}
Object.keys(set).forEach(function (k) {
var header = set[k],
method = require('./'+k+'.js'),
singular = k,
plural = k + 's';
Negotiator.prototype[plural] = function (available) {
return method(this.request.headers[header], available);
};
Negotiator.prototype[singular] = function(available) {
var set = this[plural](available);
if (set) return set[0];
};
// Keep preferred* methods for legacy compatibility
Negotiator.prototype['preferred'+capitalize(plural)] = Negotiator.prototype[plural];
Negotiator.prototype['preferred'+capitalize(singular)] = Negotiator.prototype[singular];
})
{
"name": "negotiator",
"description": "HTTP content negotiation",
"version": "0.4.5",
"author": {
"name": "Federico Romero",
"email": "federico.romero@outboxlabs.com"
},
"contributors": [
{
"name": "Isaac Z. Schlueter",
"email": "i@izs.me",
"url": "http://blog.izs.me/"
}
],
"repository": {
"type": "git",
"url": "git://github.com/federomero/negotiator.git"
},
"keywords": [
"http",
"content negotiation",
"accept",
"accept-language",
"accept-encoding",
"accept-charset"
],
"engine": "node >= 0.6",
"license": "MIT",
"devDependencies": {
"nodeunit": "0.8.x"
},
"scripts": {
"test": "nodeunit test"
},
"optionalDependencies": {},
"engines": {
"node": "*"
},
"main": "lib/negotiator.js",
"readme": "# Negotiator [![Build Status](https://travis-ci.org/federomero/negotiator.png)](https://travis-ci.org/federomero/negotiator)\n\nAn HTTP content negotiator for node.js written in javascript.\n\n# Accept Negotiation\n\n Negotiator = require('negotiator')\n\n availableMediaTypes = ['text/html', 'text/plain', 'application/json']\n\n // The negotiator constructor receives a request object\n negotiator = new Negotiator(request)\n\n // Let's say Accept header is 'text/html, application/*;q=0.2, image/jpeg;q=0.8'\n\n negotiator.mediaTypes()\n // -> ['text/html', 'image/jpeg', 'application/*']\n\n negotiator.mediaTypes(availableMediaTypes)\n // -> ['text/html', 'application/json']\n\n negotiator.mediaType(availableMediaTypes)\n // -> 'text/html'\n\nYou can check a working example at `examples/accept.js`.\n\n## Methods\n\n`mediaTypes(availableMediaTypes)`:\n\nReturns an array of preferred media types ordered by priority from a list of available media types.\n\n`mediaType(availableMediaType)`:\n\nReturns the top preferred media type from a list of available media types.\n\n# Accept-Language Negotiation\n\n Negotiator = require('negotiator')\n\n negotiator = new Negotiator(request)\n\n availableLanguages = 'en', 'es', 'fr'\n\n // Let's say Accept-Language header is 'en;q=0.8, es, pt'\n\n negotiator.languages()\n // -> ['es', 'pt', 'en']\n\n negotiator.languages(availableLanguages)\n // -> ['es', 'en']\n\n language = negotiator.language(availableLanguages)\n // -> 'es'\n\nYou can check a working example at `examples/language.js`.\n\n## Methods\n\n`languages(availableLanguages)`:\n\nReturns an array of preferred languages ordered by priority from a list of available languages.\n\n`language(availableLanguages)`:\n\nReturns the top preferred language from a list of available languages.\n\n# Accept-Charset Negotiation\n\n Negotiator = require('negotiator')\n\n availableCharsets = ['utf-8', 'iso-8859-1', 'iso-8859-5']\n\n negotiator = new Negotiator(request)\n\n // Let's say Accept-Charset header is 'utf-8, iso-8859-1;q=0.8, utf-7;q=0.2'\n\n negotiator.charsets()\n // -> ['utf-8', 'iso-8859-1', 'utf-7']\n\n negotiator.charsets(availableCharsets)\n // -> ['utf-8', 'iso-8859-1']\n\n negotiator.charset(availableCharsets)\n // -> 'utf-8'\n\nYou can check a working example at `examples/charset.js`.\n\n## Methods\n\n`charsets(availableCharsets)`:\n\nReturns an array of preferred charsets ordered by priority from a list of available charsets.\n\n`charset(availableCharsets)`:\n\nReturns the top preferred charset from a list of available charsets.\n\n# Accept-Encoding Negotiation\n\n Negotiator = require('negotiator').Negotiator\n\n availableEncodings = ['identity', 'gzip']\n\n negotiator = new Negotiator(request)\n\n // Let's say Accept-Encoding header is 'gzip, compress;q=0.2, identity;q=0.5'\n\n negotiator.encodings()\n // -> ['gzip', 'identity', 'compress']\n\n negotiator.encodings(availableEncodings)\n // -> ['gzip', 'identity']\n\n negotiator.encoding(availableEncodings)\n // -> 'gzip'\n\nYou can check a working example at `examples/encoding.js`.\n\n## Methods\n\n`encodings(availableEncodings)`:\n\nReturns an array of preferred encodings ordered by priority from a list of available encodings.\n\n`encoding(availableEncodings)`:\n\nReturns the top preferred encoding from a list of available encodings.\n\n# License\n\nMIT\n",
"readmeFilename": "readme.md",
"bugs": {
"url": "https://github.com/federomero/negotiator/issues"
},
"dependencies": {},
"_id": "negotiator@0.4.5",
"_from": "negotiator@0.4.5"
}
# Negotiator [![Build Status](https://travis-ci.org/federomero/negotiator.png)](https://travis-ci.org/federomero/negotiator)
An HTTP content negotiator for node.js written in javascript.
# Accept Negotiation
Negotiator = require('negotiator')
availableMediaTypes = ['text/html', 'text/plain', 'application/json']
// The negotiator constructor receives a request object
negotiator = new Negotiator(request)
// Let's say Accept header is 'text/html, application/*;q=0.2, image/jpeg;q=0.8'
negotiator.mediaTypes()
// -> ['text/html', 'image/jpeg', 'application/*']
negotiator.mediaTypes(availableMediaTypes)
// -> ['text/html', 'application/json']
negotiator.mediaType(availableMediaTypes)
// -> 'text/html'
You can check a working example at `examples/accept.js`.
## Methods
`mediaTypes(availableMediaTypes)`:
Returns an array of preferred media types ordered by priority from a list of available media types.
`mediaType(availableMediaType)`:
Returns the top preferred media type from a list of available media types.
# Accept-Language Negotiation
Negotiator = require('negotiator')
negotiator = new Negotiator(request)
availableLanguages = 'en', 'es', 'fr'
// Let's say Accept-Language header is 'en;q=0.8, es, pt'
negotiator.languages()
// -> ['es', 'pt', 'en']
negotiator.languages(availableLanguages)
// -> ['es', 'en']
language = negotiator.language(availableLanguages)
// -> 'es'
You can check a working example at `examples/language.js`.
## Methods
`languages(availableLanguages)`:
Returns an array of preferred languages ordered by priority from a list of available languages.
`language(availableLanguages)`:
Returns the top preferred language from a list of available languages.
# Accept-Charset Negotiation
Negotiator = require('negotiator')
availableCharsets = ['utf-8', 'iso-8859-1', 'iso-8859-5']
negotiator = new Negotiator(request)
// Let's say Accept-Charset header is 'utf-8, iso-8859-1;q=0.8, utf-7;q=0.2'
negotiator.charsets()
// -> ['utf-8', 'iso-8859-1', 'utf-7']
negotiator.charsets(availableCharsets)
// -> ['utf-8', 'iso-8859-1']
negotiator.charset(availableCharsets)
// -> 'utf-8'
You can check a working example at `examples/charset.js`.
## Methods
`charsets(availableCharsets)`:
Returns an array of preferred charsets ordered by priority from a list of available charsets.
`charset(availableCharsets)`:
Returns the top preferred charset from a list of available charsets.
# Accept-Encoding Negotiation
Negotiator = require('negotiator').Negotiator
availableEncodings = ['identity', 'gzip']
negotiator = new Negotiator(request)
// Let's say Accept-Encoding header is 'gzip, compress;q=0.2, identity;q=0.5'
negotiator.encodings()
// -> ['gzip', 'identity', 'compress']
negotiator.encodings(availableEncodings)
// -> ['gzip', 'identity']
negotiator.encoding(availableEncodings)
// -> 'gzip'
You can check a working example at `examples/encoding.js`.
## Methods
`encodings(availableEncodings)`:
Returns an array of preferred encodings ordered by priority from a list of available encodings.
`encoding(availableEncodings)`:
Returns the top preferred encoding from a list of available encodings.
# License
MIT
{
"name": "accepts",
"description": "Higher-level content negotiation",
"version": "1.0.2",
"author": {
"name": "Jonathan Ong",
"email": "me@jongleberry.com",
"url": "http://jongleberry.com"
},
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/expressjs/accepts.git"
},
"bugs": {
"url": "https://github.com/expressjs/accepts/issues"
},
"dependencies": {
"mime": "~1.2.11",
"negotiator": "0.4.5"
},
"devDependencies": {
"mocha": "*",
"should": "*"
},
"engines": {
"node": ">= 0.8.0"
},
"scripts": {
"test": "mocha --require should --reporter dot",
"test-travis": "mocha --require should --reporter spec"
},
"readme": "# Accepts\n\n[![NPM version](https://badge.fury.io/js/accepts.svg)](http://badge.fury.io/js/accepts)\n[![Build Status](https://travis-ci.org/expressjs/accepts.svg?branch=master)](https://travis-ci.org/expressjs/accepts)\n\nHigher level content negotation based on [negotiator](https://github.com/federomero/negotiator). Extracted from [koa](https://github.com/koajs/koa) for general use.\n\nIn addition to negotatior, it allows:\n\n- Allows types as an array or arguments list, ie `(['text/html', 'application/json'])` as well as `('text/html', 'application/json')`.\n- Allows type shorthands such as `json`.\n- Returns `false` when no types match\n- Treats non-existent headers as `*`\n\n## API\n\n### var accept = new Accepts(req)\n\n```js\nvar accepts = require('accepts')\n\nhttp.createServer(function (req, res) {\n var accept = accepts(req)\n})\n```\n\n### accept\\[property\\]\\(\\)\n\nReturns all the explicitly accepted content property as an array in descending priority.\n\n- `accept.types()`\n- `accept.encodings()`\n- `accept.charsets()`\n- `accept.languages()`\n\nThey are also aliased in singular form such as `accept.type()`. `accept.languages()` is also aliased as `accept.langs()`, etc.\n\nNote: you should almost never do this in a real app as it defeats the purpose of content negotiation.\n\nExample:\n\n```js\n// in Google Chrome\nvar encodings = accept.encodings() // -> ['sdch', 'gzip', 'deflate']\n```\n\nSince you probably don't support `sdch`, you should just supply the encodings you support:\n\n```js\nvar encoding = accept.encodings('gzip', 'deflate') // -> 'gzip', probably\n```\n\n### accept\\[property\\]\\(values, ...\\)\n\nYou can either have `values` be an array or have an argument list of values.\n\nIf the client does not accept any `values`, `false` will be returned.\nIf the client accepts any `values`, the preferred `value` will be return.\n\nFor `accept.types()`, shorthand mime types are allowed.\n\nExample:\n\n```js\n// req.headers.accept = 'application/json'\n\naccept.types('json') // -> 'json'\naccept.types('html', 'json') // -> 'json'\naccept.types('html') // -> false\n\n// req.headers.accept = ''\n// which is equivalent to `*`\n\naccept.types() // -> [], no explicit types\naccept.types('text/html', 'text/json') // -> 'text/html', since it was first\n```\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2013 Jonathan Ong me@jongleberry.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.",
"readmeFilename": "README.md",
"_id": "accepts@1.0.2",
"_from": "accepts@1.0.2"
}
build: components index.js
@component build
components:
@Component install
clean:
rm -fr build components template.js
.PHONY: clean
# escape-html
Escape HTML entities
## Example
```js
var escape = require('escape-html');
escape(str);
```
## License
MIT
\ No newline at end of file
{
"name": "escape-html",
"description": "Escape HTML entities",
"version": "1.0.1",
"keywords": ["escape", "html", "utility"],
"dependencies": {},
"scripts": [
"index.js"
]
}
/**
* Escape special characters in the given string of html.
*
* @param {String} html
* @return {String}
* @api private
*/
module.exports = function(html) {
return String(html)
.replace(/&/g, '&amp;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;');
}
{
"name": "escape-html",
"description": "Escape HTML entities",
"version": "1.0.1",
"keywords": [
"escape",
"html",
"utility"
],
"dependencies": {},
"main": "index.js",
"component": {
"scripts": {
"escape-html/index.js": "index.js"
}
},
"repository": {
"type": "git",
"url": "https://github.com/component/escape-html.git"
},
"readme": "\n# escape-html\n\n Escape HTML entities\n\n## Example\n\n```js\nvar escape = require('escape-html');\nescape(str);\n```\n\n## License\n\n MIT",
"readmeFilename": "Readme.md",
"bugs": {
"url": "https://github.com/component/escape-html/issues"
},
"_id": "escape-html@1.0.1",
"_from": "escape-html@1.0.1"
}
(The MIT License)
Copyright (c) 2013-2014 TJ Holowaychuk <tj@vision-media.ca>
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.
var http = require('http');
var assert = require('assert');
var methods = require('..');
describe('methods', function() {
if (http.METHODS) {
it('is a lowercased http.METHODS', function() {
var lowercased = http.METHODS.map(function(method) {
return method.toLowerCase();
});
assert.deepEqual(lowercased, methods);
});
} else {
it('contains GET, POST, PUT, and DELETE', function() {
assert.notEqual(methods.indexOf('get'), -1);
assert.notEqual(methods.indexOf('post'), -1);
assert.notEqual(methods.indexOf('put'), -1);
assert.notEqual(methods.indexOf('delete'), -1);
});
it('is all lowercase', function() {
for (var i = 0; i < methods.length; i ++) {
assert(methods[i], methods[i].toLowerCase(), methods[i] + " isn't all lowercase");
}
});
}
});
# Compiled source #
###################
*.com
*.class
*.dll
*.exe
*.o
*.so
# Packages #
############
# it's better to unpack these files and commit the raw source
# git has its own built in compression methods
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip
# Logs and databases #
######################
*.log
*.sql
*.sqlite
# OS generated files #
######################
.DS_Store*
# Icon?
ehthumbs.db
Thumbs.db
# Node.js #
###########
lib-cov
*.seed
*.log
*.csv
*.dat
*.out
*.pid
*.gz
pids
logs
results
node_modules
npm-debug.log
# Components #
##############
/build
/components
/public
\ No newline at end of file
# parseurl
Parse a URL with memoization.
## API
### var pathname = parseurl(req)
`pathname` can then be passed to a router or something.
## LICENSE
(The MIT License)
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.
\ No newline at end of file
var parse = require('url').parse;
/**
* Parse the `req` url with memoization.
*
* @param {ServerRequest} req
* @return {Object}
* @api private
*/
module.exports = function parseUrl(req){
var parsed = req._parsedUrl;
if (parsed && parsed.href == req.url) {
return parsed;
} else {
parsed = parse(req.url);
if (parsed.auth && !parsed.protocol && ~parsed.href.indexOf('//')) {
// This parses pathnames, and a strange pathname like //r@e should work
parsed = parse(req.url.replace(/@/g, '%40'));
}
return req._parsedUrl = parsed;
}
};
{
"name": "parseurl",
"description": "parse a url with memoization",
"version": "1.0.1",
"author": {
"name": "Jonathan Ong",
"email": "me@jongleberry.com",
"url": "http://jongleberry.com"
},
"repository": {
"type": "git",
"url": "https://github.com/expressjs/parseurl.git"
},
"bugs": {
"url": "https://github.com/expressjs/parseurl/issues",
"email": "me@jongleberry.com"
},
"license": "MIT",
"readme": "# parseurl\n\nParse a URL with memoization.\n\n## API\n\n### var pathname = parseurl(req)\n\n`pathname` can then be passed to a router or something.\n\n## LICENSE\n\n(The MIT License)\n\nCopyright (c) 2014 Jonathan Ong <me@jongleberry.com>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.",
"readmeFilename": "README.md",
"_id": "parseurl@1.0.1",
"_from": "parseurl@1.0.1"
}
0.1.0 / 2014-03-06
==================
* add options.end
0.0.2 / 2013-02-10
==================
* Update to match current express
* add .license property to component.json
# Path-to-RegExp
Turn an Express-style path string such as `/user/:name` into a regular expression.
## Usage
```javascript
var pathToRegexp = require('path-to-regexp');
```
### pathToRegexp(path, keys, options)
- **path** A string in the express format, an array of such strings, or a regular expression
- **keys** An array to be populated with the keys present in the url. Once the function completes, this will be an array of strings.
- **options**
- **options.sensitive** Defaults to false, set this to true to make routes case sensitive
- **options.strict** Defaults to false, set this to true to make the trailing slash matter.
- **options.end** Defaults to true, set this to false to only match the prefix of the URL.
```javascript
var keys = [];
var exp = pathToRegexp('/foo/:bar', keys);
//keys = ['bar']
//exp = /^\/foo\/(?:([^\/]+?))\/?$/i
```
## Live Demo
You can see a live demo of this library in use at [express-route-tester](http://forbeslindesay.github.com/express-route-tester/).
## License
MIT
\ No newline at end of file
{
"name": "path-to-regexp",
"description": "Express style path to RegExp utility",
"version": "0.1.0",
"keywords": [
"express",
"regexp",
"route",
"routing"
],
"scripts": [
"index.js"
],
"license": "MIT"
}
/**
* Expose `pathtoRegexp`.
*/
module.exports = pathtoRegexp;
/**
* Normalize the given path string,
* returning a regular expression.
*
* An empty array should be passed,
* which will contain the placeholder
* key names. For example "/user/:id" will
* then contain ["id"].
*
* @param {String|RegExp|Array} path
* @param {Array} keys
* @param {Object} options
* @return {RegExp}
* @api private
*/
function pathtoRegexp(path, keys, options) {
options = options || {};
var sensitive = options.sensitive;
var strict = options.strict;
var end = options.end !== false;
keys = keys || [];
if (path instanceof RegExp) return path;
if (path instanceof Array) path = '(' + path.join('|') + ')';
path = path
.concat(strict ? '' : '/?')
.replace(/\/\(/g, '/(?:')
.replace(/([\/\.])/g, '\\$1')
.replace(/(\\\/)?(\\\.)?:(\w+)(\(.*?\))?(\*)?(\?)?/g, function (match, slash, format, key, capture, star, optional) {
slash = slash || '';
format = format || '';
capture = capture || '([^/' + format + ']+?)';
optional = optional || '';
keys.push({ name: key, optional: !!optional });
return ''
+ (optional ? '' : slash)
+ '(?:'
+ format + (optional ? slash : '') + capture
+ (star ? '((?:[\\/' + format + '].+?)?)' : '')
+ ')'
+ optional;
})
.replace(/\*/g, '(.*)');
return new RegExp('^' + path + (end ? '$' : '(?=\/|$)'), sensitive ? '' : 'i');
};
{
"name": "path-to-regexp",
"description": "Express style path to RegExp utility",
"version": "0.1.2",
"scripts": {
"test": "istanbul cover _mocha -- -R spec"
},
"keywords": [
"express",
"regexp"
],
"component": {
"scripts": {
"path-to-regexp": "index.js"
}
},
"repository": {
"type": "git",
"url": "https://github.com/component/path-to-regexp.git"
},
"devDependencies": {
"mocha": "^1.17.1",
"istanbul": "^0.2.6"
},
"readme": "\n# Path-to-RegExp\n\n Turn an Express-style path string such as `/user/:name` into a regular expression.\n\n## Usage\n\n```javascript\nvar pathToRegexp = require('path-to-regexp');\n```\n### pathToRegexp(path, keys, options)\n\n - **path** A string in the express format, an array of such strings, or a regular expression\n - **keys** An array to be populated with the keys present in the url. Once the function completes, this will be an array of strings.\n - **options**\n - **options.sensitive** Defaults to false, set this to true to make routes case sensitive\n - **options.strict** Defaults to false, set this to true to make the trailing slash matter.\n - **options.end** Defaults to true, set this to false to only match the prefix of the URL.\n\n```javascript\nvar keys = [];\nvar exp = pathToRegexp('/foo/:bar', keys);\n//keys = ['bar']\n//exp = /^\\/foo\\/(?:([^\\/]+?))\\/?$/i\n```\n\n## Live Demo\n\nYou can see a live demo of this library in use at [express-route-tester](http://forbeslindesay.github.com/express-route-tester/).\n\n## License\n\n MIT",
"readmeFilename": "Readme.md",
"bugs": {
"url": "https://github.com/component/path-to-regexp/issues"
},
"_id": "path-to-regexp@0.1.2",
"_from": "path-to-regexp@0.1.2"
}
1.0.0 / 2014-05-08
==================
* Add `trust` argument to determine proxy trust on
* Accepts custom function
* Accepts IPv4/IPv6 address(es)
* Accepts subnets
* Accepts pre-defined names
* Add optional `trust` argument to `proxyaddr.all` to
stop at first untrusted
* Add `proxyaddr.compile` to pre-compile `trust` function
to make subsequent calls faster
0.0.1 / 2014-05-04
==================
* Fix bad npm publish
0.0.0 / 2014-05-04
==================
* Initial release
(The MIT License)
Copyright (c) 2014 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.
# proxy-addr [![Build Status](https://travis-ci.org/expressjs/proxy-addr.svg?branch=master)](https://travis-ci.org/expressjs/proxy-addr) [![NPM version](https://badge.fury.io/js/proxy-addr.svg)](http://badge.fury.io/js/proxy-addr)
Determine address of proxied request
## Install
npm install proxy-addr
## API
var proxyaddr = require('proxy-addr');
### proxyaddr(req, trust)
Return the address of the request, using the given `trust` parameter.
The `trust` argument is a function that returns `true` if you trust
the address, `false` if you don't. The closest untrusted address is
returned.
proxyaddr(req, function(addr){ return addr === '127.0.0.1' })
proxyaddr(req, function(addr, i){ return i < 1 })
The `trust` arugment may also be a single IP address string or an
array of trusted addresses, as plain IP addresses, CIDR-formatted
strings, or IP/netmask strings.
proxyaddr(req, '127.0.0.1')
proxyaddr(req, ['127.0.0.0/8', '10.0.0.0/8'])
proxyaddr(req, ['127.0.0.0/255.0.0.0', '192.168.0.0/255.255.0.0'])
This module also supports IPv6. Your IPv6 addresses will be normalized
automatically (i.e. `fe80::00ed:1` equals `fe80:0:0:0:0:0:ed:1`).
proxyaddr(req, '::1')
proxyaddr(req, ['::1/128', 'fe80::/10'])
proxyaddr(req, ['fe80::/ffc0::'])
This module will automatically work with IPv4-mapped IPv6 addresses
as well to support node.js in IPv6-only mode. This means that you do
not have to specify both `::ffff:a00:1` and `10.0.0.1`.
As a convenience, this module also takes certain pre-defined names
in addition to IP addresses, which expand into IP addresses:
proxyaddr(req, 'loopback')
proxyaddr(req, ['loopback', 'fc00:ac:1ab5:fff::1/64'])
* `loopback`: IPv4 and IPv6 loopback addresses (like `::1` and
`127.0.0.1`).
* `linklocal`: IPv4 and IPv6 link-local addresses (like
`fe80::1:1:1:1` and `169.254.0.1`).
* `uniquelocal`: IPv4 private addresses and IPv6 unique-local
addresses (like `fc00:ac:1ab5:fff::1` and `192.168.0.1`).
When `trust` is specified as a function, it will be called for each
address to determine if it is a trusted address. The function is
given two arguments: `addr` and `i`, where `addr` is a string of
the address to check and `i` is a number that represents the distance
from the socket address.
### proxyaddr.all(req, [trust])
Return all the addresses of the request, optionally stopping at the
first untrusted. This array is ordered from closest to furthest
(i.e. `arr[0] === req.connection.remoteAddress`).
proxyaddr.all(req)
The optional `trust` argument takes the same arguments as `trust`
does in `proxyaddr(req, trust)`.
proxyaddr.all(req, 'loopback')
### proxyaddr.compile(val)
Compiles argument `val` into a `trust` function. This function takes
the same arguments as `trust` does in `proxyaddr(req, trust)` and
returns a function suitable for `proxyaddr(req, trust)`.
var trust = proxyaddr.compile('localhost')
var addr = proxyaddr(req, trust)
This function is meant to be optimized for use against every request.
It is recommend to compile a trust function up-front for the trusted
configuration and pass that to `proxyaddr(req, trust)` for each request.
## License
[MIT](LICENSE)
/*!
* proxy-addr
* Copyright(c) 2014 Douglas Christopher Wilson
* MIT Licensed
*/
/**
* Module exports.
*/
module.exports = proxyaddr;
module.exports.all = alladdrs;
module.exports.compile = compile;
/**
* Module dependencies.
*/
var ipaddr = require('ipaddr.js');
/**
* Variables.
*/
var digitre = /^[0-9]+$/;
var isip = ipaddr.isValid;
var parseip = ipaddr.parse;
/**
* Pre-defined IP ranges.
*/
var ipranges = {
linklocal: ['169.254.0.0/16', 'fe80::/10'],
loopback: ['127.0.0.1/8', '::1/128'],
uniquelocal: ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', 'fc00::/7']
};
/**
* Get all addresses in the request, optionally stopping
* at the first untrusted.
*
* @param {Object} request
* @param {Function|Array|String} [trust]
* @api public
*/
function alladdrs(req, trust) {
if (!req) {
throw new TypeError('req argument is required');
}
var proxyAddrs = (req.headers['x-forwarded-for'] || '')
.split(/ *, */)
.filter(Boolean)
.reverse();
var socketAddr = req.connection.remoteAddress;
var addrs = [socketAddr].concat(proxyAddrs);
if (!trust) {
// Return all addresses
return addrs;
}
if (typeof trust !== 'function') {
trust = compile(trust);
}
for (var i = 0; i < addrs.length - 1; i++) {
if (trust(addrs[i], i)) continue;
addrs.length = i + 1;
}
return addrs;
}
/**
* Compile argument into trust function.
*
* @param {Array|String} val
* @api private
*/
function compile(val) {
if (!val) {
throw new TypeError('argument is required');
}
var trust = typeof val === 'string'
? [val]
: val;
if (!Array.isArray(trust)) {
throw new TypeError('unsupported trust argument');
}
for (var i = 0; i < trust.length; i++) {
val = trust[i];
if (!ipranges.hasOwnProperty(val)) {
continue;
}
// Splice in pre-defined range
val = ipranges[val];
trust.splice.apply(trust, [i, 1].concat(val));
i += val.length - 1;
}
return compileTrust(compileRangeSubnets(trust));
}
/**
* Compile `arr` elements into range subnets.
*
* @param {Array} arr
* @api private
*/
function compileRangeSubnets(arr) {
var rangeSubnets = new Array(arr.length);
for (var i = 0; i < arr.length; i++) {
rangeSubnets[i] = parseipNotation(arr[i]);
}
return rangeSubnets;
}
/**
* Compile range subnet array into trust function.
*
* @param {Array} rangeSubnets
* @api private
*/
function compileTrust(rangeSubnets) {
// Return optimized function based on length
var len = rangeSubnets.length;
return len === 0
? trustNone
: len === 1
? trustSingle(rangeSubnets[0])
: trustMulti(rangeSubnets);
}
/**
* Parse IP notation string into range subnet.
*
* @param {String} note
* @api private
*/
function parseipNotation(note) {
var ip;
var kind;
var max;
var pos = note.lastIndexOf('/');
var range;
ip = pos !== -1
? note.substring(0, pos)
: note;
if (!isip(ip)) {
throw new TypeError('invalid IP address: ' + ip);
}
ip = parseip(ip);
kind = ip.kind();
max = kind === 'ipv4' ? 32
: kind === 'ipv6' ? 128
: 0;
range = pos !== -1
? note.substring(pos + 1, note.length)
: max;
if (typeof range !== 'number') {
range = digitre.test(range)
? parseInt(range, 10)
: isip(range)
? parseNetmask(range)
: 0;
}
if (ip.kind() === 'ipv6' && ip.isIPv4MappedAddress()) {
// Store as IPv4
ip = ip.toIPv4Address();
range = range <= max
? range - 96
: range;
}
if (range <= 0 || range > max) {
throw new TypeError('invalid range on address: ' + note);
}
return [ip, range];
}
/**
* Parse netmask string into CIDR range.
*
* @param {String} note
* @api private
*/
function parseNetmask(netmask) {
var ip = parseip(netmask);
var parts;
var size;
switch (ip.kind()) {
case 'ipv4':
parts = ip.octets;
size = 8;
break;
case 'ipv6':
parts = ip.parts;
size = 16;
break;
default:
throw new TypeError('unknown netmask');
}
var max = Math.pow(2, size) - 1;
var part;
var range = 0;
for (var i = 0; i < parts.length; i++) {
part = parts[i] & max;
if (part === max) {
range += size;
continue;
}
while (part) {
part = (part << 1) & max;
range += 1;
}
break;
}
return range;
}
/**
* Determine address of proxied request.
*
* @param {Object} request
* @param {Function|Array|String} trust
* @api public
*/
function proxyaddr(req, trust) {
if (!req) {
throw new TypeError('req argument is required');
}
if (!trust) {
throw new TypeError('trust argument is required');
}
var addrs = alladdrs(req, trust);
var addr = addrs[addrs.length - 1];
return addr;
}
/**
* Static trust function to trust nothing.
*
* @api private
*/
function trustNone() {
return false;
}
/**
* Compile trust function for multiple subnets.
*
* @param {Array} subnets
* @api private
*/
function trustMulti(subnets) {
return function trust(addr) {
if (!isip(addr)) return false;
var ip = parseip(addr);
var ipv4;
var kind = ip.kind();
var subnet;
var subnetip;
var subnetkind;
var trusted;
for (var i = 0; i < subnets.length; i++) {
subnet = subnets[i];
subnetip = subnet[0];
subnetkind = subnetip.kind();
subnetrange = subnet[1];
trusted = ip;
if (kind !== subnetkind) {
if (kind !== 'ipv6' || subnetkind !== 'ipv4' || !ip.isIPv4MappedAddress()) {
continue;
}
// Store addr as IPv4
ipv4 = ipv4 || ip.toIPv4Address();
trusted = ipv4;
}
if (trusted.match(subnetip, subnetrange)) return true;
}
return false;
};
}
/**
* Compile trust function for single subnet.
*
* @param {Object} subnet
* @api private
*/
function trustSingle(subnet) {
var subnetip = subnet[0];
var subnetkind = subnetip.kind();
var subnetisipv4 = subnetkind === 'ipv4';
var subnetrange = subnet[1];
return function trust(addr) {
if (!isip(addr)) return false;
var ip = parseip(addr);
var kind = ip.kind();
return kind === subnetkind
? ip.match(subnetip, subnetrange)
: subnetisipv4 && kind === 'ipv6' && ip.isIPv4MappedAddress()
? ip.toIPv4Address().match(subnetip, subnetrange)
: false;
};
}
fs = require 'fs'
CoffeeScript = require 'coffee-script'
nodeunit = require 'nodeunit'
UglifyJS = require 'uglify-js'
task 'build', 'build the JavaScript files from CoffeeScript source', build = (cb) ->
source = fs.readFileSync 'src/ipaddr.coffee'
fs.writeFileSync 'lib/ipaddr.js', CoffeeScript.compile source.toString()
invoke 'test'
invoke 'compress'
task 'test', 'run the bundled tests', (cb) ->
nodeunit.reporters.default.run ['test']
task 'compress', 'uglify the resulting javascript', (cb) ->
result = UglifyJS.minify('lib/ipaddr.js')
fs.writeFileSync('ipaddr.min.js', result.code)
Copyright (C) 2011 Peter Zotov <whitequark@whitequark.org>
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.
\ No newline at end of file
# ipaddr.js — an IPv6 and IPv4 address manipulation library
ipaddr.js is a small (1.9K minified and gzipped) library for manipulating
IP addresses in JavaScript environments. It runs on both CommonJS runtimes
(e.g. [nodejs]) and in a web browser.
ipaddr.js allows you to verify and parse string representation of an IP
address, match it against a CIDR range or range list, determine if it falls
into some reserved ranges (examples include loopback and private ranges),
and convert between IPv4 and IPv4-mapped IPv6 addresses.
[nodejs]: http://nodejs.org
## Installation
`npm install ipaddr.js`
## API
ipaddr.js defines one object in the global scope: `ipaddr`. In CommonJS,
it is exported from the module:
```js
var ipaddr = require('ipaddr.js');
```
The API consists of several global methods and two classes: ipaddr.IPv6 and ipaddr.IPv4.
### Global methods
There are three global methods defined: `ipaddr.isValid`, `ipaddr.parse` and
`ipaddr.process`. All of them receive a string as a single parameter.
The `ipaddr.isValid` method returns `true` if the address is a valid IPv4 or
IPv6 address, and `false` otherwise. It does not throw any exceptions.
The `ipaddr.parse` method returns an object representing the IP address,
or throws an `Error` if the passed string is not a valid representation of an
IP address.
The `ipaddr.process` method works just like the `ipaddr.parse` one, but it
automatically converts IPv4-mapped IPv6 addresses to their IPv4 couterparts
before returning. It is useful when you have a Node.js instance listening
on an IPv6 socket, and the `net.ivp6.bindv6only` sysctl parameter (or its
equivalent on non-Linux OS) is set to 0. In this case, you can accept IPv4
connections on your IPv6-only socket, but the remote address will be mangled.
Use `ipaddr.process` method to automatically demangle it.
### Object representation
Parsing methods return an object which descends from `ipaddr.IPv6` or
`ipaddr.IPv4`. These objects share some properties, but most of them differ.
#### Shared properties
One can determine the type of address by calling `addr.kind()`. It will return
either `"ipv6"` or `"ipv4"`.
An address can be converted back to its string representation with `addr.toString()`.
Note that this method:
* does not return the original string used to create the object (in fact, there is
no way of getting that string)
* returns a compact representation (when it is applicable)
A `match(range, bits)` method can be used to check if the address falls into a
certain CIDR range.
Note that an address can be (obviously) matched only against an address of the same type.
For example:
```js
var addr = ipaddr.parse("2001:db8:1234::1");
var range = ipaddr.parse("2001:db8::");
addr.match(range, 32); // => true
```
A `range()` method returns one of predefined names for several special ranges defined
by IP protocols. The exact names (and their respective CIDR ranges) can be looked up
in the source: [IPv6 ranges] and [IPv4 ranges]. Some common ones include `"unicast"`
(the default one) and `"reserved"`.
You can match against your own range list by using
`ipaddr.subnetMatch(address, rangeList, defaultName)` method. It can work with both
IPv6 and IPv4 addresses, and accepts a name-to-subnet map as the range list. For example:
```js
var rangeList = {
documentationOnly: [ ipaddr.parse('2001:db8::'), 32 ],
tunnelProviders: [
[ ipaddr.parse('2001:470::'), 32 ], // he.net
[ ipaddr.parse('2001:5c0::'), 32 ] // freenet6
]
};
ipaddr.subnetMatch(ipaddr.parse('2001:470:8:66::1'), rangeList, 'unknown'); // => "he.net"
```
The addresses can be converted to their byte representation with `toByteArray()`.
(Actually, JavaScript mostly does not know about byte buffers. They are emulated with
arrays of numbers, each in range of 0..255.)
```js
var bytes = ipaddr.parse('2a00:1450:8007::68').toByteArray(); // ipv6.google.com
bytes // => [42, 0x00, 0x14, 0x50, 0x80, 0x07, 0x00, <zeroes...>, 0x00, 0x68 ]
```
The `ipaddr.IPv4` and `ipaddr.IPv6` objects have some methods defined, too. All of them
have the same interface for both protocols, and are similar to global methods.
`ipaddr.IPvX.isValid(string)` can be used to check if the string is a valid address
for particular protocol, and `ipaddr.IPvX.parse(string)` is the error-throwing parser.
[IPv6 ranges]: https://github.com/whitequark/ipaddr.js/blob/master/src/ipaddr.coffee#L186
[IPv4 ranges]: https://github.com/whitequark/ipaddr.js/blob/master/src/ipaddr.coffee#L71
#### IPv6 properties
Sometimes you will want to convert IPv6 not to a compact string representation (with
the `::` substitution); the `toNormalizedString()` method will return an address where
all zeroes are explicit.
For example:
```js
var addr = ipaddr.parse("2001:0db8::0001");
addr.toString(); // => "2001:db8::1"
addr.toNormalizedString(); // => "2001:db8:0:0:0:0:0:1"
```
The `isIPv4MappedAddress()` method will return `true` if this address is an IPv4-mapped
one, and `toIPv4Address()` will return an IPv4 object address.
To access the underlying binary representation of the address, use `addr.parts`.
```js
var addr = ipaddr.parse("2001:db8:10::1234:DEAD");
addr.parts // => [0x2001, 0xdb8, 0x10, 0, 0, 0, 0x1234, 0xdead]
```
#### IPv4 properties
`toIPv4MappedAddress()` will return a corresponding IPv4-mapped IPv6 address.
To access the underlying representation of the address, use `addr.octets`.
```js
var addr = ipaddr.parse("192.168.1.1");
addr.octets // => [192, 168, 1, 1]
```
(function(){var t,r,n,e,i,o,a,s;r={},s=this,"undefined"!=typeof module&&null!==module&&module.exports?module.exports=r:s.ipaddr=r,a=function(t,r,n,e){var i,o;if(t.length!==r.length)throw new Error("ipaddr: cannot match CIDR for objects with different lengths");for(i=0;e>0;){if(o=n-e,0>o&&(o=0),t[i]>>o!==r[i]>>o)return!1;e-=n,i+=1}return!0},r.subnetMatch=function(t,r,n){var e,i,o,a,s;null==n&&(n="unicast");for(e in r)for(i=r[e],"[object Array]"!==toString.call(i[0])&&(i=[i]),a=0,s=i.length;s>a;a++)if(o=i[a],t.match.apply(t,o))return e;return n},r.IPv4=function(){function t(t){var r,n,e;if(4!==t.length)throw new Error("ipaddr: ipv4 octet count should be 4");for(n=0,e=t.length;e>n;n++)if(r=t[n],!(r>=0&&255>=r))throw new Error("ipaddr: ipv4 octet is a byte");this.octets=t}return t.prototype.kind=function(){return"ipv4"},t.prototype.toString=function(){return this.octets.join(".")},t.prototype.toByteArray=function(){return this.octets.slice(0)},t.prototype.match=function(t,r){if("ipv4"!==t.kind())throw new Error("ipaddr: cannot match ipv4 address with non-ipv4 one");return a(this.octets,t.octets,8,r)},t.prototype.SpecialRanges={broadcast:[[new t([255,255,255,255]),32]],multicast:[[new t([224,0,0,0]),4]],linkLocal:[[new t([169,254,0,0]),16]],loopback:[[new t([127,0,0,0]),8]],"private":[[new t([10,0,0,0]),8],[new t([172,16,0,0]),12],[new t([192,168,0,0]),16]],reserved:[[new t([192,0,0,0]),24],[new t([192,0,2,0]),24],[new t([192,88,99,0]),24],[new t([198,51,100,0]),24],[new t([203,0,113,0]),24],[new t([240,0,0,0]),4]]},t.prototype.range=function(){return r.subnetMatch(this,this.SpecialRanges)},t.prototype.toIPv4MappedAddress=function(){return r.IPv6.parse("::ffff:"+this.toString())},t}(),n="(0?\\d+|0x[a-f0-9]+)",e={fourOctet:new RegExp("^"+n+"\\."+n+"\\."+n+"\\."+n+"$","i"),longValue:new RegExp("^"+n+"$","i")},r.IPv4.parser=function(t){var r,n,i,o,a;return n=function(t){return"0"===t[0]&&"x"!==t[1]?parseInt(t,8):parseInt(t)},(r=t.match(e.fourOctet))?function(){var t,e,o,a;for(o=r.slice(1,6),a=[],t=0,e=o.length;e>t;t++)i=o[t],a.push(n(i));return a}():(r=t.match(e.longValue))?(a=n(r[1]),function(){var t,r;for(r=[],o=t=0;24>=t;o=t+=8)r.push(a>>o&255);return r}().reverse()):null},r.IPv6=function(){function t(t){var r,n,e;if(8!==t.length)throw new Error("ipaddr: ipv6 part count should be 8");for(n=0,e=t.length;e>n;n++)if(r=t[n],!(r>=0&&65535>=r))throw new Error("ipaddr: ipv6 part should fit to two octets");this.parts=t}return t.prototype.kind=function(){return"ipv6"},t.prototype.toString=function(){var t,r,n,e,i,o,a;for(i=function(){var t,n,e,i;for(e=this.parts,i=[],t=0,n=e.length;n>t;t++)r=e[t],i.push(r.toString(16));return i}.call(this),t=[],n=function(r){return t.push(r)},e=0,o=0,a=i.length;a>o;o++)switch(r=i[o],e){case 0:"0"===r?n(""):n(r),e=1;break;case 1:"0"===r?e=2:n(r);break;case 2:"0"!==r&&(n(""),n(r),e=3);break;case 3:n(r)}return 2===e&&(n(""),n("")),t.join(":")},t.prototype.toByteArray=function(){var t,r,n,e,i;for(t=[],i=this.parts,n=0,e=i.length;e>n;n++)r=i[n],t.push(r>>8),t.push(255&r);return t},t.prototype.toNormalizedString=function(){var t;return function(){var r,n,e,i;for(e=this.parts,i=[],r=0,n=e.length;n>r;r++)t=e[r],i.push(t.toString(16));return i}.call(this).join(":")},t.prototype.match=function(t,r){if("ipv6"!==t.kind())throw new Error("ipaddr: cannot match ipv6 address with non-ipv6 one");return a(this.parts,t.parts,16,r)},t.prototype.SpecialRanges={unspecified:[new t([0,0,0,0,0,0,0,0]),128],linkLocal:[new t([65152,0,0,0,0,0,0,0]),10],multicast:[new t([65280,0,0,0,0,0,0,0]),8],loopback:[new t([0,0,0,0,0,0,0,1]),128],uniqueLocal:[new t([64512,0,0,0,0,0,0,0]),7],ipv4Mapped:[new t([0,0,0,0,0,65535,0,0]),96],rfc6145:[new t([0,0,0,0,65535,0,0,0]),96],rfc6052:[new t([100,65435,0,0,0,0,0,0]),96],"6to4":[new t([8194,0,0,0,0,0,0,0]),16],teredo:[new t([8193,0,0,0,0,0,0,0]),32],reserved:[[new t([8193,3512,0,0,0,0,0,0]),32]]},t.prototype.range=function(){return r.subnetMatch(this,this.SpecialRanges)},t.prototype.isIPv4MappedAddress=function(){return"ipv4Mapped"===this.range()},t.prototype.toIPv4Address=function(){var t,n,e;if(!this.isIPv4MappedAddress())throw new Error("ipaddr: trying to convert a generic ipv6 address to ipv4");return e=this.parts.slice(-2),t=e[0],n=e[1],new r.IPv4([t>>8,255&t,n>>8,255&n])},t}(),i="(?:[0-9a-f]+::?)+",o={"native":new RegExp("^(::)?("+i+")?([0-9a-f]+)?(::)?$","i"),transitional:new RegExp("^((?:"+i+")|(?:::)(?:"+i+")?)"+(""+n+"\\."+n+"\\."+n+"\\."+n+"$"),"i")},t=function(t,r){var n,e,i,o,a;if(t.indexOf("::")!==t.lastIndexOf("::"))return null;for(n=0,e=-1;(e=t.indexOf(":",e+1))>=0;)n++;for(":"===t[0]&&n--,":"===t[t.length-1]&&n--,a=r-n,o=":";a--;)o+="0:";return t=t.replace("::",o),":"===t[0]&&(t=t.slice(1)),":"===t[t.length-1]&&(t=t.slice(0,-1)),function(){var r,n,e,o;for(e=t.split(":"),o=[],r=0,n=e.length;n>r;r++)i=e[r],o.push(parseInt(i,16));return o}()},r.IPv6.parser=function(r){var n,e;return r.match(o["native"])?t(r,8):(n=r.match(o.transitional))&&(e=t(n[1].slice(0,-1),6))?(e.push(parseInt(n[2])<<8|parseInt(n[3])),e.push(parseInt(n[4])<<8|parseInt(n[5])),e):null},r.IPv4.isIPv4=r.IPv6.isIPv6=function(t){return null!==this.parser(t)},r.IPv4.isValid=r.IPv6.isValid=function(t){var r;try{return new this(this.parser(t)),!0}catch(n){return r=n,!1}},r.IPv4.parse=r.IPv6.parse=function(t){var r;if(r=this.parser(t),null===r)throw new Error("ipaddr: string is not formatted like ip address");return new this(r)},r.isValid=function(t){return r.IPv6.isValid(t)||r.IPv4.isValid(t)},r.parse=function(t){if(r.IPv6.isIPv6(t))return r.IPv6.parse(t);if(r.IPv4.isIPv4(t))return r.IPv4.parse(t);throw new Error("ipaddr: the address has neither IPv6 nor IPv4 format")},r.process=function(t){var r;return r=this.parse(t),"ipv6"===r.kind()&&r.isIPv4MappedAddress()?r.toIPv4Address():r}}).call(this);
\ No newline at end of file
{
"name": "ipaddr.js",
"description": "A library for manipulating IPv4 and IPv6 addresses in JavaScript.",
"version": "0.1.2",
"author": {
"name": "Peter Zotov",
"email": "whitequark@whitequark.org"
},
"directories": {
"lib": "./lib"
},
"dependencies": {},
"devDependencies": {
"coffee-script": "~1.6",
"nodeunit": "~0.5.3",
"uglify-js": "latest"
},
"scripts": {
"test": "cake build test"
},
"keywords": [
"ip",
"ipv4",
"ipv6"
],
"repository": {
"type": "git",
"url": "git://github.com/whitequark/ipaddr.js"
},
"main": "./lib/ipaddr",
"engines": {
"node": ">= 0.2.5"
},
"readme": "# ipaddr.js — an IPv6 and IPv4 address manipulation library\n\nipaddr.js is a small (1.9K minified and gzipped) library for manipulating\nIP addresses in JavaScript environments. It runs on both CommonJS runtimes\n(e.g. [nodejs]) and in a web browser.\n\nipaddr.js allows you to verify and parse string representation of an IP\naddress, match it against a CIDR range or range list, determine if it falls\ninto some reserved ranges (examples include loopback and private ranges),\nand convert between IPv4 and IPv4-mapped IPv6 addresses.\n\n[nodejs]: http://nodejs.org\n\n## Installation\n\n`npm install ipaddr.js`\n\n## API\n\nipaddr.js defines one object in the global scope: `ipaddr`. In CommonJS,\nit is exported from the module:\n\n```js\nvar ipaddr = require('ipaddr.js');\n```\n\nThe API consists of several global methods and two classes: ipaddr.IPv6 and ipaddr.IPv4.\n\n### Global methods\n\nThere are three global methods defined: `ipaddr.isValid`, `ipaddr.parse` and\n`ipaddr.process`. All of them receive a string as a single parameter.\n\nThe `ipaddr.isValid` method returns `true` if the address is a valid IPv4 or\nIPv6 address, and `false` otherwise. It does not throw any exceptions.\n\nThe `ipaddr.parse` method returns an object representing the IP address,\nor throws an `Error` if the passed string is not a valid representation of an\nIP address.\n\nThe `ipaddr.process` method works just like the `ipaddr.parse` one, but it\nautomatically converts IPv4-mapped IPv6 addresses to their IPv4 couterparts\nbefore returning. It is useful when you have a Node.js instance listening\non an IPv6 socket, and the `net.ivp6.bindv6only` sysctl parameter (or its\nequivalent on non-Linux OS) is set to 0. In this case, you can accept IPv4\nconnections on your IPv6-only socket, but the remote address will be mangled.\nUse `ipaddr.process` method to automatically demangle it.\n\n### Object representation\n\nParsing methods return an object which descends from `ipaddr.IPv6` or\n`ipaddr.IPv4`. These objects share some properties, but most of them differ.\n\n#### Shared properties\n\nOne can determine the type of address by calling `addr.kind()`. It will return\neither `\"ipv6\"` or `\"ipv4\"`.\n\nAn address can be converted back to its string representation with `addr.toString()`.\nNote that this method:\n * does not return the original string used to create the object (in fact, there is\n no way of getting that string)\n * returns a compact representation (when it is applicable)\n\nA `match(range, bits)` method can be used to check if the address falls into a\ncertain CIDR range.\nNote that an address can be (obviously) matched only against an address of the same type.\n\nFor example:\n\n```js\nvar addr = ipaddr.parse(\"2001:db8:1234::1\");\nvar range = ipaddr.parse(\"2001:db8::\");\n\naddr.match(range, 32); // => true\n```\n\nA `range()` method returns one of predefined names for several special ranges defined\nby IP protocols. The exact names (and their respective CIDR ranges) can be looked up\nin the source: [IPv6 ranges] and [IPv4 ranges]. Some common ones include `\"unicast\"`\n(the default one) and `\"reserved\"`.\n\nYou can match against your own range list by using\n`ipaddr.subnetMatch(address, rangeList, defaultName)` method. It can work with both\nIPv6 and IPv4 addresses, and accepts a name-to-subnet map as the range list. For example:\n\n```js\nvar rangeList = {\n documentationOnly: [ ipaddr.parse('2001:db8::'), 32 ],\n tunnelProviders: [\n [ ipaddr.parse('2001:470::'), 32 ], // he.net\n [ ipaddr.parse('2001:5c0::'), 32 ] // freenet6\n ]\n};\nipaddr.subnetMatch(ipaddr.parse('2001:470:8:66::1'), rangeList, 'unknown'); // => \"he.net\"\n```\n\nThe addresses can be converted to their byte representation with `toByteArray()`.\n(Actually, JavaScript mostly does not know about byte buffers. They are emulated with\narrays of numbers, each in range of 0..255.)\n\n```js\nvar bytes = ipaddr.parse('2a00:1450:8007::68').toByteArray(); // ipv6.google.com\nbytes // => [42, 0x00, 0x14, 0x50, 0x80, 0x07, 0x00, <zeroes...>, 0x00, 0x68 ]\n```\n\nThe `ipaddr.IPv4` and `ipaddr.IPv6` objects have some methods defined, too. All of them\nhave the same interface for both protocols, and are similar to global methods.\n\n`ipaddr.IPvX.isValid(string)` can be used to check if the string is a valid address\nfor particular protocol, and `ipaddr.IPvX.parse(string)` is the error-throwing parser.\n\n[IPv6 ranges]: https://github.com/whitequark/ipaddr.js/blob/master/src/ipaddr.coffee#L186\n[IPv4 ranges]: https://github.com/whitequark/ipaddr.js/blob/master/src/ipaddr.coffee#L71\n\n#### IPv6 properties\n\nSometimes you will want to convert IPv6 not to a compact string representation (with\nthe `::` substitution); the `toNormalizedString()` method will return an address where\nall zeroes are explicit.\n\nFor example:\n\n```js\nvar addr = ipaddr.parse(\"2001:0db8::0001\");\naddr.toString(); // => \"2001:db8::1\"\naddr.toNormalizedString(); // => \"2001:db8:0:0:0:0:0:1\"\n```\n\nThe `isIPv4MappedAddress()` method will return `true` if this address is an IPv4-mapped\none, and `toIPv4Address()` will return an IPv4 object address.\n\nTo access the underlying binary representation of the address, use `addr.parts`.\n\n```js\nvar addr = ipaddr.parse(\"2001:db8:10::1234:DEAD\");\naddr.parts // => [0x2001, 0xdb8, 0x10, 0, 0, 0, 0x1234, 0xdead]\n```\n\n#### IPv4 properties\n\n`toIPv4MappedAddress()` will return a corresponding IPv4-mapped IPv6 address.\n\nTo access the underlying representation of the address, use `addr.octets`.\n\n```js\nvar addr = ipaddr.parse(\"192.168.1.1\");\naddr.octets // => [192, 168, 1, 1]\n```\n",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/whitequark/ipaddr.js/issues"
},
"_id": "ipaddr.js@0.1.2",
"_from": "ipaddr.js@0.1.2"
}
[submodule "support/expresso"]
path = support/expresso
url = git://github.com/visionmedia/expresso.git
[submodule "support/should"]
path = support/should
url = git://github.com/visionmedia/should.js.git
test
.travis.yml
benchmark.js
component.json
examples.js
History.md
Makefile
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment