Compare commits

...

16 Commits
3.0.3 ... 3.0.5

Author SHA1 Message Date
TJ Holowaychuk
33eaa8329c Release 3.0.5 2012-12-19 13:46:16 -08:00
TJ Holowaychuk
3c4fd57e51 Merge pull request #1451 from aweeks/fix-304-must-not-contain-body
Explicitly remove Transfer-Encoding header from 204 and 304 responses
2012-12-19 13:34:16 -08:00
Alex Weeks
a1e42ac33f Explicitly remove Transfer-Encoding header from 204 and 304 responses
Per RFC 2616 §10.3.6 & §10.2.5 (http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) "The [204/304] response MUST NOT contain a message-body, and thus is always terminated by the first empty line after the header fields."
2012-12-19 10:53:17 -08:00
Thorsten Lorenz
ce7d7bfd8d add throwing when a non-function is passed to a route 2012-12-14 15:06:17 -08:00
TJ Holowaychuk
9bd86cdddc Revert "add 'etag' option"
This reverts commit 6f6eec7d8d.
2012-12-06 15:15:49 -08:00
TJ Holowaychuk
0117464ac2 Release 3.0.4 2012-12-05 17:10:59 -08:00
Max Riveiro
6f6eec7d8d add 'etag' option 2012-12-05 16:49:09 -08:00
TJ Holowaychuk
a4e93c0fb8 update connect 2012-12-05 16:35:44 -08:00
TJ Holowaychuk
e2ad0d3d6e merge 2012-11-21 08:46:36 -08:00
TJ Holowaychuk
763be5e631 Merge pull request #1426 from piscis/master
change crc generator because of license issue
2012-11-21 08:45:42 -08:00
TJ Holowaychuk
c8526932f3 Merge branch 'master' of github.com:visionmedia/express 2012-11-21 08:43:13 -08:00
TJ Holowaychuk
5cf29a3d29 Merge pull request #1425 from gmethvin/encode_text_redirect
Escape URLs in text/plain res.redirect response
2012-11-21 08:42:33 -08:00
Alexander Pirsig
18a3cc03ee use buffer-crc32 module for ETag CRC generator 2012-11-21 12:44:07 +01:00
Greg Methvin
ea5e254c7d Escape URLs in text/plain res.redirect response
Escape the URL printed by res.redirect using URL encoding. This
prevents some browsers (primarily old versions of IE) from attempting
to sniff the Content-Type and evaluate it as HTML, which causes a
cross-site scripting vulnerability.
2012-11-21 02:22:37 -05:00
TJ Holowaychuk
060653bd4c Merge branch 'master' of github.com:visionmedia/express 2012-11-20 14:25:30 -08:00
TJ Holowaychuk
c70db96b06 Update examples/cors/index.js 2012-11-08 13:52:20 -08:00
11 changed files with 104 additions and 20 deletions

View File

@@ -1,4 +1,20 @@
3.0.5 / 2012-12-19
==================
* add throwing when a non-function is passed to a route
* fix: explicitly remove Transfer-Encoding header from 204 and 304 responses
* revert "add 'etag' option"
3.0.4 / 2012-12-05
==================
* add 'etag' option to disable `res.send()` Etags
* add escaping of urls in text/plain in `res.redirect()`
for old browsers interpreting as html
* change crc32 module for a more liberal license
* update connect
3.0.3 / 2012-11-13
==================

View File

