Compare commits

...

34 Commits
3.4.5 ... 3.5.2

Author SHA1 Message Date
Douglas Christopher Wilson
d5815922ca 3.5.2 2014-04-24 16:36:37 -04:00
Douglas Christopher Wilson
972c01afc9 update supertest to 0.11.0 2014-04-24 16:30:58 -04:00
Douglas Christopher Wilson
8894e30869 Skip publishing benchmarks dir to npm 2014-04-24 16:27:00 -04:00
Douglas Christopher Wilson
5d8dba5fe0 update mocha to 1.18.2 2014-04-24 16:23:58 -04:00
Douglas Christopher Wilson
90fbc1a33e update cookie to 0.1.2 2014-04-24 16:21:22 -04:00
Douglas Christopher Wilson
55dea47b94 update mkdirp to 0.4.0 2014-04-24 16:20:31 -04:00
Douglas Christopher Wilson
c7791a207b update send to 0.3.0
fixes #2024
closes #2071
closes #2072
2014-04-24 15:50:55 -04:00
Douglas Christopher Wilson
30d18888b9 update connect to 2.14.5 2014-04-24 15:50:54 -04:00
Roman Shtylman
df50669092 3.5.1 2014-03-25 16:56:54 -04:00
Roman Shtylman
abd6b7c5c3 pin down less-middleware
Things are broken in 0.2 version of less-middleware so use 0.1 line
2014-03-25 16:55:57 -04:00
Jonathan Ong
87912103c9 3.5.0 2014-03-06 14:57:30 -08:00
Jonathan Ong
4ce1ee458e bump deps 2014-03-06 14:57:05 -08:00
Roman Shtylman
8aff64f89a backport dependency updates
- range parser 1.0.0
- fresh 0.2.1
- send 0.2.0
- cookie-signature 1.0.3
- merge-descriptors 0.0.2
2014-01-29 20:06:38 -05:00
Jonathan Ong
ff23423d34 3.4.8 2014-01-13 20:50:51 -08:00
Doug Patti
1d97599f8b prevent incorrect automatic OPTIONS responses
The router has automatic handling of OPTIONS based on the registered
routes, but if you make an OPTIONS request for an endpoint that does
not exist, then it will still return a 200 with nothing allowed.
Instead, we can let the request move on down the middleware chain. This
has two benefits: first, if the route was not defined and no other
middleware handles it, it will return with a 404. Secondly, if multiple
routers are used and a later one has the route or a custom OPTIONS
defined, the first router will not respond incorrectly.
2014-01-13 20:46:07 -08:00
Matheus Azzi
e465624fd0 Update layout.jade 2014-01-13 20:45:50 -08:00
TJ Holowaychuk
dc5932d177 Merge pull request #1877 from reqshark/master
update express jade layout generator
2013-12-23 10:34:47 -08:00
Bent Cardan
cfd93b7529 update express jade layout generator
update doctype
2013-12-23 13:03:21 -05:00
Jonathan Ong
8b2208f394 Merge pull request #1876 from yosssi/dev
Updated the example file to use `doctype html` on  because  `doctype 5` was deprecated on Jade version 1.0.0.
2013-12-23 08:10:26 -08:00
yosssi
00a3b01f39 Changed doctype 5 to doctype html on the example file because the former was deprecated on Jade version 1.0.0. 2013-12-23 22:13:05 +09:00
TJ Holowaychuk
3baca251f0 use 8 threads for benchmarks 2013-12-22 08:57:04 -08:00
TJ Holowaychuk
72daae1d92 Merge pull request #1869 from yamatt/master
Error message now describes where the view was not able to be found.
2013-12-21 11:13:04 -08:00
Matt Copperwaite
fcbe53ddb5 Added appropriate test for more descriptive render error 2013-12-21 17:34:59 +00:00
Jonathan Ong
e9851672eb bench: remove --harmony-generators flag 2013-12-20 21:15:17 -08:00
TJ Holowaychuk
9a45f7bd3d add new benchmarks (to match koa) 2013-12-20 19:34:59 -08:00
Matt Copperwaite
85834fd146 Error message now describes where the view was not able to be found. Useful for debugging. 2013-12-20 11:39:31 +00:00
Roman Shtylman
a0c1ac7b45 add license field to package.json
close #1862
2013-12-18 10:16:56 -05:00
Alex Kocharin
7b0dca0f9c throw 400 in case of malformed paths 2013-12-11 17:14:44 -08:00
Jonathan Ong
34c83d7d29 3.4.7 2013-12-10 23:57:39 -08:00
Jonathan Ong
7c6882234e bump connect, mocha, and should 2013-12-10 23:54:07 -08:00
Jonathan Ong
2e68ddbae9 expose connect.middleware using Object.getOwnPropertyDescriptor()
closes #1853. no tests, but it should be fine.
2013-12-10 23:52:48 -08:00
Jonathan Ong
7724fc6af7 3.4.6 2013-12-01 12:21:08 -08:00
Roman Shtylman
2939075f03 Merge pull request #1836 from fluxusfrequency/patch-1
Grammar and punctuation fixes [ci skip]
2013-11-28 08:18:42 -08:00
Ben Lewis
606f68de02 Grammar and punctuation fixes [ci skip] 2013-11-28 06:36:21 -07:00
20 changed files with 201 additions and 109 deletions

