Compare commits

...

78 Commits
3.2.2 ... 3.3.6

Author SHA1 Message Date
TJ Holowaychuk
197a2e3b54 Release 3.3.6 2013-08-27 13:49:09 -07:00
TJ Holowaychuk
6cf6c8b918 Revert "remove charset from json responses. Closes #1631"
This reverts commit 138d74aefa.
2013-08-27 13:48:18 -07:00
TJ Holowaychuk
752b5f705e Merge branch 'master' of github.com:visionmedia/express 2013-08-17 01:07:17 -07:00
TJ Holowaychuk
e7fa579637 update license 2013-08-17 01:07:09 -07:00
TJ Holowaychuk
97781d4112 Merge pull request #1723 from gmethvin/accepts
Make req.accepts take an argument list
2013-08-16 16:32:48 -07:00
Greg Methvin
3ddd8e66a7 Make req.accepts take an argument list 2013-08-16 15:19:33 -07:00
TJ Holowaychuk
8a1e865e37 remove silly out-of-date dep badge 2013-08-15 08:18:01 -07:00
TJ Holowaychuk
e850cb3ea3 Release 3.3.5 2013-08-11 07:50:51 +10:00
TJ Holowaychuk
13d3efe8df update fresh 2013-08-11 07:49:15 +10:00
TJ Holowaychuk
d6ecf785a2 Merge pull request #1710 from hacksparrow/master
Fixed test cases for res.format
2013-08-09 15:03:45 -07:00
Hage Yaapa
a38bdf6758 fixed test cases for res.format 2013-08-04 20:32:08 +05:30
TJ Holowaychuk
5aa9670120 Merge pull request #1685 from CharlesHolbrow/master
Fix typo in app.param comment
2013-08-02 14:46:40 -07:00
TJ Holowaychuk
8ad8cb93cc refactor 2013-08-02 14:46:25 -07:00
TJ Holowaychuk
610e172fcf Merge pull request #1694 from kavu/add_disable_etag
Add application setting to disable ETag (again)
2013-08-02 14:45:37 -07:00
TJ Holowaychuk
6942070a21 add [dir] to express(1) --help output. Closes #1699 2013-08-02 14:44:52 -07:00
TJ Holowaychuk
e283200511 remove comma-first from express(1)-generated app 2013-08-01 11:10:21 -07:00
Max Riveiro
54a192a5c5 Add application setting to disable ETag completely 2013-07-21 12:49:28 +04:00
TJ Holowaychuk
c3bd65eda2 Revert "remove old OPTIONS default response"
This reverts commit 2bba69f633.
2013-07-16 11:22:02 -07:00
Charles Holbrow
3de81e0147 Fix typo in app.param comment 2013-07-13 16:32:02 -07:00
TJ Holowaychuk
8fe1e2a5b4 Release 3.3.4 2013-07-08 14:42:45 -07:00
TJ Holowaychuk
909dbb81d5 update send and connect 2013-07-08 14:40:02 -07:00
TJ Holowaychuk
26802a689c fix package.json conflict 2013-07-04 13:39:36 -07:00
TJ Holowaychuk
37239fb67f Release 3.3.3 2013-07-04 07:37:17 -07:00
TJ Holowaychuk
018dc40b32 update connect 2013-07-04 07:36:57 -07:00
TJ Holowaychuk
52440955e6 Release 3.3.2 2013-07-03 11:25:54 -07:00
TJ Holowaychuk
c2f3d6ce2b update connect 2013-07-03 11:25:15 -07:00
TJ Holowaychuk
be858f5d07 update send 2013-07-03 11:24:31 -07:00
TJ Holowaychuk
1f14734f91 Merge pull request #1664 from paulmillr/topics/update-deps
Update commander and mkdirp dependencies.
2013-07-01 11:14:15 -07:00
Paul Miller
6d1d694dbb Update commander and mkdirp dependencies. 2013-06-28 19:15:32 +03:00
TJ Holowaychuk
ba5c48aa86 remove .version export 2013-06-27 08:38:53 -07:00
TJ Holowaychuk
320d7807a9 Release 3.3.1 2013-06-27 08:32:37 -07:00
TJ Holowaychuk
6650a312b7 update connect 2013-06-27 08:32:20 -07:00
TJ Holowaychuk
832c3b3744 Release 3.3.0 2013-06-26 10:07:34 -07:00
TJ Holowaychuk
76691bfd6b update connect 2013-06-26 10:05:40 -07:00
TJ Holowaychuk
29fe5ea785 Merge pull request #1657 from ralphtheninja/master
use send 0.1.1 to get rid of npm warning during install
2013-06-26 09:54:24 -07:00
Lars-Magnus Skog
52a820113f use send 0.1.1 to get rid of npm warning 2013-06-23 00:49:20 +02:00
TJ Holowaychuk
aec3428489 Merge pull request #1650 from printercu/master
move .app to req's & res's prototypes
2013-06-11 12:39:59 -07:00
TJ Holowaychuk
a10f695b6f pin jade dev dep so tests do not break 2013-06-11 12:24:17 -07:00
Max Melentiev
a3c9eacaf1 move .app to req's & res's prototypes 2013-06-11 19:42:30 +04:00
TJ Holowaychuk
19d685b152 return actual booleans from req.accept* functions 2013-06-06 13:47:18 -07:00
TJ Holowaychuk
8ab44081d4 add support for multiple X-Forwarded-Proto values. Closes #1646 2013-06-05 12:05:45 -07:00
TJ Holowaychuk
0431d22822 add req.secure tests 2013-06-05 11:59:47 -07:00
TJ Holowaychuk
138d74aefa remove charset from json responses. Closes #1631 2013-06-05 11:51:59 -07:00
TJ Holowaychuk
28562b2cf8 Merge pull request #1643 from jonjenkins/master
Fixed issue with callback querystring failure
2013-06-03 14:52:49 -07:00
TJ Holowaychuk
e0afda444f Release 3.2.6 2013-06-02 17:15:39 -07:00
TJ Holowaychuk
5a4cac58af update connect 2013-06-02 17:15:14 -07:00
TJ Holowaychuk
545dca6c4d Merge pull request #1642 from jade-bot/master
Update jade files [bot-update#1]
2013-06-02 16:04:50 -07:00
TJ Holowaychuk
e59a882389 Merge pull request #1634 from joshlangner/patch-1
added some additional explanation for clarity
2013-06-02 15:58:25 -07:00
TJ Holowaychuk
ccd9828535 Merge pull request #1630 from EvanHahn/patch-1
Remove dead link from readme's "More Information"
2013-06-02 15:50:45 -07:00
TJ Holowaychuk
41f0d32355 Merge pull request #1622 from saintedlama/master
Fixes indentation for css engines when using express to scaffold an application
2013-06-02 15:47:36 -07:00
Jenkins
2f19b4fefc Corrected callback crashing app when array 2013-05-26 21:35:52 -05:00
jade-bot
cd31cecfd1 Update to maintain compatability with the latest version of jade 2013-05-26 14:51:34 -07:00
TJ Holowaychuk
2fe46b3905 Release 3.2.5 2013-05-21 21:01:24 -07:00
TJ Holowaychuk
24974f1f8f update connect 2013-05-21 20:56:08 -07:00
joshlangner
fd73bd006e added some additional explanation for clarity 2013-05-19 22:47:04 -04:00
Evan Hahn
7388c2c223 Remove dead link from readme's "More Information" 2013-05-17 11:37:21 -06:00
TJ Holowaychuk
e2210b0b92 Merge pull request #1625 from ForbesLindesay/patch-1
Throw a meaningful error when there is no default engine
2013-05-15 08:27:47 -07:00
Forbes Lindesay
30919be2a0 Throw a meaningful error when there is no default engine 2013-05-15 12:39:06 +01:00
TJ Holowaychuk
10b21b41f7 Revert "fix infinite loop when res.send(status) is undefined. Closes #1623"
This reverts commit 28b8a3b5f7.
2013-05-13 13:23:23 -07:00
TJ Holowaychuk
28b8a3b5f7 fix infinite loop when res.send(status) is undefined. Closes #1623 2013-05-13 13:22:31 -07:00
saintelama
8b2f1bba95 fix indentation for css engine support 2013-05-12 23:43:52 +02:00
TJ Holowaychuk
c805d80a9b Merge pull request #1592 from bartsqueezy/eb1bbb9
Removing dependency which is no longer supported
2013-05-11 15:36:39 -07:00
TJ Holowaychuk
d876778d22 Merge pull request #1597 from Cauldrath/cookie_version
Version bump for node-cookie
2013-05-11 15:35:30 -07:00
TJ Holowaychuk
412e571600 Merge pull request #1618 from pwmckenna/patch-1
Flush messages exposed to locals *after* the view has the chance to proces...
2013-05-11 15:26:22 -07:00
TJ Holowaychuk
3296ed9cb3 change generation of ETags with res.send() to GET requests only. Closes #1619
if for some reason this is not ideal for your use-case please let me know and comment in the issue
2013-05-10 14:43:59 -07:00
Patrick Williams
91835e6816 Flush messages exposed to locals after the view has the chance to process them. 2013-05-10 09:05:37 -06:00
TJ Holowaychuk
f976625281 Release 3.2.4 2013-05-09 09:17:48 -07:00
TJ Holowaychuk
028d9d8a0c Merge pull request #1598 from colynb/patch-1
the file is hosts not vhosts
2013-05-09 09:12:54 -07:00
TJ Holowaychuk
8559c0e2a4 fix req.subdomains when no Host is present 2013-05-09 09:10:52 -07:00
TJ Holowaychuk
06ead58240 fix req.host when no Host is present, return undefined 2013-05-09 09:06:11 -07:00
TJ Holowaychuk
28ca1b5221 add req.host tests 2013-05-09 09:03:52 -07:00
TJ Holowaychuk
6d872e6693 remove qs dep 2013-05-07 07:58:54 -07:00
TJ Holowaychuk
0b09c8981f Release 3.2.3 2013-05-07 07:55:06 -07:00
TJ Holowaychuk
a1d5676ecb update connect / qs 2013-05-07 07:54:48 -07:00
colynb
69453ff889 the file is hosts not vhosts 2013-05-01 16:27:29 -07:00
Benjamin Hanes
28752cc3c0 Version bump for node-cookie 2013-05-01 15:25:14 -04:00
Steve Bartnesky
5fa685b602 removing github-flavored-markdown as a dependency as it is no longer supported. switch to use marked instead 2013-04-29 09:12:29 -05:00
Steve Bartnesky
eb1bbb92c0 removing github-flavored-markdown as a dependency as it is no longer supported. switch to use marked instead 2013-04-29 08:59:52 -05:00
28 changed files with 431 additions and 80 deletions

View File

@@ -1,4 +1,65 @@
3.3.6 / 2013-08-27
==================
* Revert "remove charset from json responses. Closes #1631" (causes issues in some clients)
* add: req.accepts take an argument list
3.3.4 / 2013-07-08
==================
* update send and connect
3.3.3 / 2013-07-04
==================
* update connect
3.3.2 / 2013-07-03
==================
* update connect
* update send
* remove .version export
3.3.1 / 2013-06-27
==================
* update connect
3.3.0 / 2013-06-26
==================
* update connect
* add support for multiple X-Forwarded-Proto values. Closes #1646
* change: remove charset from json responses. Closes #1631
* change: return actual booleans from req.accept* functions
* fix jsonp callback array throw
3.2.6 / 2013-06-02
==================
* update connect
3.2.5 / 2013-05-21
==================
* update connect
* update node-cookie
* add: throw a meaningful error when there is no default engine
* change generation of ETags with res.send() to GET requests only. Closes #1619
3.2.4 / 2013-05-09
==================
* fix `req.subdomains` when no Host is present
* fix `req.host` when no Host is present, return undefined
3.2.3 / 2013-05-07
==================
* update connect / qs
3.2.2 / 2013-05-03
==================

View File

@@ -1,6 +1,6 @@
(The MIT License)
Copyright (c) 2009-2011 TJ Holowaychuk <tj@vision-media.ca>
Copyright (c) 2009-2013 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

View File

@@ -1,6 +1,6 @@
![express logo](http://f.cl.ly/items/0V2S1n0K1i3y1c122g04/Screen%20Shot%202012-04-11%20at%209.59.42%20AM.png)
Fast, unopinionated, minimalist web framework for [node](http://nodejs.org). [![Build Status](https://secure.travis-ci.org/visionmedia/express.png)](http://travis-ci.org/visionmedia/express) [![Dependency Status](https://gemnasium.com/visionmedia/express.png)](https://gemnasium.com/visionmedia/express)
Fast, unopinionated, minimalist web framework for [node](http://nodejs.org). [![Build Status](https://secure.travis-ci.org/visionmedia/express.png)](http://travis-ci.org/visionmedia/express)
```js
var express = require('express');
@@ -64,7 +64,6 @@ app.listen(3000);
* [Google Group](http://groups.google.com/group/express-js) for discussion
* Follow [tjholowaychuk](http://twitter.com/tjholowaychuk) on twitter for updates
* Visit the [Wiki](http://github.com/visionmedia/express/wiki)
* [日本語ドキュメンテーション](http://hideyukisaito.com/doc/expressjs/) by [hideyukisaito](https://github.com/hideyukisaito)
* [Русскоязычная документация](http://jsman.ru/express/)
* Run express examples [online](https://runnable.com/express)

View File

@@ -16,6 +16,7 @@ var exec = require('child_process').exec
program
.version(version)
.usage('[options] [dir]')
.option('-s, --sessions', 'add session support')
.option('-e, --ejs', 'add ejs engine support (defaults to jade)')
.option('-J, --jshtml', 'add jshtml engine support (defaults to jade)')
@@ -208,11 +209,11 @@ var app = [
, ' * Module dependencies.'
, ' */'
, ''
, 'var express = require(\'express\')'
, ' , routes = require(\'./routes\')'
, ' , user = require(\'./routes/user\')'
, ' , http = require(\'http\')'
, ' , path = require(\'path\');'
, 'var express = require(\'express\');'
, 'var routes = require(\'./routes\');'
, 'var user = require(\'./routes/user\');'
, 'var http = require(\'http\');'
, 'var path = require(\'path\');'
, ''
, 'var app = express();'
, ''
@@ -323,10 +324,10 @@ function createApplicationAt(path) {
// CSS Engine support
switch (program.css) {
case 'less':
app = app.replace('{css}', eol + ' app.use(require(\'less-middleware\')({ src: __dirname + \'/public\' }));');
app = app.replace('{css}', eol + 'app.use(require(\'less-middleware\')({ src: __dirname + \'/public\' }));');
break;
case 'stylus':
app = app.replace('{css}', eol + ' app.use(require(\'stylus\').middleware(__dirname + \'/public\'));');
app = app.replace('{css}', eol + 'app.use(require(\'stylus\').middleware(__dirname + \'/public\'));');
break;
default:
app = app.replace('{css}', '');

View File

@@ -1,4 +1,4 @@
style
style.
body {
padding: 50px;
font: 16px "Helvetica Neue", Helvetica;

View File

@@ -1,7 +1,7 @@
html
head
title Express
script
script.
// call this whatever you like,
// or dump them into individual
// props like "var user ="
@@ -10,5 +10,5 @@ html
h1 Expose client data
p The following was exposed to the client:
pre
script
script.
document.write(JSON.stringify(data, null, 2))

View File

@@ -5,7 +5,7 @@
var express = require('../..')
, fs = require('fs')
, md = require('github-flavored-markdown').parse;
, md = require('marked').parse;
var app = module.exports = express();

View File

@@ -1,4 +1,3 @@
var express = require('../..');
var app = module.exports = express();
@@ -58,10 +57,10 @@ app.use(function(req, res, next){
});
*/
next();
// empty or "flush" the messages so they
// don't build up
req.session.messages = [];
next();
});
// load controllers
@@ -90,4 +89,4 @@ app.use(function(req, res, next){
if (!module.parent) {
app.listen(3000);
console.log('\n listening on port 3000\n');
}
}

View File

@@ -2,7 +2,7 @@
html
head
title Search example
style
style.
body {
font: 14px "Helvetica Neue", Helvetica;
padding: 50px;

View File

@@ -1,4 +1,3 @@
/**
* Module dependencies.
*/
@@ -6,14 +5,14 @@
var express = require('../..');
/*
edit /etc/vhosts:
edit /etc/hosts:
127.0.0.1 foo.example.com
127.0.0.1 bar.example.com
127.0.0.1 example.com
*/
// Main app
// Main server app
var main = express();
@@ -36,12 +35,12 @@ redirect.all('*', function(req, res){
res.redirect('http://example.com:3000/' + req.subdomains[0]);
});
// Main app
// Vhost app
var app = express();
app.use(express.vhost('*.example.com', redirect))
app.use(express.vhost('example.com', main));
app.use(express.vhost('*.example.com', redirect)) // Serves all subdomains via Redirect app
app.use(express.vhost('example.com', main)); // Serves top level domain via Main server app
app.listen(3000);
console.log('Express app started on port 3000');

View File

@@ -6,7 +6,7 @@
var express = require('../../')
, http = require('http')
, GithubView = require('./github-view')
, md = require('github-flavored-markdown').parse;
, md = require('marked').parse;
var app = module.exports = express();

View File

@@ -2,7 +2,7 @@ doctype 5
html
head
title= title
style
style.
body {
padding: 50px;
font: 16px Helvetica, Arial;

View File

@@ -46,6 +46,7 @@ app.init = function(){
app.defaultConfiguration = function(){
// default settings
this.enable('x-powered-by');
this.enable('etag');
this.set('env', process.env.NODE_ENV || 'development');
this.set('subdomain offset', 2);
debug('booting in %s mode', this.get('env'));
@@ -117,7 +118,6 @@ app.use = function(route, fn){
fn = function(req, res, next) {
var orig = req.app;
app.handle(req, res, function(err){
req.app = res.app = orig;
req.__proto__ = orig.request;
res.__proto__ = orig.response;
next(err);
@@ -185,7 +185,7 @@ app.engine = function(ext, fn){
* could automatically load a user's information from the database without
* any additional code,
*
* The callback uses the samesignature as middleware, the only differencing
* The callback uses the same signature as middleware, the only differencing
* being that the value of the placeholder is passed, in this case the _id_
* of the user. Once the `next()` function is invoked, just like middleware
* it will continue on to execute the route, or subsequent parameter functions.

View File

@@ -16,12 +16,6 @@ var connect = require('connect')
exports = module.exports = createApplication;
/**
* Framework version.
*/
exports.version = '3.2.2';
/**
* Expose mime.
*/
@@ -38,8 +32,8 @@ exports.mime = connect.mime;
function createApplication() {
var app = connect();
utils.merge(app, proto);
app.request = { __proto__: req };
app.response = { __proto__: res };
app.request = { __proto__: req, app: app };
app.response = { __proto__: res, app: app };
app.init();
return app;
}

View File

@@ -17,7 +17,6 @@ var utils = require('./utils');
exports.init = function(app){
return function expressInit(req, res, next){
req.app = res.app = app;
if (app.enabled('x-powered-by')) res.setHeader('X-Powered-By', 'Express');
req.res = res;
res.req = req;

View File

@@ -63,6 +63,7 @@ req.header = function(name){
* The `type` value may be a single mime type string
* such as "application/json", the extension name
* such as "json", a comma-delimted list such as "json, html, text/plain",
* an argument list such as `"json", "html", "text/plain"`,
* or an array `["json", "html", "text/plain"]`. When a list
* or array is given the _best_ match, if any is returned.
*
@@ -89,6 +90,7 @@ req.header = function(name){
*
* // Accept: text/*;q=.5, application/json
* req.accepts(['html', 'json']);
* req.accepts('html', 'json');
* req.accepts('html, json');
* // => "json"
*
@@ -98,7 +100,8 @@ req.header = function(name){
*/
req.accepts = function(type){
return utils.accepts(type, this.get('Accept'));
var args = arguments.length > 1 ? [].slice.apply(arguments) : type;
return utils.accepts(args, this.get('Accept'));
};
/**
@@ -110,7 +113,7 @@ req.accepts = function(type){
*/
req.acceptsEncoding = function(encoding){
return ~this.acceptedEncodings.indexOf(encoding);
return !! ~this.acceptedEncodings.indexOf(encoding);
};
/**
@@ -125,7 +128,7 @@ req.acceptsEncoding = function(encoding){
req.acceptsCharset = function(charset){
var accepted = this.acceptedCharsets;
return accepted.length
? ~accepted.indexOf(charset)
? !! ~accepted.indexOf(charset)
: true;
};
@@ -141,7 +144,7 @@ req.acceptsCharset = function(charset){
req.acceptsLanguage = function(lang){
var accepted = this.acceptedLanguages;
return accepted.length
? ~accepted.indexOf(lang)
? !! ~accepted.indexOf(lang)
: true;
};
@@ -345,11 +348,10 @@ req.is = function(type){
req.__defineGetter__('protocol', function(){
var trustProxy = this.app.get('trust proxy');
return this.connection.encrypted
? 'https'
: trustProxy
? (this.get('X-Forwarded-Proto') || 'http')
: 'http';
if (this.connection.encrypted) return 'https';
if (!trustProxy) return 'http';
var proto = this.get('X-Forwarded-Proto') || 'http';
return proto.split(/\s*,\s*/)[0];
});
/**
@@ -445,7 +447,7 @@ req.__defineGetter__('auth', function(){
req.__defineGetter__('subdomains', function(){
var offset = this.app.get('subdomain offset');
return this.get('Host')
return (this.host || '')
.split('.')
.reverse()
.slice(offset);
@@ -473,6 +475,7 @@ req.__defineGetter__('host', function(){
var trustProxy = this.app.get('trust proxy');
var host = trustProxy && this.get('X-Forwarded-Host');
host = host || this.get('Host');
if (!host) return;
return host.split(':')[0];
});

View File

@@ -78,9 +78,12 @@ res.links = function(links){
*/
res.send = function(body){
var req = this.req
, head = 'HEAD' == req.method
, len;
var req = this.req;
var head = 'HEAD' == req.method;
var len;
// settings
var app = this.app;
// allow status / body
if (2 == arguments.length) {
@@ -128,7 +131,7 @@ res.send = function(body){
// ETag support
// TODO: W/ support
if (len > 1024) {
if (app.settings.etag && len > 1024 && 'GET' == req.method) {
if (!this.get('ETag')) {
this.set('ETag', etag(body));
}
@@ -234,6 +237,7 @@ res.jsonp = function(obj){
// jsonp
if (callback) {
if (callback instanceof Array) callback = callback[0];
this.set('Content-Type', 'text/javascript');
var cb = callback.replace(/[^\[\]\w$.]/g, '');
body = cb + ' && ' + cb + '(' + body + ');';

View File

@@ -103,6 +103,9 @@ Router.prototype._dispatch = function(req, res, next){
// match route
req.route = route = self.matchRequest(req, i);
// implied OPTIONS
if (!route && 'OPTIONS' == req.method) return self._options(req, res);
// no route
if (!route) return next(err);
debug('matched %s %s', route.method, route.path);
@@ -170,6 +173,41 @@ Router.prototype._dispatch = function(req, res, next){
})(0);
};
/**
* Respond to __OPTIONS__ method.
*
* @param {IncomingMessage} req
* @param {ServerResponse} res
* @api private
*/
Router.prototype._options = function(req, res){
var path = parse(req).pathname
, body = this._optionsFor(path).join(',');
res.set('Allow', body).send(body);
};
/**
* Return an array of HTTP verbs or "options" for `path`.
*
* @param {String} path
* @return {Array}
* @api private
*/
Router.prototype._optionsFor = function(path){
var self = this;
return methods.filter(function(method){
var routes = self.map[method];
if (!routes || 'options' == method) return;
for (var i = 0, len = routes.length; i < len; ++i) {
if (routes[i].match(path)) return true;
}
}).map(function(method){
return method.toUpperCase();
});
};
/**
* Attempt to match a route for `req`
* with optional starting index of `i`

View File

@@ -38,6 +38,7 @@ function View(name, options) {
var engines = options.engines;
this.defaultEngine = options.defaultEngine;
var ext = this.ext = extname(name);
if (!ext && !this.defaultEngine) throw new Error('No default engine was specified and no extension was provided.');
if (!ext) name += (ext = this.ext = ('.' != this.defaultEngine[0] ? '.' : '') + this.defaultEngine);
this.engine = engines[ext] || (engines[ext] = require(ext.slice(1)).__express);
this.path = this.lookup(name);

View File

@@ -1,7 +1,7 @@
{
"name": "express",
"description": "Sinatra inspired web development framework",
"version": "3.2.2",
"version": "3.3.6",
"author": "TJ Holowaychuk <tj@vision-media.ca>",
"contributors": [
{
@@ -22,28 +22,27 @@
}
],
"dependencies": {
"connect": "2.7.8",
"commander": "0.6.1",
"connect": "2.8.5",
"commander": "1.2.0",
"range-parser": "0.0.4",
"mkdirp": "0.3.4",
"cookie": "0.0.5",
"mkdirp": "0.3.5",
"cookie": "0.1.0",
"buffer-crc32": "0.2.1",
"fresh": "0.1.0",
"fresh": "0.2.0",
"methods": "0.0.1",
"send": "0.1.0",
"send": "0.1.4",
"cookie-signature": "1.0.1",
"debug": "*",
"qs": "0.6.3"
"debug": "*"
},
"devDependencies": {
"ejs": "*",
"mocha": "*",
"jade": "*",
"jade": "0.30.0",
"hjs": "*",
"stylus": "*",
"should": "*",
"connect-redis": "*",
"github-flavored-markdown": "*",
"marked": "*",
"supertest": "0.6.0"
},
"keywords": [

37
test/app.options.js Normal file
View File

@@ -0,0 +1,37 @@
var express = require('../')
, request = require('./support/http');
describe('OPTIONS', function(){
it('should default to the routes defined', function(done){
var app = express();
app.del('/', function(){});
app.get('/users', function(req, res){});
app.put('/users', function(req, res){});
request(app)
.options('/users')
.expect('GET,PUT')
.expect('Allow', 'GET,PUT', done);
})
})
describe('app.options()', function(){
it('should override the default behavior', function(done){
var app = express();
app.options('/users', function(req, res){
res.set('Allow', 'GET');
res.send('GET');
});
app.get('/users', function(req, res){});
app.put('/users', function(req, res){});
request(app)
.options('/users')
.expect('GET')
.expect('Allow', 'GET', done);
})
})

View File

@@ -4,10 +4,6 @@ var express = require('../')
, assert = require('assert');
describe('exports', function(){
it('should have .version', function(){
express.should.have.property('version');
})
it('should expose connect middleware', function(){
express.should.have.property('bodyParser');
express.should.have.property('session');
@@ -21,15 +17,15 @@ describe('exports', function(){
it('should expose Router', function(){
express.Router.should.be.a('function');
})
it('should expose the application prototype', function(){
express.application.set.should.be.a('function');
})
it('should expose the request prototype', function(){
express.request.accepts.should.be.a('function');
})
it('should expose the response prototype', function(){
express.response.send.should.be.a('function');
})
@@ -51,7 +47,7 @@ describe('exports', function(){
.get('/')
.expect('bar', done);
})
it('should permit modifying the .response prototype', function(done){
express.response.foo = function(){ this.send('bar'); };
var app = express();

View File

@@ -56,6 +56,19 @@ describe('req', function(){
.expect('html', done);
})
it('should accept an argument list of type names', function(done){
var app = express();
app.use(function(req, res, next){
res.end(req.accepts('json', 'html'));
});
request(app)
.get('/')
.set('Accept', 'application/json')
.expect('json', done);
})
describe('.accept(types)', function(){
it('should return the first when Accept is not present', function(done){
var app = express();

34
test/req.host.js Normal file
View File

@@ -0,0 +1,34 @@
var express = require('../')
, request = require('./support/http')
, assert = require('assert');
describe('req', function(){
describe('.host', function(){
it('should return the Host when present', function(done){
var app = express();
app.use(function(req, res){
res.end(req.host);
});
request(app)
.post('/')
.set('Host', 'example.com')
.expect('example.com', done);
})
it('should return undefined otherwise', function(done){
var app = express();
app.use(function(req, res){
req.headers.host = null;
res.end(String(req.host));
});
request(app)
.post('/')
.expect('undefined', done);
})
})
})

83
test/req.secure.js Normal file
View File

@@ -0,0 +1,83 @@
var express = require('../')
, request = require('./support/http');
describe('req', function(){
describe('.secure', function(){
describe('when X-Forwarded-Proto is missing', function(){
it('should return false when http', function(done){
var app = express();
app.get('/', function(req, res){
res.send(req.secure ? 'yes' : 'no');
});
request(app)
.get('/')
.expect('no', done)
})
})
})
describe('.secure', function(){
describe('when X-Forwarded-Proto is present', function(){
it('should return false when http', function(done){
var app = express();
app.get('/', function(req, res){
res.send(req.secure ? 'yes' : 'no');
});
request(app)
.get('/')
.set('X-Forwarded-Proto', 'https')
.expect('no', done)
})
it('should return true when "trust proxy" is enabled', function(done){
var app = express();
app.enable('trust proxy');
app.get('/', function(req, res){
res.send(req.secure ? 'yes' : 'no');
});
request(app)
.get('/')
.set('X-Forwarded-Proto', 'https')
.expect('yes', done)
})
it('should return false when initial proxy is http', function(done){
var app = express();
app.enable('trust proxy');
app.get('/', function(req, res){
res.send(req.secure ? 'yes' : 'no');
});
request(app)
.get('/')
.set('X-Forwarded-Proto', 'http, https')
.expect('no', done)
})
it('should return true when initial proxy is https', function(done){
var app = express();
app.enable('trust proxy');
app.get('/', function(req, res){
res.send(req.secure ? 'yes' : 'no');
});
request(app)
.get('/')
.set('X-Forwarded-Proto', 'https, http')
.expect('yes', done)
})
})
})
})

View File

@@ -34,6 +34,21 @@ describe('req', function(){
})
})
describe('with no host', function(){
it('should return an empty array', function(done){
var app = express();
app.use(function(req, res){
req.headers.host = null;
res.send(req.subdomains);
});
request(app)
.get('/')
.expect('[]', done);
})
})
describe('when subdomain offset is set', function(){
describe('when subdomain offset is zero', function(){
it('should return an array with the whole domain', function(done){

View File

@@ -53,7 +53,7 @@ app3.use(function(req, res, next){
})
});
describe('req', function(){
describe('res', function(){
describe('.format(obj)', function(){
describe('with canonicalized mime types', function(){
test(app);
@@ -79,14 +79,14 @@ function test(app) {
request(app)
.get('/')
.set('Accept', 'text/html; q=.5, application/json, */*; q=.1')
.expect('{"message":"hey"}', done);
.expect({"message":"hey"}, done);
})
it('should allow wildcard type/subtypes', function(done){
request(app)
.get('/')
.set('Accept', 'text/html; q=.5, application/*, */*; q=.1')
.expect('{"message":"hey"}', done);
.expect({"message":"hey"}, done);
})
it('should default the Content-Type', function(done){

View File

@@ -1,6 +1,7 @@
var express = require('../')
, request = require('./support/http');
, request = require('./support/http')
, assert = require('assert');
describe('res', function(){
describe('.send(null)', function(){
@@ -16,7 +17,7 @@ describe('res', function(){
.expect('', done);
})
})
describe('.send(undefined)', function(){
it('should set body to ""', function(done){
var app = express();
@@ -45,7 +46,7 @@ describe('res', function(){
.expect(201, done);
})
})
describe('.send(code, body)', function(){
it('should set .statusCode and body', function(done){
var app = express();
@@ -107,7 +108,24 @@ describe('res', function(){
.expect('ETag', '"-1498647312"')
.end(done);
})
it('should not set ETag for non-GET/HEAD', function(done){
var app = express();
app.use(function(req, res){
var str = Array(1024 * 2).join('-');
res.send(str);
});
request(app)
.post('/')
.end(function(err, res){
if (err) return done(err);
assert(!res.header.etag, 'has an ETag');
done();
});
})
it('should not override Content-Type', function(done){
var app = express();
@@ -122,7 +140,7 @@ describe('res', function(){
.expect(200, done);
})
})
describe('.send(Buffer)', function(){
it('should send as octet-stream', function(done){
var app = express();
@@ -172,7 +190,7 @@ describe('res', function(){
})
})
})
describe('.send(Object)', function(){
it('should send as application/json', function(done){
var app = express();
@@ -224,7 +242,7 @@ describe('res', function(){
})
})
})
describe('when .statusCode is 304', function(){
it('should strip Content-* fields, Transfer-Encoding field, and body', function(done){
var app = express();
@@ -300,4 +318,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();
});
});
});
})
})