mirror of
https://github.com/expressjs/express.git
synced 2026-02-27 19:20:15 +00:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9f06d9b03f | ||
|
|
3fb7c4e1db | ||
|
|
d0e49f1a8a | ||
|
|
ea2664a4b8 | ||
|
|
da6524bd06 | ||
|
|
a231406931 | ||
|
|
6d39ed8ef7 | ||
|
|
f2563f4dde | ||
|
|
3df265b36a | ||
|
|
e382e6adc7 | ||
|
|
91c71d6c2e | ||
|
|
0d40c65b7f | ||
|
|
58f2057ba7 | ||
|
|
37179109db | ||
|
|
579857cfaa | ||
|
|
0b4e2df480 | ||
|
|
49cc1a70b1 | ||
|
|
f8a33d137a | ||
|
|
2db135dfc7 | ||
|
|
99bc628ad1 | ||
|
|
5ba6c301d7 | ||
|
|
88273a59f8 | ||
|
|
2e53cb72ec | ||
|
|
3b1597d79e | ||
|
|
ee9d50c128 | ||
|
|
57e48c4767 |
17
History.md
17
History.md
@@ -1,4 +1,21 @@
|
||||
|
||||
3.2.1 / 2013-04-29
|
||||
==================
|
||||
|
||||
* add app.VERB() paths array deprecation warning
|
||||
* update connect
|
||||
* update qs and remove all ~ semver crap
|
||||
* fix: accept number as value of Signed Cookie
|
||||
|
||||
3.2.0 / 2013-04-15
|
||||
==================
|
||||
|
||||
* add "view" constructor setting to override view behaviour
|
||||
* add req.acceptsEncoding(name)
|
||||
* add req.acceptedEncodings
|
||||
* revert cookie signature change causing session race conditions
|
||||
* fix sorting of Accept values of the same quality
|
||||
|
||||
3.1.2 / 2013-04-12
|
||||
==================
|
||||
|
||||
|
||||
@@ -334,7 +334,7 @@ function createApplicationAt(path) {
|
||||
|
||||
// Session support
|
||||
app = app.replace('{sess}', program.sessions
|
||||
? eol + ' app.use(express.cookieParser(\'your secret here\'));' + eol + ' app.use(express.session());'
|
||||
? eol + 'app.use(express.cookieParser(\'your secret here\'));' + eol + 'app.use(express.session());'
|
||||
: '');
|
||||
|
||||
// Template support
|
||||
|
||||
@@ -31,7 +31,9 @@ var iterations = 12000;
|
||||
|
||||
exports.hash = function (pwd, salt, fn) {
|
||||
if (3 == arguments.length) {
|
||||
crypto.pbkdf2(pwd, salt, iterations, len, fn);
|
||||
crypto.pbkdf2(pwd, salt, iterations, len, function(err, hash){
|
||||
fn(err, (new Buffer(hash, 'binary')).toString('base64'));
|
||||
});
|
||||
} else {
|
||||
fn = salt;
|
||||
crypto.randomBytes(len, function(err, salt){
|
||||
@@ -39,8 +41,8 @@ exports.hash = function (pwd, salt, fn) {
|
||||
salt = salt.toString('base64');
|
||||
crypto.pbkdf2(pwd, salt, iterations, len, function(err, hash){
|
||||
if (err) return fn(err);
|
||||
fn(null, salt, hash);
|
||||
fn(null, salt, (new Buffer(hash, 'binary')).toString('base64'));
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -3,7 +3,7 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../../')
|
||||
var express = require('../..')
|
||||
, fs = require('fs')
|
||||
, md = require('github-flavored-markdown').parse;
|
||||
|
||||
@@ -42,4 +42,4 @@ app.get('/fail', function(req, res){
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
}
|
||||
|
||||
52
examples/view-constructor/github-view.js
Normal file
52
examples/view-constructor/github-view.js
Normal file
@@ -0,0 +1,52 @@
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var http = require('http')
|
||||
, path = require('path')
|
||||
, extname = path.extname
|
||||
|
||||
/**
|
||||
* Expose `GithubView`.
|
||||
*/
|
||||
|
||||
module.exports = GithubView;
|
||||
|
||||
/**
|
||||
* Custom view that fetches and renders
|
||||
* remove github templates. You could
|
||||
* render templates from a database etc.
|
||||
*/
|
||||
|
||||
function GithubView(name, options){
|
||||
this.name = name;
|
||||
options = options || {};
|
||||
this.engine = options.engines[extname(name)];
|
||||
// "root" is the app.set('views') setting, however
|
||||
// in your own implementation you could ignore this
|
||||
this.path = '/' + options.root + '/master/' + name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the view.
|
||||
*/
|
||||
|
||||
GithubView.prototype.render = function(options, fn){
|
||||
var self = this;
|
||||
var opts = {
|
||||
host: 'rawgithub.com',
|
||||
port: 80,
|
||||
path: this.path,
|
||||
method: 'GET'
|
||||
};
|
||||
|
||||
http.request(opts, function(res) {
|
||||
var buf = '';
|
||||
res.setEncoding('utf8');
|
||||
res.on('data', function(str){ buf += str });
|
||||
res.on('end', function(){
|
||||
self.engine(buf, options, fn);
|
||||
});
|
||||
}).end();
|
||||
};
|
||||
47
examples/view-constructor/index.js
Normal file
47
examples/view-constructor/index.js
Normal file
@@ -0,0 +1,47 @@
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../../')
|
||||
, http = require('http')
|
||||
, GithubView = require('./github-view')
|
||||
, md = require('github-flavored-markdown').parse;
|
||||
|
||||
var app = module.exports = express();
|
||||
|
||||
// register .md as an engine in express view system
|
||||
app.engine('md', function(str, options, fn){
|
||||
try {
|
||||
var html = md(str);
|
||||
html = html.replace(/\{([^}]+)\}/g, function(_, name){
|
||||
return options[name] || '';
|
||||
})
|
||||
fn(null, html);
|
||||
} catch(err) {
|
||||
fn(err);
|
||||
}
|
||||
})
|
||||
|
||||
// pointing to a particular github repo to load files from it
|
||||
app.set('views', 'visionmedia/express');
|
||||
|
||||
// register a new view constructor
|
||||
app.set('view', GithubView);
|
||||
|
||||
app.get('/', function(req, res){
|
||||
// rendering a view relative to the repo.
|
||||
// app.locals, res.locals, and locals passed
|
||||
// work like they normally would
|
||||
res.render('examples/markdown/views/index.md', { title: 'Example' });
|
||||
})
|
||||
|
||||
app.get('/Readme.md', function(req, res){
|
||||
// rendering a view from https://github.com/visionmedia/express/blob/master/Readme.md
|
||||
res.render('Readme.md');
|
||||
})
|
||||
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
@@ -79,6 +79,7 @@ app.defaultConfiguration = function(){
|
||||
this.locals.settings = this.settings;
|
||||
|
||||
// default configuration
|
||||
this.set('view', View);
|
||||
this.set('views', process.cwd() + '/views');
|
||||
this.set('jsonp callback name', 'callback');
|
||||
|
||||
@@ -401,6 +402,11 @@ methods.forEach(function(method){
|
||||
app[method] = function(path){
|
||||
if ('get' == method && 1 == arguments.length) return this.set(path);
|
||||
|
||||
// deprecated
|
||||
if (Array.isArray(path)) {
|
||||
console.trace('passing an array to app.VERB() is deprecated and will be removed in 4.0');
|
||||
}
|
||||
|
||||
// if no router attached yet, attach the router
|
||||
if (!this._usedRouter) this.use(this.router);
|
||||
|
||||
@@ -479,7 +485,7 @@ app.render = function(name, options, fn){
|
||||
|
||||
// view
|
||||
if (!view) {
|
||||
view = new View(name, {
|
||||
view = new (this.get('view'))(name, {
|
||||
defaultEngine: this.get('view engine'),
|
||||
root: this.get('views'),
|
||||
engines: engines
|
||||
|
||||
@@ -20,7 +20,7 @@ exports = module.exports = createApplication;
|
||||
* Framework version.
|
||||
*/
|
||||
|
||||
exports.version = '3.1.2';
|
||||
exports.version = '3.2.0';
|
||||
|
||||
/**
|
||||
* Expose mime.
|
||||
|
||||
@@ -101,6 +101,18 @@ req.accepts = function(type){
|
||||
return utils.accepts(type, this.get('Accept'));
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the given `encoding` is accepted.
|
||||
*
|
||||
* @param {String} encoding
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.acceptsEncoding = function(encoding){
|
||||
return ~this.acceptedEncodings.indexOf(encoding);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the given `charset` is acceptable,
|
||||
* otherwise you should respond with 406 "Not Acceptable".
|
||||
@@ -159,6 +171,24 @@ req.range = function(size){
|
||||
return parseRange(size, range);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return an array of encodings.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* ['gzip', 'deflate']
|
||||
*
|
||||
* @return {Array}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.__defineGetter__('acceptedEncodings', function(){
|
||||
var accept = this.get('Accept-Encoding');
|
||||
return accept
|
||||
? accept.trim().split(/ *, */)
|
||||
: [];
|
||||
});
|
||||
|
||||
/**
|
||||
* Return an array of Accepted media types
|
||||
* ordered from highest quality to lowest.
|
||||
|
||||
@@ -580,6 +580,7 @@ res.cookie = function(name, val, options){
|
||||
var secret = this.req.secret;
|
||||
var signed = options.signed;
|
||||
if (signed && !secret) throw new Error('connect.cookieParser("secret") required for signed cookies');
|
||||
if ('number' == typeof val) val = val.toString();
|
||||
if ('object' == typeof val) val = 'j:' + JSON.stringify(val);
|
||||
if (signed) val = 's:' + sign(val, secret);
|
||||
if ('maxAge' in options) {
|
||||
|
||||
19
lib/utils.js
19
lib/utils.js
@@ -6,6 +6,12 @@
|
||||
var mime = require('connect').mime
|
||||
, crc32 = require('buffer-crc32');
|
||||
|
||||
/**
|
||||
* toString ref.
|
||||
*/
|
||||
|
||||
var toString = {}.toString;
|
||||
|
||||
/**
|
||||
* Return ETag for `body`.
|
||||
*
|
||||
@@ -217,22 +223,27 @@ exports.parseParams = function(str){
|
||||
return obj.quality;
|
||||
})
|
||||
.sort(function(a, b){
|
||||
return b.quality - a.quality;
|
||||
if (a.quality === b.quality) {
|
||||
return a.originalIndex - b.originalIndex;
|
||||
} else {
|
||||
return b.quality - a.quality;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse accept params `str` returning an
|
||||
* object with `.value`, `.quality` and `.params`.
|
||||
* also includes `.originalIndex` for stable sorting
|
||||
*
|
||||
* @param {String} str
|
||||
* @return {Object}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function acceptParams(str) {
|
||||
function acceptParams(str, index) {
|
||||
var parts = str.split(/ *; */);
|
||||
var ret = { value: parts[0], quality: 1, params: {} };
|
||||
var ret = { value: parts[0], quality: 1, params: {}, originalIndex: index };
|
||||
|
||||
for (var i = 1; i < parts.length; ++i) {
|
||||
var pms = parts[i].split(/ *= */);
|
||||
@@ -280,7 +291,7 @@ exports.escape = function(html) {
|
||||
*/
|
||||
|
||||
exports.pathRegexp = function(path, keys, sensitive, strict) {
|
||||
if (path instanceof RegExp) return path;
|
||||
if (toString.call(path) == '[object RegExp]') return path;
|
||||
if (Array.isArray(path)) path = '(' + path.join('|') + ')';
|
||||
path = path
|
||||
.concat(strict ? '' : '/?')
|
||||
|
||||
15
package.json
15
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "express",
|
||||
"description": "Sinatra inspired web development framework",
|
||||
"version": "3.1.2",
|
||||
"version": "3.2.1",
|
||||
"author": "TJ Holowaychuk <tj@vision-media.ca>",
|
||||
"contributors": [
|
||||
{
|
||||
@@ -22,17 +22,18 @@
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"connect": "2.7.5",
|
||||
"connect": "2.7.7",
|
||||
"commander": "0.6.1",
|
||||
"range-parser": "0.0.4",
|
||||
"mkdirp": "~0.3.4",
|
||||
"mkdirp": "0.3.4",
|
||||
"cookie": "0.0.5",
|
||||
"buffer-crc32": "~0.2.1",
|
||||
"buffer-crc32": "0.2.1",
|
||||
"fresh": "0.1.0",
|
||||
"methods": "0.0.1",
|
||||
"send": "0.1.0",
|
||||
"cookie-signature": "1.0.0",
|
||||
"debug": "*"
|
||||
"cookie-signature": "1.0.1",
|
||||
"debug": "*",
|
||||
"qs": "0.6.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ejs": "*",
|
||||
@@ -43,7 +44,7 @@
|
||||
"should": "*",
|
||||
"connect-redis": "*",
|
||||
"github-flavored-markdown": "*",
|
||||
"supertest": "0.0.1"
|
||||
"supertest": "0.6.0"
|
||||
},
|
||||
"keywords": [
|
||||
"express",
|
||||
|
||||
@@ -8,7 +8,7 @@ describe('app', function(){
|
||||
var app = express();
|
||||
|
||||
app.param(function(name, regexp){
|
||||
if (regexp instanceof RegExp) {
|
||||
if (Object.prototype.toString.call(regexp) == '[object RegExp]') { // See #1557
|
||||
return function(req, res, next, val){
|
||||
var captures;
|
||||
if (captures = regexp.exec(String(val))) {
|
||||
|
||||
@@ -14,7 +14,7 @@ describe('app', function(){
|
||||
done();
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
it('should support absolute paths with "view engine"', function(done){
|
||||
var app = express();
|
||||
|
||||
@@ -40,7 +40,7 @@ describe('app', function(){
|
||||
done();
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
it('should support index.<engine>', function(done){
|
||||
var app = express();
|
||||
|
||||
@@ -109,8 +109,31 @@ describe('app', function(){
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('when a "view" constructor is given', function(){
|
||||
it('should create an instance of it', function(done){
|
||||
var app = express();
|
||||
|
||||
function View(name, options){
|
||||
this.name = name;
|
||||
this.path = 'path is required by application.js as a signal of success even though it is not used there.';
|
||||
}
|
||||
|
||||
View.prototype.render = function(options, fn){
|
||||
fn(null, 'abstract engine');
|
||||
};
|
||||
|
||||
app.set('view', View);
|
||||
|
||||
app.render('something', function(err, str){
|
||||
if (err) return done(err);
|
||||
str.should.equal('abstract engine');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
describe('.render(name, options, fn)', function(){
|
||||
it('should render the template', function(done){
|
||||
var app = express();
|
||||
@@ -125,7 +148,7 @@ describe('app', function(){
|
||||
done();
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
it('should expose app.locals', function(done){
|
||||
var app = express();
|
||||
|
||||
@@ -138,7 +161,7 @@ describe('app', function(){
|
||||
done();
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
it('should give precedence to app.render() locals', function(done){
|
||||
var app = express();
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ describe('app.router', function(){
|
||||
calls.push('before');
|
||||
next();
|
||||
});
|
||||
|
||||
|
||||
app.use(app.router);
|
||||
|
||||
app.use(function(req, res, next){
|
||||
@@ -68,7 +68,7 @@ describe('app.router', function(){
|
||||
done();
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
it('should be auto .use()d on the first app.VERB() call', function(done){
|
||||
var app = express();
|
||||
|
||||
@@ -78,7 +78,7 @@ describe('app.router', function(){
|
||||
calls.push('before');
|
||||
next();
|
||||
});
|
||||
|
||||
|
||||
app.get('/', function(req, res, next){
|
||||
calls.push('GET /')
|
||||
next();
|
||||
@@ -109,7 +109,7 @@ describe('app.router', function(){
|
||||
.get('/user/12?foo=bar')
|
||||
.expect('user', done);
|
||||
})
|
||||
|
||||
|
||||
it('should populate req.params with the captures', function(done){
|
||||
var app = express();
|
||||
|
||||
@@ -124,24 +124,6 @@ describe('app.router', function(){
|
||||
.expect('editing user 10', done);
|
||||
})
|
||||
})
|
||||
|
||||
describe('when given an array', function(){
|
||||
it('should match all paths in the array', function(done){
|
||||
var app = express();
|
||||
|
||||
app.get(['/one', '/two'], function(req, res){
|
||||
res.end('works');
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/one')
|
||||
.expect('works', function() {
|
||||
request(app)
|
||||
.get('/two')
|
||||
.expect('works', done);
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
describe('case sensitivity', function(){
|
||||
it('should be disabled by default', function(done){
|
||||
@@ -155,7 +137,7 @@ describe('app.router', function(){
|
||||
.get('/USER')
|
||||
.expect('tj', done);
|
||||
})
|
||||
|
||||
|
||||
describe('when "case sensitive routing" is enabled', function(){
|
||||
it('should match identical casing', function(done){
|
||||
var app = express();
|
||||
@@ -170,7 +152,7 @@ describe('app.router', function(){
|
||||
.get('/uSer')
|
||||
.expect('tj', done);
|
||||
})
|
||||
|
||||
|
||||
it('should not match otherwise', function(done){
|
||||
var app = express();
|
||||
|
||||
@@ -199,7 +181,7 @@ describe('app.router', function(){
|
||||
.get('/user/')
|
||||
.expect('tj', done);
|
||||
})
|
||||
|
||||
|
||||
describe('when "strict routing" is enabled', function(){
|
||||
it('should match trailing slashes', function(done){
|
||||
var app = express();
|
||||
@@ -214,7 +196,7 @@ describe('app.router', function(){
|
||||
.get('/user/')
|
||||
.expect('tj', done);
|
||||
})
|
||||
|
||||
|
||||
it('should match no slashes', function(done){
|
||||
var app = express();
|
||||
|
||||
@@ -228,7 +210,7 @@ describe('app.router', function(){
|
||||
.get('/user')
|
||||
.expect('tj', done);
|
||||
})
|
||||
|
||||
|
||||
it('should fail when omitting the trailing slash', function(done){
|
||||
var app = express();
|
||||
|
||||
@@ -242,7 +224,7 @@ describe('app.router', function(){
|
||||
.get('/user')
|
||||
.expect(404, done);
|
||||
})
|
||||
|
||||
|
||||
it('should fail when adding the trailing slash', function(done){
|
||||
var app = express();
|
||||
|
||||
@@ -275,7 +257,7 @@ describe('app.router', function(){
|
||||
.expect(404, done);
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
it('should allow literal "."', function(done){
|
||||
var app = express();
|
||||
|
||||
@@ -303,7 +285,7 @@ describe('app.router', function(){
|
||||
.get('/user/tj.json')
|
||||
.expect('tj', done);
|
||||
})
|
||||
|
||||
|
||||
it('should work with several', function(done){
|
||||
var app = express();
|
||||
|
||||
@@ -346,7 +328,7 @@ describe('app.router', function(){
|
||||
.get('/api/users/0.json')
|
||||
.expect('users/0.json', done);
|
||||
})
|
||||
|
||||
|
||||
it('should not be greedy immediately after param', function(done){
|
||||
var app = express();
|
||||
|
||||
@@ -370,7 +352,7 @@ describe('app.router', function(){
|
||||
.get('/user/122/aaa')
|
||||
.expect('122', done);
|
||||
})
|
||||
|
||||
|
||||
it('should span multiple segments', function(done){
|
||||
var app = express();
|
||||
|
||||
@@ -382,7 +364,7 @@ describe('app.router', function(){
|
||||
.get('/file/javascripts/jquery.js')
|
||||
.expect('javascripts/jquery.js', done);
|
||||
})
|
||||
|
||||
|
||||
it('should be optional', function(done){
|
||||
var app = express();
|
||||
|
||||
@@ -394,7 +376,7 @@ describe('app.router', function(){
|
||||
.get('/file/')
|
||||
.expect('', done);
|
||||
})
|
||||
|
||||
|
||||
it('should require a preceeding /', function(done){
|
||||
var app = express();
|
||||
|
||||
@@ -420,7 +402,7 @@ describe('app.router', function(){
|
||||
.get('/user/tj')
|
||||
.expect('tj', done);
|
||||
})
|
||||
|
||||
|
||||
it('should match a single segment only', function(done){
|
||||
var app = express();
|
||||
|
||||
@@ -432,7 +414,7 @@ describe('app.router', function(){
|
||||
.get('/user/tj/edit')
|
||||
.expect(404, done);
|
||||
})
|
||||
|
||||
|
||||
it('should allow several capture groups', function(done){
|
||||
var app = express();
|
||||
|
||||
@@ -459,7 +441,7 @@ describe('app.router', function(){
|
||||
.get('/user/tj')
|
||||
.expect('viewing tj', done);
|
||||
})
|
||||
|
||||
|
||||
it('should populate the capture group', function(done){
|
||||
var app = express();
|
||||
|
||||
@@ -473,7 +455,7 @@ describe('app.router', function(){
|
||||
.expect('editing tj', done);
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
describe('.:name', function(){
|
||||
it('should denote a format', function(done){
|
||||
var app = express();
|
||||
@@ -491,7 +473,7 @@ describe('app.router', function(){
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
describe('.:name?', function(){
|
||||
it('should denote an optional format', function(done){
|
||||
var app = express();
|
||||
@@ -509,7 +491,7 @@ describe('app.router', function(){
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
describe('when next() is called', function(){
|
||||
it('should continue lookup', function(done){
|
||||
var app = express()
|
||||
@@ -528,7 +510,7 @@ describe('app.router', function(){
|
||||
calls.push('/foo');
|
||||
next();
|
||||
});
|
||||
|
||||
|
||||
app.get('/foo', function(req, res, next){
|
||||
calls.push('/foo 2');
|
||||
res.end('done');
|
||||
@@ -542,7 +524,7 @@ describe('app.router', function(){
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
describe('when next(err) is called', function(){
|
||||
it('should break out of app.router', function(done){
|
||||
var app = express()
|
||||
@@ -561,7 +543,7 @@ describe('app.router', function(){
|
||||
calls.push('/foo');
|
||||
next(new Error('fail'));
|
||||
});
|
||||
|
||||
|
||||
app.get('/foo', function(req, res, next){
|
||||
assert(0);
|
||||
});
|
||||
|
||||
36
test/req.acceptedEncodings.js
Normal file
36
test/req.acceptedEncodings.js
Normal file
@@ -0,0 +1,36 @@
|
||||
|
||||
var express = require('../')
|
||||
, request = require('./support/http');
|
||||
|
||||
describe('req', function(){
|
||||
describe('.acceptedEncodings', function(){
|
||||
it('should return an array of accepted encodings', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
req.acceptedEncodings.should.eql(['gzip', 'deflate']);
|
||||
res.end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Accept-Encoding', ' gzip, deflate')
|
||||
.expect(200, done);
|
||||
})
|
||||
|
||||
describe('when Accept-Encoding is not present', function(){
|
||||
it('should default to []', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
req.acceptedEncodings.should.have.length(0);
|
||||
res.end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect(200, done);
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -39,7 +39,7 @@ describe('res', function(){
|
||||
done();
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
it('should allow multiple calls', function(done){
|
||||
var app = express();
|
||||
|
||||
@@ -58,7 +58,7 @@ describe('res', function(){
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
describe('.cookie(name, string, options)', function(){
|
||||
it('should set params', function(done){
|
||||
var app = express();
|
||||
@@ -76,7 +76,7 @@ describe('res', function(){
|
||||
done();
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
describe('maxAge', function(){
|
||||
it('should set relative expires', function(done){
|
||||
var app = express();
|
||||
@@ -164,7 +164,7 @@ describe('res', function(){
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
var val = ['name=s%3Atobi.z6Nfs5haoP4UAqCcr497ZljiIbrNqn8EjjM10baIYvvG32lReGseC3v2T79fecY4G%2FLdEm9fpTihvlEMVuNjGw; Path=/'];
|
||||
var val = ['name=s%3Atobi.xJjV2iZ6EI7C8E5kzwbfA9PVLl1ZR07UTnuTgQQ4EnQ; Path=/'];
|
||||
res.headers['set-cookie'].should.eql(val);
|
||||
done();
|
||||
})
|
||||
|
||||
@@ -6,7 +6,7 @@ describe('utils.etag(body)', function(){
|
||||
|
||||
var str = 'Hello CRC';
|
||||
var strUTF8 = '<!DOCTYPE html>\n<html>\n<head>\n</head>\n<body><p>自動販売</p></body></html>';
|
||||
|
||||
|
||||
it('should support strings', function(){
|
||||
utils.etag(str).should.eql('"-2034458343"');
|
||||
})
|
||||
@@ -27,7 +27,7 @@ describe('utils.isAbsolute()', function(){
|
||||
assert(utils.isAbsolute('c:\\'));
|
||||
assert(!utils.isAbsolute(':\\'));
|
||||
})
|
||||
|
||||
|
||||
it('should unices', function(){
|
||||
assert(utils.isAbsolute('/foo/bar'));
|
||||
assert(!utils.isAbsolute('foo/bar'));
|
||||
@@ -52,32 +52,32 @@ describe('utils.escape(html)', function(){
|
||||
describe('utils.parseParams(str)', function(){
|
||||
it('should default quality to 1', function(){
|
||||
utils.parseParams('text/html')
|
||||
.should.eql([{ value: 'text/html', quality: 1, params: {}}]);
|
||||
.should.eql([{ value: 'text/html', quality: 1, params: {}, originalIndex: 0 }]);
|
||||
})
|
||||
|
||||
|
||||
it('should parse qvalues', function(){
|
||||
utils.parseParams('text/html; q=0.5')
|
||||
.should.eql([{ value: 'text/html', quality: 0.5, params: {}}]);
|
||||
.should.eql([{ value: 'text/html', quality: 0.5, params: {}, originalIndex: 0 }]);
|
||||
|
||||
utils.parseParams('text/html; q=.2')
|
||||
.should.eql([{ value: 'text/html', quality: 0.2, params: {}}]);
|
||||
.should.eql([{ value: 'text/html', quality: 0.2, params: {}, originalIndex: 0 }]);
|
||||
})
|
||||
|
||||
it('should parse accept parameters', function(){
|
||||
utils.parseParams('application/json; ver=2.0')
|
||||
.should.eql([{ value: 'application/json', quality: 1, params: {ver: "2.0"}}]);
|
||||
.should.eql([{ value: 'application/json', quality: 1, params: {ver: "2.0"}, originalIndex: 0 }]);
|
||||
|
||||
utils.parseParams('text/html; q=0.5; level=2')
|
||||
.should.eql([{ value: 'text/html', quality: 0.5, params: {level: "2"}}]);
|
||||
.should.eql([{ value: 'text/html', quality: 0.5, params: {level: "2"}, originalIndex: 0 }]);
|
||||
utils.parseParams('text/html;q=.2;ver=beta')
|
||||
.should.eql([{ value: 'text/html', quality: 0.2, params: {ver: "beta"}}]);
|
||||
.should.eql([{ value: 'text/html', quality: 0.2, params: {ver: "beta"}, originalIndex: 0 }]);
|
||||
})
|
||||
|
||||
it('should work with messed up whitespace', function(){
|
||||
utils.parseParams('text/html ; q = .2')
|
||||
.should.eql([{ value: 'text/html', quality: 0.2, params: {}}]);
|
||||
.should.eql([{ value: 'text/html', quality: 0.2, params: {}, originalIndex: 0 }]);
|
||||
})
|
||||
|
||||
|
||||
it('should work with multiples', function(){
|
||||
var str = 'da, en;q=.5, en-gb;q=.8';
|
||||
var arr = utils.parseParams(str);
|
||||
@@ -85,7 +85,13 @@ describe('utils.parseParams(str)', function(){
|
||||
arr[1].value.should.equal('en-gb');
|
||||
arr[2].value.should.equal('en');
|
||||
})
|
||||
|
||||
|
||||
it('should work with long lists', function(){
|
||||
var str = 'en, nl, fr, de, ja, it, es, pt, pt-PT, da, fi, nb, sv, ko, zh-Hans, zh-Hant, ru, pl';
|
||||
var arr = utils.parseParams(str).map(function(o){ return o.value });
|
||||
arr.should.eql(str.split(', '));
|
||||
})
|
||||
|
||||
it('should sort by quality', function(){
|
||||
var str = 'text/plain;q=.2, application/json, text/html;q=0.5';
|
||||
var arr = utils.parseParams(str);
|
||||
@@ -93,7 +99,7 @@ describe('utils.parseParams(str)', function(){
|
||||
arr[1].value.should.equal('text/html');
|
||||
arr[2].value.should.equal('text/plain');
|
||||
})
|
||||
|
||||
|
||||
it('should exclude those with a quality of 0', function(){
|
||||
var str = 'text/plain;q=.2, application/json, text/html;q=0';
|
||||
var arr = utils.parseParams(str);
|
||||
@@ -106,7 +112,7 @@ describe('utils.parseAccept(str)', function(){
|
||||
var arr = utils.parseAccept('text/html');
|
||||
arr[0].type.should.equal('text');
|
||||
})
|
||||
|
||||
|
||||
it('should provide .subtype', function(){
|
||||
var arr = utils.parseAccept('text/html');
|
||||
arr[0].subtype.should.equal('html');
|
||||
@@ -120,7 +126,7 @@ describe('utils.accepts(type, str)', function(){
|
||||
.should.equal('text/html');
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
describe('when a string is empty', function(){
|
||||
it('should return the value', function(){
|
||||
utils.accepts('text/html', '')
|
||||
@@ -166,44 +172,44 @@ describe('utils.accepts(type, str)', function(){
|
||||
utils.accepts('text/html', 'text/plain, text/html')
|
||||
.should.equal('text/html');
|
||||
})
|
||||
|
||||
|
||||
it('should return undefined otherwise', function(){
|
||||
assert(null == utils.accepts('text/html', 'text/plain, application/json'));
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
describe('when accepting */subtype', function(){
|
||||
it('should return the value when present', function(){
|
||||
utils.accepts('text/html', 'text/*')
|
||||
.should.equal('text/html');
|
||||
})
|
||||
|
||||
|
||||
it('should return undefined otherwise', function(){
|
||||
assert(null == utils.accepts('text/html', 'image/*'));
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
describe('when accepting type/*', function(){
|
||||
it('should return the value when present', function(){
|
||||
utils.accepts('text/html', '*/html')
|
||||
.should.equal('text/html');
|
||||
})
|
||||
|
||||
|
||||
it('should return undefined otherwise', function(){
|
||||
assert(null == utils.accepts('text/html', '*/json'));
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
describe('when an extension is given', function(){
|
||||
it('should return the value when present', function(){
|
||||
utils.accepts('html', 'text/html, application/json')
|
||||
.should.equal('html');
|
||||
})
|
||||
|
||||
|
||||
it('should return undefined otherwise', function(){
|
||||
assert(null == utils.accepts('html', 'text/plain, application/json'));
|
||||
})
|
||||
|
||||
|
||||
it('should support *', function(){
|
||||
utils.accepts('html', 'text/*')
|
||||
.should.equal('html');
|
||||
@@ -212,4 +218,4 @@ describe('utils.accepts(type, str)', function(){
|
||||
.should.equal('html');
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user