Compare commits

...

101 Commits

Author SHA1 Message Date
Douglas Christopher Wilson
4405b849a9 3.18.6 2014-12-12 21:39:47 -05:00
Troy Goode
5d74a553d6 Fix exception in req.fresh/req.stale without response headers
fixes #2468
2014-12-12 21:17:23 -05:00
Douglas Christopher Wilson
262b60537f 3.18.5 2014-12-11 23:10:34 -05:00
Douglas Christopher Wilson
e77e644224 deps: should@~4.3.1 2014-12-11 23:03:01 -05:00
Douglas Christopher Wilson
ce89c00cd9 deps: istanbul@0.3.5 2014-12-11 23:01:12 -05:00
Douglas Christopher Wilson
d5ad34b0e9 deps: connect@2.27.6 2014-12-10 22:55:36 -05:00
Douglas Christopher Wilson
ebfa00a9c0 build: remove support folder 2014-11-29 12:10:30 -05:00
Douglas Christopher Wilson
d23417e6e8 examples: switch examples used in tests to ejs engine 2014-11-29 12:09:00 -05:00
Douglas Christopher Wilson
91824514ce tests: run render tests with internal template engine 2014-11-28 09:10:44 -05:00
Douglas Christopher Wilson
6c8bcd5c4e 3.18.4 2014-11-23 15:42:03 -05:00
Douglas Christopher Wilson
95e63ec287 deps: should@~4.3.0 2014-11-23 15:36:59 -05:00
Douglas Christopher Wilson
ebca5887cc deps: proxy-addr@~1.0.4 2014-11-23 15:34:57 -05:00
Douglas Christopher Wilson
8535d3a990 deps: supertest@~0.15.0 2014-11-23 14:58:56 -05:00
Douglas Christopher Wilson
13184c4379 deps: etag@~1.5.1 2014-11-23 14:58:22 -05:00
Douglas Christopher Wilson
eaba4eeb70 deps: connect@2.27.4 2014-11-23 14:53:23 -05:00
Douglas Christopher Wilson
28c6952d1c 3.18.3 2014-11-09 18:35:34 -05:00
Douglas Christopher Wilson
01e3530a31 deps: should@~4.2.1 2014-11-09 18:33:17 -05:00
Douglas Christopher Wilson
77c83d0c57 deps: connect@2.27.3 2014-11-09 18:32:43 -05:00
Douglas Christopher Wilson
a12ae729bd 3.18.2 2014-10-29 01:10:45 -04:00
Douglas Christopher Wilson
d53a0cd91e deps: connect@2.27.2 2014-10-29 01:08:36 -04:00
Douglas Christopher Wilson
88dfd36eaa 3.18.1 2014-10-23 01:26:21 -04:00
Douglas Christopher Wilson
5759b3e9f5 deps: send@0.10.1 2014-10-23 01:25:07 -04:00
Douglas Christopher Wilson
c939a771c0 deps: connect@2.27.1 2014-10-23 01:23:54 -04:00
Douglas Christopher Wilson
af1043844f Fix internal utils.merge deprecation warnings 2014-10-22 15:18:10 -04:00
Douglas Christopher Wilson
dd763ec5b8 deps: should@~4.1.0 2014-10-22 15:10:22 -04:00
Douglas Christopher Wilson
9c2c21aaaf deps: mocha@~2.0.0 2014-10-22 15:08:49 -04:00
Douglas Christopher Wilson
366000184f 3.18.0 2014-10-18 00:57:48 -04:00
Douglas Christopher Wilson
4d1ee23f84 Use etag module to generate ETag headers 2014-10-18 00:53:17 -04:00
Douglas Christopher Wilson
0e5613363f Use content-disposition module 2014-10-17 21:08:05 -04:00
Fishrock123
7a7f18c20b build: misc. updates to packaging
closes #2398
2014-10-17 20:49:56 -04:00
Douglas Christopher Wilson
b766aad112 deps: jade@~1.7.0 2014-10-17 20:45:57 -04:00
Douglas Christopher Wilson
7488e27609 deps: send@0.10.0 2014-10-17 20:45:09 -04:00
Douglas Christopher Wilson
bc9d854763 deps: depd@~1.0.0 2014-10-17 20:44:07 -04:00
Douglas Christopher Wilson
2e20a85810 deps: debug@~2.1.0 2014-10-17 20:43:23 -04:00
Douglas Christopher Wilson
a706408208 deps: connect@2.27.0 2014-10-17 20:42:12 -04:00
Douglas Christopher Wilson
6d39d0f8a8 3.17.8 2014-10-16 00:29:56 -04:00
Douglas Christopher Wilson
159ea67713 deps: connect@2.26.6 2014-10-16 00:24:28 -04:00
Douglas Christopher Wilson
33959ed350 deps: mocha@~1.21.5 2014-10-16 00:19:47 -04:00
Bessie Chan
be478d348c Fix typo in res.redirect deprecation
closes #2395
2014-10-11 18:11:22 -04:00
Douglas Christopher Wilson
9f292d873e 3.17.7 2014-10-08 17:00:45 -04:00
Douglas Christopher Wilson
ef3e95ca73 deps: supertest@~0.14.0 2014-10-08 16:44:29 -04:00
Douglas Christopher Wilson
f45bd632df deps: connect@2.26.5 2014-10-08 16:43:02 -04:00
Douglas Christopher Wilson
cc18da5cdf 3.17.6 2014-10-02 23:29:40 -04:00
Douglas Christopher Wilson
5603f86edd deps: connect@2.26.4 2014-10-02 23:27:41 -04:00
Douglas Christopher Wilson
43e2cd79cb 3.17.5 2014-09-24 19:38:35 -04:00
Douglas Christopher Wilson
653270bb43 deps: send@0.9.3 2014-09-24 19:15:46 -04:00
Douglas Christopher Wilson
734bdf5ca1 deps: proxy-addr@~1.0.3 2014-09-24 19:14:33 -04:00
Douglas Christopher Wilson
341c1919d9 deps: connect@2.26.3 2014-09-24 19:12:43 -04:00
Douglas Christopher Wilson
b09afad7b1 3.17.4 2014-09-19 22:57:07 -07:00
Douglas Christopher Wilson
0e0b259556 deps: connect@2.26.2 2014-09-19 22:54:39 -07:00
Douglas Christopher Wilson
63286e1192 3.17.3 2014-09-18 10:38:31 -07:00
Douglas Christopher Wilson
c00f2f8596 deps: proxy-addr@~1.0.2 2014-09-18 10:36:21 -07:00
Douglas Christopher Wilson
f29399c4e1 3.17.2 2014-09-16 00:14:41 -07:00
Douglas Christopher Wilson
f6ac068ab0 Use crc instead of buffer-crc32 for speed 2014-09-16 00:11:08 -07:00
Douglas Christopher Wilson
7eb65eeca2 deps: send@0.9.2 2014-09-15 23:59:02 -07:00
Douglas Christopher Wilson
178fe15091 deps: depd@0.4.5 2014-09-15 23:57:41 -07:00
Douglas Christopher Wilson
381f278d0a deps: connect@2.26.1 2014-09-15 23:56:36 -07:00
Douglas Christopher Wilson
534fa181c6 Add test-tap npm script for TAP output
closes #2359
2014-09-15 21:41:35 -07:00
Julien Gilli
80847d8c82 tests: fix broken tests with node v0.12 branch
Currently, test/req.ip.js assumes that the connection between the client
and the server is an IPv4 connection. However, depending on the
configuration of the host where this test runs, the connection can be an
IPv4 one or an IPv6 one using an IPv4 mapped address. In the future, it
could also be a "full" IPv6 connection.