View File

@@ -1,4 +1,5 @@
.git*
benchmarks/
docs/
examples/
support/

View File

@@ -1,3 +1,38 @@
3.5.2 / 2014-04-24
==================
* update connect to 2.14.5
* update cookie to 0.1.2
* update mkdirp to 0.4.0
* update send to 0.3.0
3.5.1 / 2014-03-25
==================
* pin less-middleware in generated app
3.5.0 / 2014-03-06
==================
* bump deps
3.4.8 / 2014-01-13
==================
* prevent incorrect automatic OPTIONS responses #1868 @dpatti
* update binary and examples for jade 1.0 #1876 @yossi, #1877 @reqshark, #1892 @matheusazzi
* throw 400 in case of malformed paths @rlidwka
3.4.7 / 2013-12-10
==================
* update connect
3.4.6 / 2013-12-01
==================
* update connect (raw-body)
3.4.5 / 2013-11-27
==================

View File

@@ -24,11 +24,11 @@ test-cov: lib-cov
lib-cov:
@jscoverage lib lib-cov
benchmark:
@./support/bench
bench:
@$(MAKE) -C benchmarks
clean:
rm -f coverage.html
rm -fr lib-cov
.PHONY: test test-unit test-acceptance benchmark clean
.PHONY: test test-unit test-acceptance bench clean

View File