@@ -1,4 +1,3 @@
/**
* Module dependencies.
*/
@@ -21,6 +20,7 @@ api.use(express.bodyParser());
*/
api.all('*', function(req, res, next){
if (!req.get('Origin')) return next();
// use "*" here to accept any origin
res.set('Access-Control-Allow-Origin', 'http://localhost:3000');
res.set('Access-Control-Allow-Methods', 'GET, POST');

View File

@@ -20,7 +20,7 @@ exports = module.exports = createApplication;
* Framework version.
*/
exports.version = '3.0.3';
exports.version = '3.0.5';
/**
* Expose mime.
@@ -46,7 +46,7 @@ function createApplication() {
/**
* Expose connect.middleware as express.*
* for example `express.logger` etc.
* for example `express.logger` etc.
*/
for (var key in connect.middleware) {

View File

@@ -141,6 +141,7 @@ res.send = function(body){
if (204 == this.statusCode || 304 == this.statusCode) {
this.removeHeader('Content-Type');
this.removeHeader('Content-Length');
this.removeHeader('Transfer-Encoding');
body = '';
}
@@ -656,7 +657,7 @@ res.redirect = function(url){
// Support text/{plain,html} by default
this.format({
text: function(){
body = statusCodes[status] + '. Redirecting to ' + url;
body = statusCodes[status] + '. Redirecting to ' + encodeURI(url);
},
html: function(){

View File

@@ -243,11 +243,17 @@ Router.prototype.route = function(method, path, callbacks){
// ensure path was given
if (!path) throw new Error('Router#' + method + '() requires a path');
// ensure all callbacks are functions
callbacks.forEach(function(fn){
if ('function' == typeof fn) return;
throw new Error('Router#' + method + '() requires all callbacks to be functions');
});
// create the route
debug('defined %s %s', method, path);
var route = new Route(method, path, callbacks, {
sensitive: this.caseSensitive
, strict: this.strict
sensitive: this.caseSensitive,
strict: this.strict
});
// add it

View File

@@ -4,7 +4,7 @@
*/
var mime = require('connect').mime
, crc = require('crc');
, crc32 = require('buffer-crc32');
/**
* Return ETag for `body`.
@@ -15,9 +15,7 @@ var mime = require('connect').mime
*/
exports.etag = function(body){
return '"' + (Buffer.isBuffer(body)
? crc.buffer.crc32(body)
: crc.crc32(body)) + '"';
return '"' + crc32.signed(body) + '"';
};
/**

View File

@@ -1,21 +1,21 @@
{
"name": "express",
"description": "Sinatra inspired web development framework",
"version": "3.0.3",
"version": "3.0.5",
"author": "TJ Holowaychuk <tj@vision-media.ca>",
"contributors": [
{ "name": "TJ Holowaychuk", "email": "tj@vision-media.ca" },
"contributors": [
{ "name": "TJ Holowaychuk", "email": "tj@vision-media.ca" },
{ "name": "Aaron Heckmann", "email": "aaron.heckmann+github@gmail.com" },
{ "name": "Ciaran Jessup", "email": "ciaranj@gmail.com" },
{ "name": "Guillermo Rauch", "email": "rauchg@gmail.com" }
],
"dependencies": {
"connect": "2.7.0",
"connect": "2.7.1",
"commander": "0.6.1",
"range-parser": "0.0.4",
"mkdirp": "0.3.3",
"cookie": "0.0.5",
"crc": "0.2.0",
"buffer-crc32": "0.1.1",
"fresh": "0.1.0",
"methods": "0.0.1",
"send": "0.1.0",

View File

@@ -76,4 +76,28 @@ describe('Router', function(){
.expect('foo', done);
})
})
})
describe('.multiple callbacks', function(){
it('should throw if a callback is null', function(){
assert.throws(function () {
router.route('get', '/foo', null, function(){});
})
})
it('should throw if a callback is undefined', function(){
assert.throws(function () {
router.route('get', '/foo', undefined, function(){});
})
})
it('should throw if a callback is not a function', function(){
assert.throws(function () {
router.route('get', '/foo', 'not a function', function(){});
})
})
it('should not throw if all callbacks are functions', function(){
router.route('get', '/foo', function(){}, function(){});
})
})
})

View File

@@ -287,6 +287,23 @@ describe('res', function(){
done();
})
})
it('should encode the url', function(done){
var app = express();
app.use(function(req, res){
res.redirect('http://example.com/?param=<script>alert("hax");</script>');
});
request(app)
.get('/')
.set('Host', 'http://example.com')
.set('Accept', 'text/plain, */*')
.end(function(err, res){
res.text.should.equal('Moved Temporarily. Redirecting to http://example.com/?param=%3Cscript%3Ealert(%22hax%22);%3C/script%3E');
done();
})
})
})
describe('when accepting neither text or html', function(){

View File

@@ -206,11 +206,11 @@ describe('res', function(){
})
describe('when .statusCode is 204', function(){
it('should strip Content-* fields & body', function(done){
it('should strip Content-* fields, Transfer-Encoding field, and body', function(done){
var app = express();
app.use(function(req, res){
res.status(204).send('foo');
res.status(204).set('Transfer-Encoding', 'chunked').send('foo');
});
request(app)
@@ -218,6 +218,7 @@ describe('res', function(){
.end(function(err, res){
res.headers.should.not.have.property('content-type');
res.headers.should.not.have.property('content-length');
res.headers.should.not.have.property('transfer-encoding');
res.text.should.equal('');
done();
})
@@ -225,11 +226,11 @@ describe('res', function(){
})
describe('when .statusCode is 304', function(){
it('should strip Content-* fields & body', function(done){
it('should strip Content-* fields, Transfer-Encoding field, and body', function(done){
var app = express();
app.use(function(req, res){
res.status(304).send('foo');
res.status(304).set('Transfer-Encoding', 'chunked').send('foo');
});
request(app)
@@ -237,6 +238,7 @@ describe('res', function(){
.end(function(err, res){
res.headers.should.not.have.property('content-type');
res.headers.should.not.have.property('content-length');
res.headers.should.not.have.property('transfer-encoding');
res.text.should.equal('');
done();
})

View File

@@ -2,6 +2,26 @@
var utils = require('../lib/utils')
, assert = require('assert');
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"');
})
it('should support utf8 strings', function(){
utils.etag(strUTF8).should.eql('"1395090196"');
})
it('should support buffer', function(){
utils.etag(new Buffer(strUTF8)).should.eql('"1395090196"');
utils.etag(new Buffer(str)).should.eql('"-2034458343"');
})
})
describe('utils.isAbsolute()', function(){
it('should support windows', function(){
assert(utils.isAbsolute('c:\\'));