This change makes this test handle any type of address.

fixes #2342
2014-09-15 21:41:34 -07:00
Douglas Christopher Wilson
4b1b8e420f 3.17.1 2014-09-08 23:45:38 -04:00
Douglas Christopher Wilson
70767b19ac Fix error in req.subdomains on empty host 2014-09-08 23:45:34 -04:00
Douglas Christopher Wilson
7d277c1c15 docs: remove erroneous from history 2014-09-08 23:44:24 -04:00
Douglas Christopher Wilson
fa1fcd9fec 3.17.0 2014-09-08 23:07:02 -04:00
Douglas Christopher Wilson
2de6514b4b Support IP address host in req.subdomains
fixes #2308
2014-09-08 23:04:06 -04:00
Douglas Christopher Wilson
d07c06363f Support X-Forwarded-Host in req.subdomains 2014-09-08 23:02:42 -04:00
Douglas Christopher Wilson
4e97533fd2 deps: jade@~1.6.0 2014-09-08 22:48:47 -04:00
Douglas Christopher Wilson
d7d6219a1e deps: range-parser@~1.0.2 2014-09-08 22:47:54 -04:00
Douglas Christopher Wilson
9b18461bbc deps: vary@~1.0.0 2014-09-08 21:18:28 -04:00
Douglas Christopher Wilson
b77aa38c98 deps: cookie-signature@1.0.5 2014-09-08 21:17:03 -04:00
Douglas Christopher Wilson
cbb251377e deps: fresh@0.2.4 2014-09-08 21:14:27 -04:00
Douglas Christopher Wilson
d6ed469de3 deps: send@0.9.1 2014-09-08 21:13:20 -04:00
Douglas Christopher Wilson
49284c236b deps: debug@~2.0.0 2014-09-08 21:11:41 -04:00
Douglas Christopher Wilson
be18487f7d deps: media-typer@0.3.0 2014-09-08 21:10:57 -04:00
Douglas Christopher Wilson
094ff11949 deps: connect@2.26.0 2014-09-08 21:09:22 -04:00
Douglas Christopher Wilson
b97f6eb506 examples: fix github view example
closes #2344
2014-09-08 19:31:58 -04:00
Douglas Christopher Wilson
3d188fe13e 3.16.10 2014-09-05 02:17:55 -04:00
Douglas Christopher Wilson
8327708ec2 deps: istanbul@0.3.2 2014-09-05 01:57:02 -04:00
Douglas Christopher Wilson
c8640b3465 deps: send@0.8.5 2014-09-05 01:56:27 -04:00
Douglas Christopher Wilson
3ce5f9b493 deps: connect@2.25.10 2014-09-05 01:55:24 -04:00
Douglas Christopher Wilson
4d032cda05 3.16.9 2014-08-30 01:22:06 -04:00
Douglas Christopher Wilson
4127ba10b0 deps: connect@2.25.9 2014-08-30 01:19:53 -04:00
Douglas Christopher Wilson
0299bee8fa 3.16.8 2014-08-27 21:09:18 -04:00
Douglas Christopher Wilson
6a581c9961 deps: connect@2.25.8 2014-08-27 21:04:41 -04:00
Douglas Christopher Wilson
0b12cc0cac 3.16.7 2014-08-18 22:45:17 -04:00
Douglas Christopher Wilson
fdd0ccabe8 docs: flatten badges for github look 2014-08-18 22:45:13 -04:00
Douglas Christopher Wilson
8c36eab679 docs: use shields.io badges 2014-08-18 22:19:21 -04:00
Douglas Christopher Wilson
5c145b5490 build: add link to homepage 2014-08-18 22:17:25 -04:00
Raymond Feng
d7bef52591 build: move repository
closes #2268
closes #2270
2014-08-18 22:07:35 -04:00
Douglas Christopher Wilson
1576a95e87 deps: send@0.8.3 2014-08-18 21:57:29 -04:00
Douglas Christopher Wilson
7f92fe66e0 deps: connect@2.25.7 2014-08-18 21:41:14 -04:00
Douglas Christopher Wilson
f13f4652da 3.16.6 2014-08-14 23:53:32 -04:00
Douglas Christopher Wilson
059c068c7b deps: send@0.8.2
fixes #2300
2014-08-14 23:52:07 -04:00
Douglas Christopher Wilson
49947f1476 deps: connect@2.25.6 2014-08-14 23:49:39 -04:00
Douglas Christopher Wilson
0dddd772c0 3.16.5 2014-08-11 22:30:09 -04:00
Douglas Christopher Wilson
0f87c6f392 deps: connect@2.25.5 2014-08-11 22:29:35 -04:00
Douglas Christopher Wilson
7119f2b16d 3.16.4 2014-08-10 22:22:58 -04:00
Douglas Christopher Wilson
a57efea173 Fix original URL parsing in res.location 2014-08-10 22:20:54 -04:00
Douglas Christopher Wilson
4a4ca7347a deps: parseurl@~1.3.0 2014-08-10 22:19:10 -04:00
Douglas Christopher Wilson
570f60d36e deps: connect@2.25.4 2014-08-10 22:18:12 -04:00
Douglas Christopher Wilson
d13e613584 3.16.3 2014-08-07 22:32:16 -04:00
Douglas Christopher Wilson
9204e1f42a deps: connect@2.25.3 2014-08-07 22:31:53 -04:00
50 changed files with 714 additions and 345 deletions

38
.gitignore vendored
View File

@@ -1,16 +1,26 @@
coverage/
.DS_Store
*.seed
# OS X
.DS_Store*
Icon?
._*
# Windows
Thumbs.db
ehthumbs.db
Desktop.ini
# Linux
.directory
*~
# npm
node_modules
*.log
*.csv
*.dat
*.out
*.pid
*.swp
*.swo
*.gz
# Coveralls
coverage
# Benchmarking
benchmarks/graphs
testing
node_modules/
testing
test.js
.idea

View File

@@ -1,10 +0,0 @@
.git*
benchmarks/
coverage/
docs/
examples/
support/
test/
testing.js
.DS_Store
.travis.yml

View File