@@ -50,14 +50,14 @@ app.listen(3000);
## Philosophy
The Express philosophy is to provide small, robust tooling for HTTP servers. Making
The Express philosophy is to provide small, robust tooling for HTTP servers, making
it a great solution for single page applications, web sites, hybrids, or public
HTTP APIs.
Built on Connect you can use _only_ what you need, and nothing more, applications
Built on Connect, you can use _only_ what you need, and nothing more. Applications
can be as big or as small as you like, even a single file. Express does
not force you to use any specific ORM or template engine. With support for over
14 template engines via [Consolidate.js](http://github.com/visionmedia/consolidate.js)
14 template engines via [Consolidate.js](http://github.com/visionmedia/consolidate.js),
you can quickly craft your perfect framework.
## More Information
@@ -72,27 +72,27 @@ app.listen(3000);
## Viewing Examples
Clone the Express repo, then install the dev dependencies to install all the example / test suite deps:
Clone the Express repo, then install the dev dependencies to install all the example / test suite dependencies:
$ git clone git://github.com/visionmedia/express.git --depth 1
$ cd express
$ npm install
then run whichever tests you want:
Then run whichever tests you want:
$ node examples/content-negotiation
You can also view live examples here
You can also view live examples here:
<a href="https://runnable.com/express" target="_blank"><img src="https://runnable.com/external/styles/assets/runnablebtn.png" style="width:67px;height:25px;"></a>
## Running Tests
To run the test suite first invoke the following command within the repo, installing the development dependencies:
To run the test suite, first invoke the following command within the repo, installing the development dependencies:
$ npm install
then run the tests:
Then run the tests:
$ make test

13
benchmarks/Makefile Normal file
View File

@@ -0,0 +1,13 @@
all:
@./run 1 middleware
@./run 5 middleware
@./run 10 middleware
@./run 15 middleware
@./run 20 middleware
@./run 30 middleware
@./run 50 middleware
@./run 100 middleware
@echo
.PHONY: all

23
benchmarks/middleware.js Normal file
View File

@@ -0,0 +1,23 @@
var http = require('http');
var express = require('..');
var app = express();
// number of middleware
var n = parseInt(process.env.MW || '1', 10);
console.log(' %s middleware', n);
while (n--) {
app.use(function(req, res, next){
next();
});
}
var body = new Buffer('Hello World');
app.use(function(req, res, next){
res.send(body);
});
app.listen(3333);

16
benchmarks/run Executable file
View File

@@ -0,0 +1,16 @@
#!/usr/bin/env bash
echo
MW=$1 node $2 &
pid=$!
sleep 2
wrk 'http://localhost:3333/?foo[bar]=baz' \
-d 3 \
-c 50 \
-t 8 \
| grep 'Requests/sec' \
| awk '{ print " " $2 }'
kill $pid

View File

@@ -74,7 +74,7 @@ var users = [
*/
var jadeLayout = [
'doctype 5'
'doctype html'
, 'html'
, ' head'
, ' title= title'
@@ -357,7 +357,7 @@ function createApplicationAt(path) {
// CSS Engine support
switch (program.css) {
case 'less':
pkg.dependencies['less-middleware'] = '*';
pkg.dependencies['less-middleware'] = '~0.1.15';
break;
default:
if (program.css) {

View File

@@ -1,5 +1,5 @@
!!! 5
doctype html
html
include header
body
block content
block content

View File

@@ -1,4 +1,4 @@
doctype 5
doctype html
html
head
title= title

View File

@@ -490,7 +490,7 @@ app.render = function(name, options, fn){
});
if (!view.path) {
var err = new Error('Failed to lookup view "' + name + '"');
var err = new Error('Failed to lookup view "' + name + '" in views directory "' + view.root + '"');
err.view = view;
return fn(err);
}

View File

@@ -2,6 +2,7 @@
* Module dependencies.
*/
var merge = require('merge-descriptors');
var connect = require('connect')
, proto = require('./application')
, Route = require('./router/route')
@@ -43,12 +44,7 @@ function createApplication() {
* for example `express.logger` etc.
*/
for (var key in connect.middleware) {
Object.defineProperty(
exports
, key
, Object.getOwnPropertyDescriptor(connect.middleware, key));
}
merge(exports, connect.middleware);
/**
* Error on createServer().

View File

@@ -104,7 +104,7 @@ Router.prototype._dispatch = function(req, res, next){
req.route = route = self.matchRequest(req, i);
// implied OPTIONS
if (!route && 'OPTIONS' == req.method) return self._options(req, res);
if (!route && 'OPTIONS' == req.method) return self._options(req, res, next);
// no route
if (!route) return next(err);
@@ -181,9 +181,10 @@ Router.prototype._dispatch = function(req, res, next){
* @api private
*/
Router.prototype._options = function(req, res){
Router.prototype._options = function(req, res, next){
var path = parse(req).pathname
, body = this._optionsFor(path).join(',');
if (!body) return next();
res.set('Allow', body).send(body);
};

View File

@@ -57,9 +57,15 @@ Route.prototype.match = function(path){
for (var i = 1, len = m.length; i < len; ++i) {
var key = keys[i - 1];
var val = 'string' == typeof m[i]
? utils.decode(m[i])
: m[i];
try {
var 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;

View File

@@ -312,22 +312,3 @@ exports.pathRegexp = function(path, keys, sensitive, strict) {
.replace(/\*/g, '(.*)');
return new RegExp('^' + path + '$', sensitive ? '' : 'i');
}
/**
* Decodes a URI component. Returns
* the original string if the component
* is malformed.
*
* @param {String} str
* @return {String}
* @api private
*/
exports.decode = function(str) {
try {
return decodeURIComponent(str);
} catch (e) {
return str;
}
}

View File

@@ -1,7 +1,7 @@
{
"name": "express",
"description": "Sinatra inspired web development framework",
"version": "3.4.5",
"version": "3.5.2",
"author": "TJ Holowaychuk <tj@vision-media.ca>",
"contributors": [
{
@@ -22,28 +22,29 @@
}
],
"dependencies": {
"connect": "2.11.1",
"connect": "2.14.5",
"commander": "1.3.2",
"range-parser": "0.0.4",
"mkdirp": "0.3.5",
"cookie": "0.1.0",
"range-parser": "1.0.0",
"mkdirp": "0.4.0",
"cookie": "0.1.2",
"buffer-crc32": "0.2.1",
"fresh": "0.2.0",
"fresh": "0.2.2",
"methods": "0.1.0",
"send": "0.1.4",
"cookie-signature": "1.0.1",
"send": "0.3.0",
"cookie-signature": "1.0.3",
"merge-descriptors": "0.0.2",
"debug": ">= 0.7.3 < 1"
},
"devDependencies": {
"ejs": "~0.8.4",
"mocha": "~1.14.0",
"mocha": "~1.18.2",
"jade": "~0.30.0",
"hjs": "~0.0.6",
"stylus": "~0.40.0",
"should": "~2.0.2",
"should": "~2.1.1",
"connect-redis": "~1.4.5",
"marked": "0.2.10",
"supertest": "~0.8.1"
"supertest": "~0.11.0"
},
"keywords": [
"express",
@@ -67,5 +68,6 @@
},
"engines": {
"node": ">= 0.8.0"
}
},
"license": "MIT"
}

View File

@@ -1,32 +0,0 @@
#!/usr/bin/env bash
NODE_ENV=production node ./support/app &
pid=$!
bench() {
ab -n 5000 -c 50 -k -q http://127.0.0.1:8000$1 \
| grep "Requests per" \
| cut -d ' ' -f 7 \
| xargs echo "$2:"
}
bench_conditional() {
ab -n 5000 -c 50 -H "If-None-Match: $3" -k -q http://127.0.0.1:8000$1 \
| grep "Requests per" \
| cut -d ' ' -f 7 \
| xargs echo "$2:"
}
sleep .5
bench / "Hello World"
bench /blog "Mounted Hello World"
bench /blog/admin "Mounted 2 Hello World"
bench /middleware "Middleware"
bench /match "Router"
bench /render "Render"
bench /json "JSON tiny"
bench /json/15 "JSON small"
bench /json/50 "JSON medium"
bench /json/150 "JSON large"
kill -9 $pid

View File

@@ -15,6 +15,30 @@ describe('OPTIONS', function(){
.expect('GET,PUT')
.expect('Allow', 'GET,PUT', done);
})
it('should not respond if the path is not defined', function(done){
var app = express();
app.get('/users', function(req, res){});
request(app)
.options('/other')
.expect(404, done);
})
it('should forward requests down the middleware chain', function(done){
var app = express();
var router = new express.Router();
router.get('/users', function(req, res){});
app.use(router.middleware);
app.get('/other', function(req, res){});
request(app)
.options('/other')
.expect('GET')
.expect('Allow', 'GET', done);
})
})
describe('app.options()', function(){

View File

@@ -59,7 +59,7 @@ describe('app', function(){
var app = express();
app.set('views', __dirname + '/fixtures');
app.render('rawr.jade', function(err){
err.message.should.equal('Failed to lookup view "rawr.jade"');
err.message.should.equal('Failed to lookup view "rawr.jade" in views directory "' + __dirname + '/fixtures"');
done();
});
})

View File

@@ -27,28 +27,54 @@ describe('app.router', function(){
});
})
it('should decode params', function(done){
var app = express();
describe('decode querystring', function(){
it('should decode correct params', function(done){
var app = express();
app.get('/:name', function(req, res, next){
res.send(req.params.name);
});
app.get('/:name', function(req, res, next){
res.send(req.params.name);
});
request(app)
.get('/foo%2Fbar')
.expect('foo/bar', done);
})
request(app)
.get('/foo%2Fbar')
.expect('foo/bar', done);
})
it('should accept params in malformed paths', function(done) {
var app = express();
it('should not accept params in malformed paths', function(done) {
var app = express();
app.get('/:name', function(req, res, next){
res.send(req.params.name);
});
app.get('/:name', function(req, res, next){
res.send(req.params.name);
});
request(app)
.get('/%foobar')
.expect('%foobar', done);
request(app)
.get('/%foobar')
.expect(400, done);
})
it('should not decode spaces', function(done) {
var app = express();
app.get('/:name', function(req, res, next){
res.send(req.params.name);
});
request(app)
.get('/foo+bar')
.expect('foo+bar', done);
})
it('should work with unicode', function(done) {
var app = express();
app.get('/:name', function(req, res, next){
res.send(req.params.name);
});
request(app)
.get('/%ce%b1')
.expect('\u03b1', done);
})
})
it('should be .use()able', function(done){