Comparar commits

..

21 Commits

Autor SHA1 Mensagem Data
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 b709009bc9 Release 3.0.3 2012-11-13 09:14:13 -08:00
TJ Holowaychuk b80d7ec257 update connect 2012-11-13 09:12:47 -08:00
TJ Holowaychuk ff0384e610 update cookie module 2012-11-13 09:12:32 -08:00
TJ Holowaychuk ab9c275bde fix cookie max-age
the cookie module we depend on never used to
set this value, however now it does :)
2012-11-13 09:08:37 -08:00
TJ Holowaychuk c70db96b06 Update examples/cors/index.js 2012-11-08 13:52:20 -08:00
TJ Holowaychuk 1c616e29e2 Merge branch 'master' of github.com:visionmedia/express 2012-11-08 09:20:29 -08:00
TJ Holowaychuk cb7518435f Merge pull request #1406 from DmitryBochkarev/patch-1
remove connect.static.send import from response.js
2012-11-08 09:20:20 -08:00
TJ Holowaychuk 79f81c0a25 Merge pull request #1408 from Laboratory/master
delete unused variables
2012-11-08 09:20:08 -08:00
Vitaly 534fbdb307 delete unused variables 2012-11-08 17:07:08 +04:00
Dmitry Bochkarev 6b309a4457 remove connect.static.send import from response.js 2012-11-08 12:43:38 +05:00
TJ Holowaychuk af5e38c31a Update Readme.md 2012-11-05 09:10:34 -08:00
13 arquivos alterados com 156 adições e 32 exclusões
+1
Ver Arquivo
@@ -16,3 +16,4 @@ testing
.coverage_data
cover_html
test.js
.idea
+16
Ver Arquivo
@@ -1,4 +1,20 @@
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
==================
* update connect
* update cookie module
* fix cookie max-age
3.0.2 / 2012-11-08
==================
-4
Ver Arquivo
@@ -17,10 +17,6 @@ app.listen(3000);
$ npm install -g express
To install the 3.0 alpha:
$ npm install -g express@3.0
## Quick Start
The quickest way to get started with express is to utilize the executable `express(1)` to generate an application as shown below:
+1 -1
Ver Arquivo
@@ -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');
+3 -4
Ver Arquivo
@@ -45,10 +45,9 @@ app.init = function(){
*/
app.defaultConfiguration = function(){
var self = this;
// default settings
this.enable('x-powered-by');
this.enable('etag');
this.set('env', process.env.NODE_ENV || 'development');
debug('booting in %s mode', this.get('env'));
@@ -103,7 +102,7 @@ app.defaultConfiguration = function(){
*/
app.use = function(route, fn){
var app, handle;
var app;
// default route to '/'
if ('string' != typeof route) fn = route, route = '/';
@@ -404,7 +403,7 @@ app.configure = function(env, fn){
methods.forEach(function(method){
app[method] = function(path){
if ('get' == method && 1 == arguments.length) return this.set(path);
if ('get' == method && 1 == arguments.length) return this.set(path);
var args = [method].concat([].slice.call(arguments));
if (!this._usedRouter) this.use(this.router);
this._router.route.apply(this._router, args);
+1 -1
Ver Arquivo
@@ -20,7 +20,7 @@ exports = module.exports = createApplication;
* Framework version.
*/
exports.version = '3.0.2';
exports.version = '3.0.3';
/**
* Expose mime.
+15 -12
Ver Arquivo
@@ -11,7 +11,6 @@ var http = require('http')
, normalizeTypes = require('./utils').normalizeTypes
, etag = require('./utils').etag
, statusCodes = http.STATUS_CODES
, send = connect.static.send
, cookie = require('cookie')
, send = require('send')
, mime = connect.mime
@@ -83,6 +82,9 @@ res.send = function(body){
, head = 'HEAD' == req.method
, len;
// settings
var app = this.app;
// allow status / body
if (2 == arguments.length) {
// res.send(body, status) backwards compat
@@ -129,7 +131,7 @@ res.send = function(body){
// ETag support
// TODO: W/ support
if (len > 1024) {
if (app.settings.etag && len > 1024) {
if (!this.get('ETag')) {
this.set('ETag', etag(body));
}
@@ -242,7 +244,7 @@ res.jsonp = function(obj){
/**
* Transfer the file at the given `path`.
*
*
* Automatically sets the _Content-Type_ response header field.
* The callback `fn(err)` is invoked when the transfer is complete
* or when an error occurs. Be sure to check `res.sentHeader`
@@ -264,7 +266,7 @@ res.jsonp = function(obj){
* app.get('/user/:uid/photos/:file', function(req, res){
* var uid = req.params.uid
* , file = req.params.file;
*
*
* req.user.mayViewFilesFrom(uid, function(yes){
* if (yes) {
* res.sendfile('/uploads/' + uid + '/' + file);
@@ -409,11 +411,11 @@ res.type = function(type){
* 'text/plain': function(){
* res.send('hey');
* },
*
*
* 'text/html': function(){
* res.send('<p>hey</p>');
* },
*
*
* 'appliation/json': function(){
* res.send({ message: 'hey' });
* }
@@ -426,11 +428,11 @@ res.type = function(type){
* text: function(){
* res.send('hey');
* },
*
*
* html: function(){
* res.send('<p>hey</p>');
* },
*
*
* json: function(){
* res.send({ message: 'hey' });
* }
@@ -499,7 +501,7 @@ res.attachment = function(filename){
* res.set('Accept', 'application/json');
* res.set({ Accept: 'text/plain', 'X-API-Key': 'tobi' });
*
* Aliased as `res.header()`.
* Aliased as `res.header()`.
*
* @param {String|Object} field
* @param {String} val
@@ -507,7 +509,7 @@ res.attachment = function(filename){
* @api public
*/
res.set =
res.set =
res.header = function(field, val){
if (2 == arguments.length) {
this.setHeader(field, '' + val);
@@ -579,6 +581,7 @@ res.cookie = function(name, val, options){
if (signed) val = 's:' + sign(val, secret);
if ('maxAge' in options) options.expires = new Date(Date.now() + options.maxAge);
if (null == options.path) options.path = '/';
options.maxAge /= 1000;
this.set('Set-Cookie', cookie.serialize(name, String(val), options));
return this;
};
@@ -602,7 +605,7 @@ res.cookie = function(name, val, options){
* Mounting:
*
* When an application is mounted, and `res.redirect()`
* is given a path that does _not_ lead with "/". For
* is given a path that does _not_ lead with "/". For
* example suppose a "blog" app is mounted at "/blog",
* the following redirect would result in "/blog/login":
*
@@ -656,7 +659,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(){
+2 -4
Ver Arquivo
@@ -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) + '"';
};
/**
+6 -6
Ver Arquivo
@@ -1,21 +1,21 @@
{
"name": "express",
"description": "Sinatra inspired web development framework",
"version": "3.0.2",
"version": "3.0.4",
"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.6.2",
"connect": "2.7.1",
"commander": "0.6.1",
"range-parser": "0.0.4",
"mkdirp": "0.3.3",
"cookie": "0.0.4",
"crc": "0.2.0",
"cookie": "0.0.5",
"buffer-crc32": "0.1.1",
"fresh": "0.1.0",
"methods": "0.0.1",
"send": "0.1.0",
+16
Ver Arquivo
@@ -92,6 +92,22 @@ describe('res', function(){
done();
})
})
it('should set max-age', function(done){
var app = express();
app.use(function(req, res){
res.cookie('name', 'tobi', { maxAge: 1000 });
res.end();
});
request(app)
.get('/')
.end(function(err, res){
res.headers['set-cookie'][0].should.include('Max-Age=1');
done();
})
})
})
describe('signed', function(){
+17
Ver Arquivo
@@ -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(){
+58
Ver Arquivo
@@ -298,4 +298,62 @@ describe('res', function(){
.get('/?callback=foo')
.expect('{"foo":"bar"}', done);
})
describe('"etag" setting', function(){
describe('when enabled', function(){
it('should send ETag ', function(done){
var app = express();
app.use(function(req, res){
var str = Array(1024 * 2).join('-');
res.send(str);
});
request(app)
.get('/')
.end(function(err, res){
res.headers.should.have.property('etag', '"-1498647312"');
done();
});
});
});
describe('when disabled', function(){
it('should send no ETag', function(done){
var app = express();
app.use(function(req, res){
var str = Array(1024 * 2).join('-');
res.send(str);
});
app.disable('etag');
request(app)
.get('/')
.end(function(err, res){
res.headers.should.not.have.property('etag');
done();
});
});
it('should send ETag when manually set', function(done){
var app = express();
app.disable('etag');
app.use(function(req, res){
res.set('etag', 1);
res.send(200);
});
request(app)
.get('/')
.end(function(err, res){
res.headers.should.have.property('etag');
done();
});
});
});
})
})
+20
Ver Arquivo
@@ -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:\\'));