@@ -1,3 +1,280 @@
3.18.6 / 2014-12-12
===================
* Fix exception in `req.fresh`/`req.stale` without response headers
3.18.5 / 2014-12-11
===================
* deps: connect@2.27.6
- deps: compression@~1.2.2
- deps: express-session@~1.9.3
- deps: http-errors@~1.2.8
- deps: serve-index@~1.5.3
- deps: type-is@~1.5.4
3.18.4 / 2014-11-23
===================
* deps: connect@2.27.4
- deps: body-parser@~1.9.3
- deps: compression@~1.2.1
- deps: errorhandler@~1.2.3
- deps: express-session@~1.9.2
- deps: qs@2.3.3
- deps: serve-favicon@~2.1.7
- deps: serve-static@~1.5.1
- deps: type-is@~1.5.3
* deps: etag@~1.5.1
* deps: proxy-addr@~1.0.4
- deps: ipaddr.js@0.1.5
3.18.3 / 2014-11-09
===================
* deps: connect@2.27.3
- Correctly invoke async callback asynchronously
- deps: csurf@~1.6.3
3.18.2 / 2014-10-28
===================
* deps: connect@2.27.2
- Fix handling of URLs containing `://` in the path
- deps: body-parser@~1.9.2
- deps: qs@2.3.2
3.18.1 / 2014-10-22
===================
* Fix internal `utils.merge` deprecation warnings
* deps: connect@2.27.1
- deps: body-parser@~1.9.1
- deps: express-session@~1.9.1
- deps: finalhandler@0.3.2
- deps: morgan@~1.4.1
- deps: qs@2.3.0
- deps: serve-static@~1.7.1
* deps: send@0.10.1
- deps: on-finished@~2.1.1
3.18.0 / 2014-10-17
===================
* Use `content-disposition` module for `res.attachment`/`res.download`
- Sends standards-compliant `Content-Disposition` header
- Full Unicode support
* Use `etag` module to generate `ETag` headers
* deps: connect@2.27.0
- Use `http-errors` module for creating errors
- Use `utils-merge` module for merging objects
- deps: body-parser@~1.9.0
- deps: compression@~1.2.0
- deps: connect-timeout@~1.4.0
- deps: debug@~2.1.0
- deps: depd@~1.0.0
- deps: express-session@~1.9.0
- deps: finalhandler@0.3.1
- deps: method-override@~2.3.0
- deps: morgan@~1.4.0
- deps: response-time@~2.2.0
- deps: serve-favicon@~2.1.6
- deps: serve-index@~1.5.0
- deps: serve-static@~1.7.0
* deps: debug@~2.1.0
- Implement `DEBUG_FD` env variable support
* deps: depd@~1.0.0
* deps: send@0.10.0
- deps: debug@~2.1.0
- deps: depd@~1.0.0
- deps: etag@~1.5.0
3.17.8 / 2014-10-15
===================
* deps: connect@2.26.6
- deps: compression@~1.1.2
- deps: csurf@~1.6.2
- deps: errorhandler@~1.2.2
3.17.7 / 2014-10-08
===================
* deps: connect@2.26.5
- Fix accepting non-object arguments to `logger`
- deps: serve-static@~1.6.4
3.17.6 / 2014-10-02
===================
* deps: connect@2.26.4
- deps: morgan@~1.3.2
- deps: type-is@~1.5.2
3.17.5 / 2014-09-24
===================
* deps: connect@2.26.3
- deps: body-parser@~1.8.4
- deps: serve-favicon@~2.1.5
- deps: serve-static@~1.6.3
* deps: proxy-addr@~1.0.3
- Use `forwarded` npm module
* deps: send@0.9.3
- deps: etag@~1.4.0
3.17.4 / 2014-09-19
===================
* deps: connect@2.26.2
- deps: body-parser@~1.8.3
- deps: qs@2.2.4
3.17.3 / 2014-09-18
===================
* deps: proxy-addr@~1.0.2
- Fix a global leak when multiple subnets are trusted
- deps: ipaddr.js@0.1.3
3.17.2 / 2014-09-15
===================
* Use `crc` instead of `buffer-crc32` for speed
* deps: connect@2.26.1
- deps: body-parser@~1.8.2
- deps: depd@0.4.5
- deps: express-session@~1.8.2
- deps: morgan@~1.3.1
- deps: serve-favicon@~2.1.3
- deps: serve-static@~1.6.2
* deps: depd@0.4.5
* deps: send@0.9.2
- deps: depd@0.4.5
- deps: etag@~1.3.1
- deps: range-parser@~1.0.2
3.17.1 / 2014-09-08
===================
* Fix error in `req.subdomains` on empty host
3.17.0 / 2014-09-08
===================
* Support IP address host in `req.subdomains`
* deps: connect@2.26.0
- deps: body-parser@~1.8.1
- deps: compression@~1.1.0
- deps: connect-timeout@~1.3.0
- deps: cookie-parser@~1.3.3
- deps: cookie-signature@1.0.5
- deps: csurf@~1.6.1
- deps: debug@~2.0.0
- deps: errorhandler@~1.2.0
- deps: express-session@~1.8.1
- deps: finalhandler@0.2.0
- deps: fresh@0.2.4
- deps: media-typer@0.3.0
- deps: method-override@~2.2.0
- deps: morgan@~1.3.0
- deps: qs@2.2.3
- deps: serve-favicon@~2.1.3
- deps: serve-index@~1.2.1
- deps: serve-static@~1.6.1
- deps: type-is@~1.5.1
- deps: vhost@~3.0.0
* deps: cookie-signature@1.0.5
* deps: debug@~2.0.0
* deps: fresh@0.2.4
* deps: media-typer@0.3.0
- Throw error when parameter format invalid on parse
* deps: range-parser@~1.0.2
* deps: send@0.9.1
- Add `lastModified` option
- Use `etag` to generate `ETag` header
- deps: debug@~2.0.0
- deps: fresh@0.2.4
* deps: vary@~1.0.0
- Accept valid `Vary` header string as `field`
3.16.10 / 2014-09-04
====================
* deps: connect@2.25.10
- deps: serve-static@~1.5.4
* deps: send@0.8.5
- Fix a path traversal issue when using `root`
- Fix malicious path detection for empty string path
3.16.9 / 2014-08-29
===================
* deps: connect@2.25.9
- deps: body-parser@~1.6.7
- deps: qs@2.2.2
3.16.8 / 2014-08-27
===================
* deps: connect@2.25.8
- deps: body-parser@~1.6.6
- deps: csurf@~1.4.1
- deps: qs@2.2.0
3.16.7 / 2014-08-18
===================
* deps: connect@2.25.7
- deps: body-parser@~1.6.5
- deps: express-session@~1.7.6
- deps: morgan@~1.2.3
- deps: serve-static@~1.5.3
* deps: send@0.8.3
- deps: destroy@1.0.3
- deps: on-finished@2.1.0
3.16.6 / 2014-08-14
===================
* deps: connect@2.25.6
- deps: body-parser@~1.6.4
- deps: qs@1.2.2
- deps: serve-static@~1.5.2
* deps: send@0.8.2
- Work around `fd` leak in Node.js 0.10 for `fs.ReadStream`
3.16.5 / 2014-08-11
===================
* deps: connect@2.25.5
- Fix backwards compatibility in `logger`
3.16.4 / 2014-08-10
===================
* Fix original URL parsing in `res.location`
* deps: connect@2.25.4
- Fix `query` middleware breaking with argument
- deps: body-parser@~1.6.3
- deps: compression@~1.0.11
- deps: connect-timeout@~1.2.2
- deps: express-session@~1.7.5
- deps: method-override@~2.1.3
- deps: on-headers@~1.0.0
- deps: parseurl@~1.3.0
- deps: qs@1.2.1
- deps: response-time@~2.0.1
- deps: serve-index@~1.1.6
- deps: serve-static@~1.5.1
* deps: parseurl@~1.3.0
3.16.3 / 2014-08-07
===================
* deps: connect@2.25.3
- deps: multiparty@3.3.2
3.16.2 / 2014-08-07
===================

View File

@@ -2,10 +2,10 @@
Fast, unopinionated, minimalist web framework for [node](http://nodejs.org).
[![NPM version](https://badge.fury.io/js/express.svg)](http://badge.fury.io/js/express)
[![Build Status](https://travis-ci.org/visionmedia/express.svg?branch=master)](https://travis-ci.org/visionmedia/express)
[![Coverage Status](https://img.shields.io/coveralls/visionmedia/express.svg)](https://coveralls.io/r/visionmedia/express)
[![Gittip](http://img.shields.io/gittip/dougwilson.svg)](https://www.gittip.com/dougwilson/)
[![NPM version](https://img.shields.io/npm/v/express.svg?style=flat)](https://www.npmjs.org/package/express)
[![Build Status](https://img.shields.io/travis/strongloop/express.svg?style=flat)](https://travis-ci.org/strongloop/express)
[![Coverage Status](https://img.shields.io/coveralls/strongloop/express.svg?style=flat)](https://coveralls.io/r/strongloop/express)
[![Gittip](https://img.shields.io/gittip/dougwilson.svg?style=flat)](https://www.gittip.com/dougwilson/)
```js
var express = require('express');
@@ -65,11 +65,11 @@ app.listen(3000);
## More Information
* [Website and Documentation](http://expressjs.com/) stored at [visionmedia/expressjs.com](https://github.com/visionmedia/expressjs.com)
* [Website and Documentation](http://expressjs.com/) stored at [strongloop/expressjs.com](https://github.com/strongloop/expressjs.com)
* Join #express on freenode
* [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)
* Visit the [Wiki](http://github.com/strongloop/express/wiki)
* [Русскоязычная документация](http://jsman.ru/express/)
* Run express examples [online](https://runnable.com/express)
@@ -77,7 +77,7 @@ app.listen(3000);
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
$ git clone git://github.com/strongloop/express.git --depth 1
$ cd express
$ npm install
@@ -103,7 +103,7 @@ $ npm test
## Contributors
https://github.com/visionmedia/express/graphs/contributors
https://github.com/strongloop/express/graphs/contributors
## License

View File

@@ -8,7 +8,7 @@ var express = require('../../')
// general config
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.set('view engine', 'ejs');
// our custom "verbose errors" setting
// which we can use in the templates
@@ -82,7 +82,7 @@ app.use(function(err, req, res, next){
// Routes
app.get('/', function(req, res){
res.render('index.jade');
res.render('index.ejs');
});
app.get('/404', function(req, res, next){

View File

@@ -0,0 +1,3 @@
<% include error_header %>
<h2>Cannot find <%= url %></h2>
<% include footer %>

View File

@@ -1,5 +0,0 @@
extends error
block content
h2 Cannot find #{url}

View File

@@ -0,0 +1,8 @@
<% include error_header %>
<h2>Error: <%= error.message %></h2>
<% if (settings['verbose errors']) { %>
<pre><%= error.stack %></pre>
<% } else { %>
<p>An error occurred!</p>
<% } %>
<% include footer %>

View File

@@ -1,13 +0,0 @@
// note that we extend a different
// layout with jade for 4xx & 5xx
// responses
extends error
block content
h1 Error: #{error.message}
if settings['verbose errors']
pre= error.stack
else
p An error ocurred!

View File

@@ -1,6 +0,0 @@
html
head
title Error
body
h1 An error occurred!
block content

View File

@@ -0,0 +1,8 @@
<!DOCTYPE html>
<html>
<head>
<title>Error</title>
</head>
<body>
<h1>An error occurred!</h1>

View File

@@ -0,0 +1,2 @@
</body>
</html>

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<title>Custom Pages Example</title>
</head>
<body>
<h1>My Site</h1>
<h2>Pages Example</h2>
<ul>
<li>visit <a href="/500">500</a></li>
<li>visit <a href="/404">404</a></li>
<li>visit <a href="/403">403</a></li>
</ul>
</body>
</html>

View File

@@ -1,15 +0,0 @@
extends layout
block content
h2 Pages Example
ul
li
| visit
a(href="/500") 500
li
| visit
a(href="/404") 404
li
| visit
a(href='/403') 403

View File

@@ -1,6 +0,0 @@
html
head
title Custom Pages Example
body
h1 My Site
block content

View File

@@ -1,7 +1,7 @@
var db = require('../../db');
exports.engine = 'jade';
exports.engine = 'ejs';
exports.before = function(req, res, next){
var pet = db.pets[req.params.pet_id];

View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="/style.css">
<title>Edit <%= pet.name %></title>
</head>
<body>
<h1><%= pet.name %></h1>
<form action="/pet/<%= pet.id %>" method="post">
<input type="hidden" name="_method" value="put">
<label>Name: <input type="text" name="user[name]" value="<%= pet.name %>"></label>
<input type="submit" value="Update">
</form>
</body>
</html>

View File

@@ -1,7 +0,0 @@
link(rel='stylesheet', href='/style.css')
h1= pet.name
form(action='/pet/#{pet.id}', method='post')
input(type='hidden', name='_method', value='put')
label Name:
input(type='text', name='user[name]', value=pet.name)
input(type='submit', value='Update')

View File

@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="/style.css">
<title><%= pet.name %></title>
</head>
<body>
<h1><%= pet.name %> <a href="/pet/<%= pet.id %>/edit">edit</a></h1>
<p>You are viewing <%= pet.name %></p>
</body>
</html>

View File

@@ -1,6 +0,0 @@
link(rel='stylesheet', href='/style.css')
h1= pet.name
a(href='/pet/#{pet.id}/edit') edit
p You are viewing #{pet.name}

View File

@@ -35,13 +35,13 @@ function GithubView(name, options){
GithubView.prototype.render = function(options, fn){
var self = this;
var opts = {
host: 'rawgithub.com',
port: 80,
host: 'raw.githubusercontent.com',
port: 443,
path: this.path,
method: 'GET'
};
http.request(opts, function(res) {
https.request(opts, function(res) {
var buf = '';
res.setEncoding('utf8');
res.on('data', function(str){ buf += str });

View File

@@ -24,7 +24,7 @@ app.engine('md', function(str, options, fn){
})
// pointing to a particular github repo to load files from it
app.set('views', 'visionmedia/express');
app.set('views', 'strongloop/express');
// register a new view constructor
app.set('view', GithubView);
@@ -37,7 +37,7 @@ app.get('/', function(req, res){
})
app.get('/Readme.md', function(req, res){
// rendering a view from https://github.com/visionmedia/express/blob/master/Readme.md
// rendering a view from https://github.com/strongloop/express/blob/master/Readme.md
res.render('Readme.md');
})

View File

@@ -73,7 +73,7 @@ var apiKeys = ['foo', 'bar', 'baz'];
// these two objects will serve as our faux database
var repos = [
{ name: 'express', url: 'http://github.com/visionmedia/express' }
{ name: 'express', url: 'http://github.com/strongloop/express' }
, { name: 'stylus', url: 'http://github.com/learnboost/stylus' }
, { name: 'cluster', url: 'http://github.com/learnboost/cluster' }
];

View File

@@ -11,9 +11,9 @@ var connect = require('connect')
, compileETag = require('./utils').compileETag
, compileTrust = require('./utils').compileTrust
, View = require('./view')
, utils = connect.utils
, http = require('http');
var deprecate = require('depd')('express');
var merge = require('utils-merge');
/**
* Application prototype.
@@ -484,13 +484,15 @@ app.render = function(name, options, fn){
}
// merge app.locals
utils.merge(opts, this.locals);
merge(opts, this.locals);
// merge options._locals
if (options._locals) utils.merge(opts, options._locals);
if (options._locals) {
merge(opts, options._locals);
}
// merge options
utils.merge(opts, options);
merge(opts, options);
// set .cache unless explicitly provided
opts.cache = null == opts.cache

View File

@@ -3,14 +3,14 @@
*/
var deprecate = require('depd')('express');
var merge = require('merge-descriptors');
var mixin = require('merge-descriptors');
var merge = require('utils-merge');
var connect = require('connect')
, proto = require('./application')
, Route = require('./router/route')
, Router = require('./router')
, req = require('./request')
, res = require('./response')
, utils = connect.utils;
, res = require('./response');
/**
* Expose `createApplication()`.
@@ -33,7 +33,7 @@ exports.mime = connect.mime;
function createApplication() {
var app = connect();
utils.merge(app, proto);
merge(app, proto);
app.request = { __proto__: req, app: app };
app.response = { __proto__: res, app: app };
app.init();
@@ -45,7 +45,7 @@ function createApplication() {
* for example `express.logger` etc.
*/
merge(exports, connect.middleware);
mixin(exports, connect.middleware);
/**
* Deprecated createServer().

View File

@@ -13,6 +13,7 @@ var http = require('http')
, parse = require('parseurl')
, proxyaddr = require('proxy-addr')
, mime = connect.mime;
var isIP = require('net').isIP;
/**
* Request prototype.
@@ -452,11 +453,16 @@ req.__defineGetter__('auth', function(){
*/
req.__defineGetter__('subdomains', function(){
var host = this.host;
if (!host) return [];
var offset = this.app.get('subdomain offset');
return (this.host || '')
.split('.')
.reverse()
.slice(offset);
var subdomains = !isIP(host)
? host.split('.').reverse()
: [host];
return subdomains.slice(offset);
});
/**
@@ -520,7 +526,7 @@ req.__defineGetter__('fresh', function(){
// 2xx or 304 as per rfc2616 14.26
if ((s >= 200 && s < 300) || 304 == s) {
return fresh(this.headers, this.res._headers);
return fresh(this.headers, (this.res._headers || {}));
}
return false;

View File

@@ -2,13 +2,15 @@
* Module dependencies.
*/
var contentDisposition = require('content-disposition');
var deprecate = require('depd')('express');
var escapeHtml = require('escape-html');
var merge = require('utils-merge');
var parseUrl = require('parseurl');
var vary = require('vary');
var http = require('http')
, path = require('path')
, connect = require('connect')
, utils = connect.utils
, sign = require('cookie-signature').sign
, normalizeType = require('./utils').normalizeType
, normalizeTypes = require('./utils').normalizeTypes
@@ -412,15 +414,17 @@ res.sendfile = function(path, options, fn){
* @api public
*/
res.download = function(path, filename, fn){
res.download = function download(path, filename, fn) {
// support function as second arg
if ('function' == typeof filename) {
if (typeof filename === 'function') {
fn = filename;
filename = null;
}
filename = filename || path;
this.set('Content-Disposition', 'attachment; filename="' + basename(filename) + '"');
this.set('Content-Disposition', contentDisposition(filename));
return this.sendfile(path, fn);
};
@@ -543,11 +547,13 @@ res.format = function(obj){
* @api public
*/
res.attachment = function(filename){
if (filename) this.type(extname(filename));
this.set('Content-Disposition', filename
? 'attachment; filename="' + basename(filename) + '"'
: 'attachment');
res.attachment = function attachment(filename) {
if (filename) {
this.type(extname(filename));
}
this.set('Content-Disposition', contentDisposition(filename));
return this;
};
@@ -607,7 +613,7 @@ res.get = function(field){
res.clearCookie = function(name, options){
var opts = { expires: new Date(1), path: '/' };
return this.cookie(name, '', options
? utils.merge(opts, options)
? merge(opts, options)
: opts);
};
@@ -635,7 +641,7 @@ res.clearCookie = function(name, options){
*/
res.cookie = function(name, val, options){
options = utils.merge({}, options);
options = merge({}, options);
var secret = this.req.secret;
var signed = options.signed;
if (signed && !secret) throw new Error('connect.cookieParser("secret") required for signed cookies');
@@ -693,7 +699,7 @@ res.location = function(url){
if (!~url.indexOf('://') && 0 != url.indexOf('//')) {
// relative to path
if ('.' == url[0]) {
path = req.originalUrl.split('?')[0];
path = parseUrl.original(req).pathname;
path = path + ('/' == path[path.length - 1] ? '' : '/');
url = resolve(path, url);
// relative to mount-point
@@ -737,7 +743,7 @@ res.redirect = function(url){
status = url;
url = arguments[1];
} else {
deprecate('res.redirect(ur, status): Use res.redirect(status, url) instead');
deprecate('res.redirect(url, status): Use res.redirect(status, url) instead');
status = arguments[1];
}
}

View File

@@ -3,10 +3,9 @@
* Module dependencies.
*/
var mime = require('connect').mime
, proxyaddr = require('proxy-addr')
, crc32 = require('buffer-crc32')
, crypto = require('crypto');
var etag = require('etag');
var mime = require('connect').mime;
var proxyaddr = require('proxy-addr');
var typer = require('media-typer');
/**
@@ -24,17 +23,12 @@ var toString = {}.toString;
* @api private
*/
exports.etag = function etag(body, encoding){
if (body.length === 0) {
// fast-path empty body
return '"1B2M2Y8AsgTpgAmY7PhCfg=="'
}
exports.etag = function (body, encoding) {
var buf = !Buffer.isBuffer(body)
? new Buffer(body, encoding)
: body;
var hash = crypto
.createHash('md5')
.update(body, encoding)
.digest('base64')
return '"' + hash + '"'
return etag(buf, {weak: false});
};
/**
@@ -47,16 +41,11 @@ exports.etag = function etag(body, encoding){
*/
exports.wetag = function wetag(body, encoding){
if (body.length === 0) {
// fast-path empty body
return 'W/"0-0"'
}
var buf = !Buffer.isBuffer(body)
? new Buffer(body, encoding)
: body;
var buf = Buffer.isBuffer(body)
? body
: new Buffer(body, encoding)
var len = buf.length
return 'W/"' + len.toString(16) + '-' + crc32.unsigned(buf) + '"'
return etag(buf, {weak: true});
};
/**

View File

@@ -1,7 +1,7 @@
{
"name": "express",
"description": "Sinatra inspired web development framework",
"version": "3.16.2",
"version": "3.18.6",
"author": "TJ Holowaychuk <tj@vision-media.ca>",
"contributors": [
"Aaron Heckmann <aaron.heckmann+github@gmail.com>",
@@ -11,6 +11,9 @@
"Jonathan Ong <me@jongleberry.com>",
"Roman Shtylman <shtylman+expressjs@gmail.com"
],
"license": "MIT",
"repository": "strongloop/express",
"homepage": "http://expressjs.com/",
"keywords": [
"express",
"framework",
@@ -22,39 +25,38 @@
"app",
"api"
],
"repository": "visionmedia/express",
"license": "MIT",
"dependencies": {
"basic-auth": "1.0.0",
"buffer-crc32": "0.2.3",
"connect": "2.25.2",
"connect": "2.27.6",
"content-disposition": "0.5.0",
"commander": "1.3.2",
"debug": "1.0.4",
"depd": "0.4.4",
"cookie-signature": "1.0.5",
"debug": "~2.1.0",
"depd": "~1.0.0",
"escape-html": "1.0.1",
"media-typer": "0.2.0",
"etag": "~1.5.1",
"fresh": "0.2.4",
"media-typer": "0.3.0",
"methods": "1.1.0",
"mkdirp": "0.5.0",
"parseurl": "~1.2.0",
"proxy-addr": "1.0.1",
"range-parser": "1.0.0",
"send": "0.8.1",
"vary": "0.1.0",
"parseurl": "~1.3.0",
"proxy-addr": "~1.0.4",
"range-parser": "~1.0.2",
"send": "0.10.1",
"utils-merge": "1.0.0",
"vary": "~1.0.0",
"cookie": "0.1.2",
"fresh": "0.2.2",
"cookie-signature": "1.0.4",
"merge-descriptors": "0.0.2"
},
"devDependencies": {
"connect-redis": "~1.5.0",
"istanbul": "0.3.0",
"mocha": "~1.21.4",
"should": "~4.0.0",
"istanbul": "0.3.5",
"mocha": "~2.0.0",
"should": "~4.3.1",
"supertest": "~0.15.0",
"ejs": "~1.0.0",
"jade": "~1.5.0",
"hjs": "~0.0.6",
"marked": "0.3.2",
"supertest": "~0.13.0"
"marked": "0.3.2"
},
"engines": {
"node": ">= 0.8.0"
@@ -62,10 +64,18 @@
"bin": {
"express": "./bin/express"
},
"files": [
"LICENSE",
"History.md",
"Readme.md",
"index.js",
"bin/",
"lib/"
],
"scripts": {
"prepublish": "npm prune",
"test": "mocha --require test/support/env --reporter dot --check-leaks test/ test/acceptance/",
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --require test/support/env --reporter dot --check-leaks test/ test/acceptance/",
"test-tap": "mocha --require test/support/env --reporter tap --check-leaks test/ test/acceptance/",
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --reporter spec --check-leaks test/ test/acceptance/"
}
}

View File

@@ -1,66 +0,0 @@
/**
* Module dependencies.
*/
var express = require('../');
var app = express()
, blog = express()
, admin = express();
// app.use(express.logger('dev'))
blog.use('/admin', admin);
app.use('/blog', blog);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.locals.self = true;
app.get('/render', function(req, res){
res.render('hello');
});
admin.get('/', function(req, res){
res.send('Hello World\n');
});
blog.get('/', function(req, res){
res.send('Hello World\n');
});
app.get('/', function(req, res){
res.send('Hello World\n');
});
app.get('/json', function(req, res){
res.send({ name: 'Tobi', role: 'admin' });
});
app.get('/json/:n', function(req, res){
var n = ~~req.params.n;
var arr = [];
var obj = { name: 'Tobi', role: 'admin' };
while (n--) arr.push(obj);
res.send(arr);
});
function foo(req, res, next) {
next();
}
app.get('/middleware', foo, foo, foo, foo, function(req, res){
res.send('Hello World\n');
});
var n = 100;
while (n--) {
app.get('/foo', foo, foo, function(req, res){
});
}
app.get('/match', function(req, res){
res.send('Hello World\n');
});
app.listen(8000);

View File

@@ -1,21 +0,0 @@
#!/usr/bin/env node
var buf = '';
process.stdin.setEncoding('utf8');
process.stdin.on('data', function(chunk){
buf += chunk;
}).on('end', function(){
var comments = JSON.parse(buf);
comments.forEach(function(comment){
if (comment.ignore) return;
if (comment.isPrivate) return;
if (!comment.ctx) return;
if (!comment.description.full.indexOf('Module dep')) return;
var ctx = comment.ctx;
console.log();
console.log('# %s', ctx.string);
console.log();
console.log(comment.description.full.trim().replace(/^/gm, ' '));
});
console.log();
}).resume();

View File

@@ -1 +0,0 @@
p Hello

View File

@@ -53,7 +53,7 @@ describe('web-service', function(){
.get('/api/repos?api-key=foo')
.expect('Content-Type', 'application/json; charset=utf-8')
.expect(/"name":"express"/)
.expect(/"url":"http:\/\/github.com\/visionmedia\/express"/)
.expect(/"url":"http:\/\/github.com\/strongloop\/express"/)
.expect(200, done)
})
})

View File

@@ -1,14 +1,15 @@
var express = require('../');
var express = require('..');
var tmpl = require('./support/tmpl');
describe('app', function(){
describe('.render(name, fn)', function(){
it('should support absolute paths', function(done){
var app = express();
var app = createApp();
app.locals.user = { name: 'tobi' };
app.render(__dirname + '/fixtures/user.jade', function(err, str){
app.render(__dirname + '/fixtures/user.tmpl', function (err, str) {
if (err) return done(err);
str.should.equal('<p>tobi</p>');
done();
@@ -16,9 +17,9 @@ describe('app', function(){
})
it('should support absolute paths with "view engine"', function(done){
var app = express();
var app = createApp();
app.set('view engine', 'jade');
app.set('view engine', 'tmpl');
app.locals.user = { name: 'tobi' };
app.render(__dirname + '/fixtures/user', function(err, str){
@@ -29,12 +30,12 @@ describe('app', function(){
})
it('should expose app.locals', function(done){
var app = express();
var app = createApp();
app.set('views', __dirname + '/fixtures');
app.locals.user = { name: 'tobi' };
app.render('user.jade', function(err, str){
app.render('user.tmpl', function (err, str) {
if (err) return done(err);
str.should.equal('<p>tobi</p>');
done();
@@ -42,12 +43,12 @@ describe('app', function(){
})
it('should support index.<engine>', function(done){
var app = express();
var app = createApp();
app.set('views', __dirname + '/fixtures');
app.set('view engine', 'jade');
app.set('view engine', 'tmpl');
app.render('blog/post', function(err, str){
app.render('blog/post', function (err, str) {
if (err) return done(err);
str.should.equal('<h1>blog post</h1>');
done();
@@ -77,10 +78,11 @@ describe('app', function(){
describe('when the file does not exist', function(){
it('should provide a helpful error', function(done){
var app = express();
var app = createApp();
app.set('views', __dirname + '/fixtures');
app.render('rawr.jade', function(err){
err.message.should.equal('Failed to lookup view "rawr.jade" in views directory "' + __dirname + '/fixtures"');
app.render('rawr.tmpl', function (err) {
err.message.should.equal('Failed to lookup view "rawr.tmpl" in views directory "' + __dirname + '/fixtures"');
done();
});
})
@@ -88,11 +90,11 @@ describe('app', function(){
describe('when an error occurs', function(){
it('should invoke the callback', function(done){
var app = express();
var app = createApp();
app.set('views', __dirname + '/fixtures');
app.render('user.jade', function(err, str){
app.render('user.tmpl', function (err, str) {
// nextTick to prevent cyclic
process.nextTick(function(){
err.message.should.match(/Cannot read property 'name' of undefined/);
@@ -104,11 +106,11 @@ describe('app', function(){
describe('when an extension is given', function(){
it('should render the template', function(done){
var app = express();
var app = createApp();
app.set('views', __dirname + '/fixtures');
app.render('email.jade', function(err, str){
app.render('email.tmpl', function (err, str) {
if (err) return done(err);
str.should.equal('<p>This is an email</p>');
done();
@@ -118,9 +120,9 @@ describe('app', function(){
describe('when "view engine" is given', function(){
it('should render the template', function(done){
var app = express();
var app = createApp();
app.set('view engine', 'jade');
app.set('view engine', 'tmpl');
app.set('views', __dirname + '/fixtures');
app.render('email', function(err, str){
@@ -219,13 +221,13 @@ describe('app', function(){
describe('.render(name, options, fn)', function(){
it('should render the template', function(done){
var app = express();
var app = createApp();
app.set('views', __dirname + '/fixtures');
var user = { name: 'tobi' };
app.render('user.jade', { user: user }, function(err, str){
app.render('user.tmpl', { user: user }, function (err, str) {
if (err) return done(err);
str.should.equal('<p>tobi</p>');
done();
@@ -233,12 +235,12 @@ describe('app', function(){
})
it('should expose app.locals', function(done){
var app = express();
var app = createApp();
app.set('views', __dirname + '/fixtures');
app.locals.user = { name: 'tobi' };
app.render('user.jade', {}, function(err, str){
app.render('user.tmpl', {}, function (err, str) {
if (err) return done(err);
str.should.equal('<p>tobi</p>');
done();
@@ -246,13 +248,13 @@ describe('app', function(){
})
it('should give precedence to app.render() locals', function(done){
var app = express();
var app = createApp();
app.set('views', __dirname + '/fixtures');
app.locals.user = { name: 'tobi' };
var jane = { name: 'jane' };
app.render('user.jade', { user: jane }, function(err, str){
app.render('user.tmpl', { user: jane }, function (err, str) {
if (err) return done(err);
str.should.equal('<p>jane</p>');
done();
@@ -292,3 +294,11 @@ describe('app', function(){
})
})
})
function createApp() {
var app = express();
app.engine('.tmpl', tmpl);
return app;
}

View File

@@ -1 +0,0 @@
h1 blog post

1
test/fixtures/blog/post/index.tmpl vendored Normal file
View File

@@ -0,0 +1 @@
<h1>blog post</h1>

View File

@@ -1 +0,0 @@
p This is an email

1
test/fixtures/email.tmpl vendored Normal file
View File

@@ -0,0 +1 @@
<p>This is an email</p>

View File

@@ -1 +0,0 @@
p #{first} #{last} is a #{species}

View File

@@ -1 +0,0 @@
p= user.name

1
test/fixtures/user.tmpl vendored Normal file
View File

@@ -0,0 +1 @@
<p>$user.name</p>

View File

@@ -32,5 +32,18 @@ describe('req', function(){
.set('If-None-Match', '"12345"')
.expect(200, 'false', done);
})
it('should return false without response headers', function(done){
var app = express();
app.use(function(req, res){
res._headers = undefined;
res.send(req.fresh);
});
request(app)
.get('/')
.expect(200, 'false', done);
})
})
})

View File

@@ -45,10 +45,9 @@ describe('req', function(){
res.send(req.ip);
});
request(app)
.get('/')
.set('X-Forwarded-For', 'client, p1, p2')
.expect('127.0.0.1', done);
var test = request(app).get('/')
test.set('X-Forwarded-For', 'client, p1, p2')
test.expect(200, getExpectedClientAddress(test._server), done);
})
})
})
@@ -63,10 +62,19 @@ describe('req', function(){
res.send(req.ip);
});
request(app)
.get('/')
.expect('127.0.0.1', done);
var test = request(app).get('/')
test.expect(200, getExpectedClientAddress(test._server), done);
})
})
})
})
/**
* Get the local client address depending on AF_NET of server
*/
function getExpectedClientAddress(server) {
return server.address().address === '::'
? '::ffff:127.0.0.1'
: '127.0.0.1';
}

View File

@@ -32,5 +32,18 @@ describe('req', function(){
.set('If-None-Match', '"12345"')
.expect(200, 'true', done);
})
it('should return true without response headers', function(done){
var app = express();
app.use(function(req, res){
res._headers = undefined;
res.send(req.stale);
});
request(app)
.get('/')
.expect(200, 'true', done);
})
})
})

View File

@@ -15,7 +15,33 @@ describe('req', function(){
request(app)
.get('/')
.set('Host', 'tobi.ferrets.example.com')
.expect(["ferrets","tobi"], done);
.expect(200, ['ferrets', 'tobi'], done);
})
it('should work with IPv4 address', function(done){
var app = express();
app.use(function(req, res){
res.send(req.subdomains);
});
request(app)
.get('/')
.set('Host', '127.0.0.1')
.expect(200, [], done);
})
it('should work with IPv6 address', function(done){
var app = express();
app.use(function(req, res){
res.send(req.subdomains);
});
request(app)
.get('/')
.set('Host', '[::1]')
.expect(200, [], done);
})
})
@@ -30,7 +56,7 @@ describe('req', function(){
request(app)
.get('/')
.set('Host', 'example.com')
.expect([], done);
.expect(200, [], done);
})
})
@@ -45,7 +71,23 @@ describe('req', function(){
request(app)
.get('/')
.expect([], done);
.expect(200, [], done);
})
})
describe('with trusted X-Forwarded-Host', function () {
it('should return an array', function (done) {
var app = express();
app.set('trust proxy', true);
app.use(function (req, res) {
res.send(req.subdomains);
});
request(app)
.get('/')
.set('X-Forwarded-Host', 'tobi.ferrets.example.com')
.expect(200, ['ferrets', 'tobi'], done);
})
})
@@ -62,7 +104,35 @@ describe('req', function(){
request(app)
.get('/')
.set('Host', 'tobi.ferrets.sub.example.com')
.expect(["com","example","sub","ferrets","tobi"], done);
.expect(200, ['com', 'example', 'sub', 'ferrets', 'tobi'], done);
})
it('should return an array with the whole IPv4', function (done) {
var app = express();
app.set('subdomain offset', 0);
app.use(function(req, res){
res.send(req.subdomains);
});
request(app)
.get('/')
.set('Host', '127.0.0.1')
.expect(200, ['127.0.0.1'], done);
})
it('should return an array with the whole IPv6', function (done) {
var app = express();
app.set('subdomain offset', 0);
app.use(function(req, res){
res.send(req.subdomains);
});
request(app)
.get('/')
.set('Host', '[::1]')
.expect(200, ['[::1]'], done);
})
})
@@ -78,7 +148,7 @@ describe('req', function(){
request(app)
.get('/')
.set('Host', 'tobi.ferrets.sub.example.com')
.expect(["ferrets","tobi"], done);
.expect(200, ['ferrets', 'tobi'], done);
})
})
@@ -94,7 +164,7 @@ describe('req', function(){
request(app)
.get('/')
.set('Host', 'sub.example.com')
.expect([], done);
.expect(200, [], done);
})
})
})

View File

@@ -1,8 +1,8 @@
var express = require('../')
, request = require('supertest')
, utils = require('connect').utils
, cookie = require('cookie');
var merge = require('utils-merge');
describe('res', function(){
describe('.cookie(name, object)', function(){
@@ -111,7 +111,7 @@ describe('res', function(){
var app = express();
var options = { maxAge: 1000 };
var optionsCopy = utils.merge({}, options);
var optionsCopy = merge({}, options);
app.use(function(req, res){
res.cookie('name', 'tobi', options)

View File

@@ -1,16 +1,17 @@
var express = require('../')
, request = require('supertest');
var express = require('..');
var request = require('supertest');
var tmpl = require('./support/tmpl');
describe('res', function(){
describe('.render(name)', function(){
it('should support absolute paths', function(done){
var app = express();
var app = createApp();
app.locals.user = { name: 'tobi' };
app.use(function(req, res){
res.render(__dirname + '/fixtures/user.jade');
res.render(__dirname + '/fixtures/user.tmpl');
});
request(app)
@@ -19,10 +20,10 @@ describe('res', function(){
})
it('should support absolute paths with "view engine"', function(done){
var app = express();
var app = createApp();
app.locals.user = { name: 'tobi' };
app.set('view engine', 'jade');
app.set('view engine', 'tmpl');
app.use(function(req, res){
res.render(__dirname + '/fixtures/user');
@@ -34,13 +35,13 @@ describe('res', function(){
})
it('should expose app.locals', function(done){
var app = express();
var app = createApp();
app.set('views', __dirname + '/fixtures');
app.locals.user = { name: 'tobi' };
app.use(function(req, res){
res.render('user.jade');
res.render('user.tmpl');
});
request(app)
@@ -49,10 +50,10 @@ describe('res', function(){
})
it('should support index.<engine>', function(done){
var app = express();
var app = createApp();
app.set('views', __dirname + '/fixtures');
app.set('view engine', 'jade');
app.set('view engine', 'tmpl');
app.use(function(req, res){
res.render('blog/post');
@@ -65,12 +66,12 @@ describe('res', function(){
describe('when an error occurs', function(){
it('should next(err)', function(done){
var app = express();
var app = createApp();
app.set('views', __dirname + '/fixtures');
app.use(function(req, res){
res.render('user.jade');
res.render('user.tmpl');
});
app.use(function(err, req, res, next){
@@ -85,9 +86,9 @@ describe('res', function(){
describe('when "view engine" is given', function(){
it('should render the template', function(done){
var app = express();
var app = createApp();
app.set('view engine', 'jade');
app.set('view engine', 'tmpl');
app.set('views', __dirname + '/fixtures');
app.use(function(req, res){
@@ -103,14 +104,14 @@ describe('res', function(){
describe('.render(name, option)', function(){
it('should render the template', function(done){
var app = express();
var app = createApp();
app.set('views', __dirname + '/fixtures');
var user = { name: 'tobi' };
app.use(function(req, res){
res.render('user.jade', { user: user });
res.render('user.tmpl', { user: user });
});
request(app)
@@ -119,13 +120,13 @@ describe('res', function(){
})
it('should expose app.locals', function(done){
var app = express();
var app = createApp();
app.set('views', __dirname + '/fixtures');
app.locals.user = { name: 'tobi' };
app.use(function(req, res){
res.render('user.jade');
res.render('user.tmpl');
});
request(app)
@@ -134,13 +135,13 @@ describe('res', function(){
})
it('should expose res.locals', function(done){
var app = express();
var app = createApp();
app.set('views', __dirname + '/fixtures');
app.use(function(req, res){
res.locals.user = { name: 'tobi' };
res.render('user.jade');
res.render('user.tmpl');
});
request(app)
@@ -149,14 +150,14 @@ describe('res', function(){
})
it('should give precedence to res.locals over app.locals', function(done){
var app = express();
var app = createApp();
app.set('views', __dirname + '/fixtures');
app.locals.user = { name: 'tobi' };
app.use(function(req, res){
res.locals.user = { name: 'jane' };
res.render('user.jade', {});
res.render('user.tmpl', {});
});
request(app)
@@ -165,14 +166,14 @@ describe('res', function(){
})
it('should give precedence to res.render() locals over res.locals', function(done){
var app = express();
var app = createApp();
app.set('views', __dirname + '/fixtures');
var jane = { name: 'jane' };
app.use(function(req, res){
res.locals.user = { name: 'tobi' };
res.render('user.jade', { user: jane });
res.render('user.tmpl', { user: jane });
});
request(app)
@@ -181,14 +182,14 @@ describe('res', function(){
})
it('should give precedence to res.render() locals over app.locals', function(done){
var app = express();
var app = createApp();
app.set('views', __dirname + '/fixtures');
app.locals.user = { name: 'tobi' };
var jane = { name: 'jane' };
app.use(function(req, res){
res.render('user.jade', { user: jane });
res.render('user.tmpl', { user: jane });
});
request(app)
@@ -199,13 +200,13 @@ describe('res', function(){
describe('.render(name, options, fn)', function(){
it('should pass the resulting string', function(done){
var app = express();
var app = createApp();
app.set('views', __dirname + '/fixtures');
app.use(function(req, res){
var tobi = { name: 'tobi' };
res.render('user.jade', { user: tobi }, function(err, html){
res.render('user.tmpl', { user: tobi }, function (err, html) {
html = html.replace('tobi', 'loki');
res.end(html);
});
@@ -219,13 +220,13 @@ describe('res', function(){
describe('.render(name, fn)', function(){
it('should pass the resulting string', function(done){
var app = express();
var app = createApp();
app.set('views', __dirname + '/fixtures');
app.use(function(req, res){
res.locals.user = { name: 'tobi' };
res.render('user.jade', function(err, html){
res.render('user.tmpl', function (err, html) {
html = html.replace('tobi', 'loki');
res.end(html);
});
@@ -238,12 +239,12 @@ describe('res', function(){
describe('when an error occurs', function(){
it('should pass it to the callback', function(done){
var app = express();
var app = createApp();
app.set('views', __dirname + '/fixtures');
app.use(function(req, res){
res.render('user.jade', function(err){
res.render('user.tmpl', function (err) {
res.end(err.message);
});
});
@@ -255,3 +256,11 @@ describe('res', function(){
})
})
})
function createApp() {
var app = express();
app.engine('.tmpl', tmpl);
return app;
}

View File

@@ -120,7 +120,7 @@ describe('res', function(){
request(app)
.get('/')
.expect('ETag', 'W/"7ff-2796319984"')
.expect('ETag', 'W/"fz/jGo0ONwzb+aKy/rWipg=="')
.end(done);
})
@@ -209,7 +209,7 @@ describe('res', function(){
request(app)
.get('/')
.expect('ETag', 'W/"7ff-2796319984"')
.expect('ETag', 'W/"fz/jGo0ONwzb+aKy/rWipg=="')
.end(done);
})
@@ -325,7 +325,7 @@ describe('res', function(){
request(app)
.get('/')
.set('If-None-Match', 'W/"7ff-2796319984"')
.set('If-None-Match', 'W/"fz/jGo0ONwzb+aKy/rWipg=="')
.expect(304, done);
})
@@ -371,7 +371,7 @@ describe('res', function(){
request(app)
.get('/')
.expect('etag', 'W/"c-1525560792"', done)
.expect('etag', 'W/"c-5aee35d8"', done)
})
it('should send ETag for empty string response', function(done){
@@ -400,7 +400,7 @@ describe('res', function(){
request(app)
.get('/')
.expect('etag', 'W/"7ff-2796319984"', done)
.expect('etag', 'W/"fz/jGo0ONwzb+aKy/rWipg=="', done)
});
it('should not override ETag when manually set', function(done){
@@ -499,7 +499,7 @@ describe('res', function(){
request(app)
.get('/')
.expect('etag', 'W/"d-1486392595"', done)
.expect('etag', 'W/"d-58988d13"', done)
})
})

35
test/support/tmpl.js Normal file
View File

@@ -0,0 +1,35 @@
var fs = require('fs');
var variableRegExp = /\$([0-9a-zA-Z\.]+)/g;
module.exports = function renderFile(fileName, options, callback) {
function onReadFile(err, str) {
if (err) {
callback(err);
return;
}
try {
str = str.replace(variableRegExp, generateVariableLookup(options));
} catch (e) {
err = e;
}
callback(err, str);
}
fs.readFile(fileName, 'utf8', onReadFile);
};
function generateVariableLookup(data) {
return function variableLookup(str, path) {
var parts = path.split('.');
var value = data;
for (var i = 0; i < parts.length; i++) {
value = value[parts[i]];
}
return value;
};
}

View File

@@ -28,18 +28,18 @@ describe('utils.etag(body, encoding)', function(){
describe('utils.wetag(body, encoding)', function(){
it('should support strings', function(){
utils.wetag('express!')
.should.eql('W/"8-3098196679"')
.should.eql('W/"8-b8aabac7"')
})
it('should support utf8 strings', function(){
utils.wetag('express❤', 'utf8')
.should.eql('W/"a-1751845617"')
.should.eql('W/"a-686b0af1"')
})
it('should support buffer', function(){
var buf = new Buffer('express!')
utils.wetag(buf)
.should.eql('W/"8-3098196679"');
.should.eql('W/"8-b8aabac7"');
})
it('should support empty string', function(){