Compare commits

...

134 Commits

Author SHA1 Message Date
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
Douglas Christopher Wilson
ddac571fdf 3.16.2 2014-08-07 11:59:54 -04:00
Douglas Christopher Wilson
982d24b475 deps: connect@2.25.2 2014-08-07 11:53:40 -04:00
Douglas Christopher Wilson
ea427c1bb4 3.16.1 2014-08-06 18:07:31 -04:00
Douglas Christopher Wilson
0bd6c311cf deps: mocha@~1.21.4 2014-08-06 18:06:19 -04:00
Douglas Christopher Wilson
7f606ebf29 deps: connect@2.25.1 2014-08-06 18:05:50 -04:00
Douglas Christopher Wilson
c652cf7eed 3.16.0 2014-08-06 01:40:46 -04:00
Douglas Christopher Wilson
19fd6f85b0 deps: connect-redis@~1.5.0 2014-08-06 01:39:12 -04:00
Douglas Christopher Wilson
b6c5b0511f deps: jade@~1.5.0 2014-08-06 01:37:58 -04:00
Douglas Christopher Wilson
0e42a37edd deps: send@0.8.1 2014-08-06 01:37:13 -04:00
Douglas Christopher Wilson
b24ed15878 deps: connect@2.25.0 2014-08-06 01:35:00 -04:00
Douglas Christopher Wilson
15590d75b2 3.15.3 2014-08-04 17:31:52 -04:00
Douglas Christopher Wilson
e8b471ff4f fix res.sendfile regression for serving directory index files 2014-08-04 17:30:25 -04:00
Douglas Christopher Wilson
767db01b79 deps: connect@2.24.3 2014-08-04 17:26:43 -04:00
Douglas Christopher Wilson
696e150f0a 3.15.2 2014-07-27 15:53:45 -04:00
Douglas Christopher Wilson
819265c7ae deps: send@0.7.2 2014-07-27 15:41:54 -04:00
Douglas Christopher Wilson
baf8b14a71 deps: depd@0.4.4
fixes #2262
2014-07-27 15:41:19 -04:00
Douglas Christopher Wilson
06e7685d65 deps: connect@2.24.2 2014-07-27 15:40:19 -04:00
Douglas Christopher Wilson
9f4968aaa3 3.15.1 2014-07-26 17:42:18 -04:00
Douglas Christopher Wilson
afea3c0ae8 deps: mocha@~1.21.0 2014-07-26 17:36:42 -04:00
Douglas Christopher Wilson
edaabe66cf deps: send@0.7.1 2014-07-26 17:36:40 -04:00
Douglas Christopher Wilson
f724730e1a Adjust wording on deprecation messages 2014-07-26 17:36:39 -04:00
Douglas Christopher Wilson
e49d0dc9e3 deps: depd@0.4.3
fixes #2262
2014-07-26 17:36:24 -04:00
Douglas Christopher Wilson
e7a3fbaf48 deps: connect@2.24.1 2014-07-26 17:30:13 -04:00
Douglas Christopher Wilson
928952e7f0 3.15.0 2014-07-23 00:53:19 -04:00
Ashley Streb
a28b7a85cf Fix req.protocol for proxy-direct connections
fixes #2252
2014-07-23 00:19:10 -04:00
Douglas Christopher Wilson
3fc8dc54ee docs: replace Gittip badge 2014-07-23 00:13:21 -04:00
Douglas Christopher Wilson
0d77305a1a Pass options from res.sendfile to send
fixes #2017
2014-07-23 00:08:15 -04:00
Douglas Christopher Wilson
323c185079 deps: send@0.7.0 2014-07-23 00:05:45 -04:00
Douglas Christopher Wilson
1d0da9036b deps: parseurl@~1.2.0 2014-07-22 23:53:50 -04:00
Douglas Christopher Wilson
683ba1cd75 deps: depd@0.4.2 2014-07-22 23:52:44 -04:00
Douglas Christopher Wilson
e4ff5281c9 deps: connect@2.24.0 2014-07-22 23:50:36 -04:00
Douglas Christopher Wilson
7414a1f463 deps: debug@1.0.4 2014-07-18 14:18:35 -04:00
Douglas Christopher Wilson
916c53737d 3.14.0 2014-07-11 13:11:31 -04:00
Douglas Christopher Wilson
b2382a7336 Remove unnecessary escaping in res.jsonp 2014-07-11 00:20:11 -04:00
Douglas Christopher Wilson
f684a64df7 Add explicit "Rosetta Flash JSONP abuse" protection 2014-07-11 00:15:55 -04:00
Douglas Christopher Wilson
5d03d0eac8 Deprecate res.redirect(url, status) 2014-07-10 23:21:16 -04:00
Yad Smood
544c6665f5 Fix res.send(status, num) to send num as json
fixes #2226
2014-07-10 23:19:57 -04:00
Douglas Christopher Wilson
cf8005e63f deps: basic-auth@1.0.0 2014-07-10 23:07:45 -04:00
Douglas Christopher Wilson
25ef8425d2 deps: methods@1.1.0 2014-07-10 23:06:15 -04:00
Douglas Christopher Wilson
577cc1d1a0 deps: parseurl@~1.1.3 2014-07-10 23:03:26 -04:00
Douglas Christopher Wilson
3c87a6aede deps: debug@1.0.3 2014-07-10 23:02:24 -04:00
Douglas Christopher Wilson
7c1f90bf16 deps: istanbul@0.3.0 2014-07-10 22:57:08 -04:00
Douglas Christopher Wilson
7bcf5f5085 deps: connect@2.23.0 2014-07-10 22:56:31 -04:00
Douglas Christopher Wilson
abe0ffa311 3.13.0 2014-07-04 00:40:01 -04:00
Douglas Christopher Wilson
b601d64203 tests: fix inconsistent test 2014-07-04 00:38:59 -04:00
Douglas Christopher Wilson
f381f2d9b6 add deprecation message to req.auth 2014-07-04 00:24:01 -04:00
Douglas Christopher Wilson
12507cfcd0 deps: connect@2.22.0 2014-07-03 23:09:44 -04:00
Douglas Christopher Wilson
185e327e29 add deprecation message to app.configure 2014-07-03 14:13:39 -04:00
Douglas Christopher Wilson
c468f5ff20 deps: send@0.5.0 2014-07-03 13:10:33 -04:00
Douglas Christopher Wilson
9bb47fba30 3.12.1 2014-06-26 18:35:54 -04:00
Douglas Christopher Wilson
78d489d730 deps: cookie-signature@1.0.4 2014-06-26 18:26:34 -04:00
Douglas Christopher Wilson
8ffb9f9477 deps: connect@2.21.1 2014-06-26 18:25:48 -04:00
Douglas Christopher Wilson
9cb147370e deps: istanbul@0.2.12 2014-06-26 18:21:26 -04:00
Douglas Christopher Wilson
75422c16bf 3.12.0 2014-06-21 21:57:02 -04:00
Douglas Christopher Wilson
e66667e465 Use media-typer to alter content-type charset 2014-06-21 21:09:12 -04:00
Douglas Christopher Wilson
7d6208e0af deps: connect@2.21.0 2014-06-21 21:09:10 -04:00
Douglas Christopher Wilson
2a105df9f2 3.11.0 2014-06-19 23:36:00 -04:00
Douglas Christopher Wilson
9c731f1883 deprecate things with depd module 2014-06-19 23:34:58 -04:00
Douglas Christopher Wilson
5a4e9125de deps: connect@2.20.2 2014-06-19 23:24:07 -04:00
Douglas Christopher Wilson
9db1367c2d deps: buffer-crc32@0.2.3 2014-06-19 22:55:21 -04:00
Douglas Christopher Wilson
73c5533e66 3.10.5 2014-06-12 00:28:08 -04:00
Douglas Christopher Wilson
3b1f747f96 deps: send@0.4.3 2014-06-12 00:24:21 -04:00
Douglas Christopher Wilson
9e9827d236 deps: debug@1.0.2 2014-06-12 00:23:15 -04:00
Douglas Christopher Wilson
a76d508424 deps: connect@2.19.6 2014-06-12 00:20:30 -04:00
Douglas Christopher Wilson
f881784e9b 3.10.4 2014-06-09 18:53:52 -04:00
Douglas Christopher Wilson
5af625903f deps: send@0.4.2 2014-06-09 18:51:55 -04:00
Douglas Christopher Wilson
dc94f305cc deps: debug@1.0.1 2014-06-09 18:50:36 -04:00
Douglas Christopher Wilson
8060a49c6c deps: connect@2.19.5 2014-06-09 18:50:00 -04:00
Douglas Christopher Wilson
2fd31f6ea6 3.10.3 2014-06-05 23:38:58 -04:00
Douglas Christopher Wilson
9cf7bba8f0 deps: connect@2.19.4 2014-06-05 23:37:22 -04:00
Douglas Christopher Wilson
2e257d1cf7 build: use compressed formats in package 2014-06-05 19:45:00 -04:00
Douglas Christopher Wilson
56831d7799 deps: debug@1.0.0 2014-06-05 19:34:05 -04:00
Jonathan Ong
6d65ae5ba6 use vary@0.1.0
with backwards compatibility

closes #2161
2014-06-05 19:32:32 -04:00
Douglas Christopher Wilson
c919b4a573 3.10.2 2014-06-03 21:35:34 -04:00
Douglas Christopher Wilson
fe6f392c2d deps: connect@2.19.3 2014-06-03 21:33:55 -04:00
Douglas Christopher Wilson
3b34a537ee 3.10.1 2014-06-03 16:45:09 -04:00
Douglas Christopher Wilson
ad79ce9c4b deps: connect@2.19.2 2014-06-03 16:44:29 -04:00
Douglas Christopher Wilson
721f6388c3 deps: proxy-addr@1.0.1 2014-06-03 16:42:49 -04:00
Douglas Christopher Wilson
298ac11018 3.10.0 2014-06-03 00:40:27 -04:00
Douglas Christopher Wilson
bb6e207336 deps: connect@2.19.1 2014-06-03 00:37:57 -04:00
Douglas Christopher Wilson
f433b7c7cf replace utils.escape with html-escape 2014-06-03 00:37:32 -04:00
Douglas Christopher Wilson
a94278abd1 deps: send@0.4.1 2014-06-02 21:31:23 -04:00
Douglas Christopher Wilson
a7cd5a2553 deps: methods@1.0.1 2014-06-02 19:19:56 -04:00
29 changed files with 780 additions and 309 deletions

View File

@@ -1,3 +1,403 @@
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
===================
* deps: connect@2.25.2
- deps: body-parser@~1.6.2
- deps: qs@1.2.0
3.16.1 / 2014-08-06
===================
* deps: connect@2.25.1
- deps: body-parser@~1.6.1
- deps: qs@1.1.0
3.16.0 / 2014-08-05
===================
* deps: connect@2.25.0
- deps: body-parser@~1.6.0
- deps: compression@~1.0.10
- deps: csurf@~1.4.0
- deps: express-session@~1.7.4
- deps: qs@1.0.2
- deps: serve-static@~1.5.0
* deps: send@0.8.1
- Add `extensions` option
3.15.3 / 2014-08-04
===================
* fix `res.sendfile` regression for serving directory index files
* deps: connect@2.24.3
- deps: serve-index@~1.1.5
- deps: serve-static@~1.4.4
* deps: send@0.7.4
- Fix incorrect 403 on Windows and Node.js 0.11
- Fix serving index files without root dir
3.15.2 / 2014-07-27
===================
* deps: connect@2.24.2
- deps: body-parser@~1.5.2
- deps: depd@0.4.4
- deps: express-session@~1.7.2
- deps: morgan@~1.2.2
- deps: serve-static@~1.4.2
* deps: depd@0.4.4
- Work-around v8 generating empty stack traces
* deps: send@0.7.2
- deps: depd@0.4.4
3.15.1 / 2014-07-26
===================
* deps: connect@2.24.1
- deps: body-parser@~1.5.1
- deps: depd@0.4.3
- deps: express-session@~1.7.1
- deps: morgan@~1.2.1
- deps: serve-index@~1.1.4
- deps: serve-static@~1.4.1
* deps: depd@0.4.3
- Fix exception when global `Error.stackTraceLimit` is too low
* deps: send@0.7.1
- deps: depd@0.4.3
3.15.0 / 2014-07-22
===================
* Fix `req.protocol` for proxy-direct connections
* Pass options from `res.sendfile` to `send`
* deps: connect@2.24.0
- deps: body-parser@~1.5.0
- deps: compression@~1.0.9
- deps: connect-timeout@~1.2.1
- deps: debug@1.0.4
- deps: depd@0.4.2
- deps: express-session@~1.7.0
- deps: finalhandler@0.1.0
- deps: method-override@~2.1.2
- deps: morgan@~1.2.0
- deps: multiparty@3.3.1
- deps: parseurl@~1.2.0
- deps: serve-static@~1.4.0
* deps: debug@1.0.4
* deps: depd@0.4.2
- Add `TRACE_DEPRECATION` environment variable
- Remove non-standard grey color from color output
- Support `--no-deprecation` argument
- Support `--trace-deprecation` argument
* deps: parseurl@~1.2.0
- Cache URLs based on original value
- Remove no-longer-needed URL mis-parse work-around
- Simplify the "fast-path" `RegExp`
* deps: send@0.7.0
- Add `dotfiles` option
- Cap `maxAge` value to 1 year
- deps: debug@1.0.4
- deps: depd@0.4.2
3.14.0 / 2014-07-11
===================
* add explicit "Rosetta Flash JSONP abuse" protection
- previous versions are not vulnerable; this is just explicit protection
* deprecate `res.redirect(url, status)` -- use `res.redirect(status, url)` instead
* fix `res.send(status, num)` to send `num` as json (not error)
* remove unnecessary escaping when `res.jsonp` returns JSON response
* deps: basic-auth@1.0.0
- support empty password
- support empty username
* deps: connect@2.23.0
- deps: debug@1.0.3
- deps: express-session@~1.6.4
- deps: method-override@~2.1.0
- deps: parseurl@~1.1.3
- deps: serve-static@~1.3.1
* deps: debug@1.0.3
- Add support for multiple wildcards in namespaces
* deps: methods@1.1.0
- add `CONNECT`
* deps: parseurl@~1.1.3
- faster parsing of href-only URLs
3.13.0 / 2014-07-03
===================
* add deprecation message to `app.configure`
* add deprecation message to `req.auth`
* use `basic-auth` to parse `Authorization` header
* deps: connect@2.22.0
- deps: csurf@~1.3.0
- deps: express-session@~1.6.1
- deps: multiparty@3.3.0
- deps: serve-static@~1.3.0
* deps: send@0.5.0
- Accept string for `maxage` (converted by `ms`)
- Include link in default redirect response
3.12.1 / 2014-06-26
===================
* deps: connect@2.21.1
- deps: cookie-parser@1.3.2
- deps: cookie-signature@1.0.4
- deps: express-session@~1.5.2
- deps: type-is@~1.3.2
* deps: cookie-signature@1.0.4
- fix for timing attacks
3.12.0 / 2014-06-21
===================
* use `media-typer` to alter content-type charset
* deps: connect@2.21.0
- deprecate `connect(middleware)` -- use `app.use(middleware)` instead
- deprecate `connect.createServer()` -- use `connect()` instead
- fix `res.setHeader()` patch to work with with get -> append -> set pattern
- deps: compression@~1.0.8
- deps: errorhandler@~1.1.1
- deps: express-session@~1.5.0
- deps: serve-index@~1.1.3
3.11.0 / 2014-06-19
===================
* deprecate things with `depd` module
* deps: buffer-crc32@0.2.3
* deps: connect@2.20.2
- deprecate `verify` option to `json` -- use `body-parser` npm module instead
- deprecate `verify` option to `urlencoded` -- use `body-parser` npm module instead
- deprecate things with `depd` module
- use `finalhandler` for final response handling
- use `media-typer` to parse `content-type` for charset
- deps: body-parser@1.4.3
- deps: connect-timeout@1.1.1
- deps: cookie-parser@1.3.1
- deps: csurf@1.2.2
- deps: errorhandler@1.1.0
- deps: express-session@1.4.0
- deps: multiparty@3.2.9
- deps: serve-index@1.1.2
- deps: type-is@1.3.1
- deps: vhost@2.0.0
3.10.5 / 2014-06-11
===================
* deps: connect@2.19.6
- deps: body-parser@1.3.1
- deps: compression@1.0.7
- deps: debug@1.0.2
- deps: serve-index@1.1.1
- deps: serve-static@1.2.3
* deps: debug@1.0.2
* deps: send@0.4.3
- Do not throw un-catchable error on file open race condition
- Use `escape-html` for HTML escaping
- deps: debug@1.0.2
- deps: finished@1.2.2
- deps: fresh@0.2.2
3.10.4 / 2014-06-09
===================
* deps: connect@2.19.5
- fix "event emitter leak" warnings
- deps: csurf@1.2.1
- deps: debug@1.0.1
- deps: serve-static@1.2.2
- deps: type-is@1.2.1
* deps: debug@1.0.1
* deps: send@0.4.2
- fix "event emitter leak" warnings
- deps: finished@1.2.1
- deps: debug@1.0.1
3.10.3 / 2014-06-05
===================
* use `vary` module for `res.vary`
* deps: connect@2.19.4
- deps: errorhandler@1.0.2
- deps: method-override@2.0.2
- deps: serve-favicon@2.0.1
* deps: debug@1.0.0
3.10.2 / 2014-06-03
===================
* deps: connect@2.19.3
- deps: compression@1.0.6
3.10.1 / 2014-06-03
===================
* deps: connect@2.19.2
- deps: compression@1.0.4
* deps: proxy-addr@1.0.1
3.10.0 / 2014-06-02
===================
* deps: connect@2.19.1
- deprecate `methodOverride()` -- use `method-override` npm module instead
- deps: body-parser@1.3.0
- deps: method-override@2.0.1
- deps: multiparty@3.2.8
- deps: response-time@2.0.0
- deps: serve-static@1.2.1
* deps: methods@1.0.1
* deps: send@0.4.1
- Send `max-age` in `Cache-Control` in correct format
3.9.0 / 2014-05-30
==================

View File

@@ -2,7 +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/visionmedia.svg)](https://www.gittip.com/visionmedia/)
[![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');
@@ -62,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)
@@ -74,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
@@ -100,7 +103,7 @@ $ npm test
## Contributors
https://github.com/visionmedia/express/graphs/contributors
https://github.com/strongloop/express/graphs/contributors
## License

View File

@@ -335,7 +335,7 @@ function createApplicationAt(path) {
// Session support
app = app.replace('{sess}', program.sessions
? eol + 'app.use(express.cookieParser(\'your secret here\'));' + eol + 'app.use(express.session());'
? eol + 'app.use(express.session({ secret: \'your secret here\' }));'
: '');
// Template support

View File

@@ -14,9 +14,8 @@ app.set('views', __dirname + '/views');
// middleware
app.use(express.bodyParser());
app.use(express.cookieParser('shhhh, very secret'));
app.use(express.session());
app.use(express.urlencoded({ extended: false }));
app.use(express.session({ secret: 'shhhh, very secret' }));
// Session-persisted message middleware

View File

@@ -31,11 +31,10 @@ if (!module.parent) app.use(express.logger('dev'));
app.use(express.static(__dirname + '/public'));
// session support
app.use(express.cookieParser('some secret here'));
app.use(express.session());
app.use(express.session({ secret: 'some secret here' }));
// parse request bodies (req.body)
app.use(express.bodyParser());
app.use(express.urlencoded({ extended: true }));
// support _method (PUT in forms etc)
app.use(express.methodOverride());

View File

@@ -9,13 +9,8 @@ var app = express();
app.use(express.logger('dev'));
// Required by session() middleware
// pass the secret for signed cookies
// (required by session())
app.use(express.cookieParser('keyboard cat'));
// Populates req.session
app.use(express.session());
app.use(express.session({ secret: 'keyboard cat' }));
app.get('/', function(req, res){
var body = '';

View File

@@ -10,13 +10,8 @@ var app = express();
app.use(express.logger('dev'));
// Required by session() middleware
// pass the secret for signed cookies
// (required by session())
app.use(express.cookieParser('keyboard cat'));
// Populates req.session
app.use(express.session({ store: new RedisStore }));
app.use(express.session({ store: new RedisStore, secret: 'keyboard cat' }));
app.get('/', function(req, res){
var body = '';

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

@@ -12,8 +12,8 @@ var connect = require('connect')
, compileTrust = require('./utils').compileTrust
, View = require('./view')
, utils = connect.utils
, deprecate = require('./utils').deprecate
, http = require('http');
var deprecate = require('depd')('express');
/**
* Application prototype.
@@ -48,10 +48,12 @@ app.defaultConfiguration = function(){
// default settings
this.enable('x-powered-by');
this.set('etag', 'weak');
this.set('env', process.env.NODE_ENV || 'development');
var env = process.env.NODE_ENV || 'development';
this.set('env', env);
this.set('subdomain offset', 2);
this.set('trust proxy', false);
debug('booting in %s mode', this.get('env'));
debug('booting in %s mode', env);
// implicit middleware
this.use(connect.query());
@@ -86,13 +88,13 @@ app.defaultConfiguration = function(){
this.set('views', process.cwd() + '/views');
this.set('jsonp callback name', 'callback');
this.configure('development', function(){
if (env === 'development') {
this.set('json spaces', 2);
});
}
this.configure('production', function(){
if (env === 'production') {
this.enable('view cache');
});
}
};
/**
@@ -411,6 +413,9 @@ app.configure = function(env, fn){
return this;
};
app.configure = deprecate.function(app.configure,
'app.configure: Check app.get(\'env\') in an if statement');
/**
* Delegate `.VERB(...)` calls to `router.VERB(...)`.
*/
@@ -448,7 +453,7 @@ app.all = function(path){
// del -> delete alias
app.del = deprecate(app.delete, 'app.del: Use app.delete instead');
app.del = deprecate.function(app.delete, 'app.del: Use app.delete instead');
/**
* Render the given view `name` name with `options`

View File

@@ -2,6 +2,7 @@
* Module dependencies.
*/
var deprecate = require('depd')('express');
var merge = require('merge-descriptors');
var connect = require('connect')
, proto = require('./application')
@@ -9,7 +10,6 @@ var connect = require('connect')
, Router = require('./router')
, req = require('./request')
, res = require('./response')
, deprecate = require('./utils').deprecate
, utils = connect.utils;
/**
@@ -51,7 +51,7 @@ merge(exports, connect.middleware);
* Deprecated createServer().
*/
exports.createServer = deprecate(createApplication,
exports.createServer = deprecate.function(createApplication,
'createServer() is deprecated\n' +
'express applications no longer inherit from http.Server\n' +
'please use:\n' +

View File

@@ -3,6 +3,8 @@
* Module dependencies.
*/
var auth = require('basic-auth');
var deprecate = require('depd')('express');
var http = require('http')
, utils = require('./utils')
, connect = require('connect')
@@ -11,6 +13,7 @@ var http = require('http')
, parse = require('parseurl')
, proxyaddr = require('proxy-addr')
, mime = connect.mime;
var isIP = require('net').isIP;
/**
* Request prototype.
@@ -339,7 +342,9 @@ req.is = function(type){
* Return the protocol string "http" or "https"
* when requested with TLS. When the "trust proxy"
* setting trusts the socket address, the
* "X-Forwarded-Proto" header field will be trusted.
* "X-Forwarded-Proto" header field will be trusted
* and used if present.
*
* If you're running behind a reverse proxy that
* supplies https for you this may be enabled.
*
@@ -348,17 +353,18 @@ req.is = function(type){
*/
req.__defineGetter__('protocol', function(){
var proto = this.connection.encrypted
? 'https'
: 'http';
var trust = this.app.get('trust proxy fn');
if (!trust(this.connection.remoteAddress)) {
return this.connection.encrypted
? 'https'
: 'http';
return proto;
}
// Note: X-Forwarded-Proto is normally only ever a
// single value, but this is to be safe.
var proto = this.get('X-Forwarded-Proto') || 'http';
proto = this.get('X-Forwarded-Proto') || proto;
return proto.split(/\s*,\s*/)[0];
});
@@ -422,20 +428,13 @@ req.__defineGetter__('ips', function(){
*/
req.__defineGetter__('auth', function(){
// missing
var auth = this.get('Authorization');
if (!auth) return;
// malformed
var parts = auth.split(' ');
if ('basic' != parts[0].toLowerCase()) return;
if (!parts[1]) return;
auth = parts[1];
deprecate('req.auth: Use basic-auth npm module instead');
// credentials
auth = new Buffer(auth, 'base64').toString().match(/^([^:]*):(.*)$/);
if (!auth) return;
return { username: auth[1], password: auth[2] };
var creds = auth(this);
if (!creds) return;
return { username: creds.name, password: creds.pass };
});
/**
@@ -454,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);
});
/**

View File

@@ -2,6 +2,10 @@
* Module dependencies.
*/
var deprecate = require('depd')('express');
var escapeHtml = require('escape-html');
var parseUrl = require('parseurl');
var vary = require('vary');
var http = require('http')
, path = require('path')
, connect = require('connect')
@@ -10,7 +14,6 @@ var http = require('http')
, normalizeType = require('./utils').normalizeType
, normalizeTypes = require('./utils').normalizeTypes
, setCharset = require('./utils').setCharset
, deprecate = require('./utils').deprecate
, statusCodes = http.STATUS_CODES
, cookie = require('cookie')
, send = require('send')
@@ -101,13 +104,15 @@ res.send = function(body){
}
}
// disambiguate res.send(status) and res.send(status, num)
if (typeof body === 'number' && arguments.length === 1) {
// res.send(status) will set status message as text string
this.get('Content-Type') || this.type('txt');
this.statusCode = body;
body = http.STATUS_CODES[body];
}
switch (typeof body) {
// response status
case 'number':
this.get('Content-Type') || this.type('txt');
this.statusCode = body;
body = http.STATUS_CODES[body];
break;
// string defaulting to html
case 'string':
if (!this.get('Content-Type')) {
@@ -116,6 +121,7 @@ res.send = function(body){
}
break;
case 'boolean':
case 'number':
case 'object':
if (null == body) {
body = '';
@@ -194,9 +200,11 @@ res.json = function(obj){
// res.json(body, status) backwards compat
if ('number' == typeof arguments[1]) {
this.statusCode = arguments[1];
return 'number' === typeof obj
? jsonNumDeprecated.call(this, obj)
: jsonDeprecated.call(this, obj);
if (typeof obj === 'number') {
deprecate('res.json(obj, status): Use res.json(status, obj) instead');
} else {
deprecate('res.json(num, status): Use res.status(status).json(num) instead');
}
} else {
this.statusCode = obj;
obj = arguments[1];
@@ -216,12 +224,6 @@ res.json = function(obj){
return this.send(body);
};
var jsonDeprecated = deprecate(res.json,
'res.json(obj, status): Use res.json(status, obj) instead');
var jsonNumDeprecated = deprecate(res.json,
'res.json(num, status): Use res.status(status).json(num) instead');
/**
* Send JSON response with JSONP callback support.
*
@@ -244,9 +246,11 @@ res.jsonp = function(obj){
// res.json(body, status) backwards compat
if ('number' == typeof arguments[1]) {
this.statusCode = arguments[1];
return 'number' === typeof obj
? jsonpNumDeprecated.call(this, obj)
: jsonpDeprecated.call(this, obj);
if (typeof obj === 'number') {
deprecate('res.jsonp(obj, status): Use res.jsonp(status, obj) instead');
} else {
deprecate('res.jsonp(num, status): Use res.status(status).jsonp(num) instead');
}
} else {
this.statusCode = obj;
obj = arguments[1];
@@ -257,14 +261,15 @@ res.jsonp = function(obj){
var app = this.app;
var replacer = app.get('json replacer');
var spaces = app.get('json spaces');
var body = JSON.stringify(obj, replacer, spaces)
.replace(/\u2028/g, '\\u2028')
.replace(/\u2029/g, '\\u2029');
var body = JSON.stringify(obj, replacer, spaces);
var callback = this.req.query[app.get('jsonp callback name')];
// content-type
this.charset = this.charset || 'utf-8';
this.get('Content-Type') || this.set('Content-Type', 'application/json');
if (!this.get('Content-Type')) {
this.charset = 'utf-8';
this.set('X-Content-Type-Options', 'nosniff');
this.set('Content-Type', 'application/json');
}
// fixup callback
if (Array.isArray(callback)) {
@@ -272,21 +277,27 @@ res.jsonp = function(obj){
}
// jsonp
if (callback && 'string' === typeof callback) {
if (typeof callback === 'string' && callback.length !== 0) {
this.charset = 'utf-8';
this.set('X-Content-Type-Options', 'nosniff');
this.set('Content-Type', 'text/javascript');
var cb = callback.replace(/[^\[\]\w$.]/g, '');
body = 'typeof ' + cb + ' === \'function\' && ' + cb + '(' + body + ');';
// restrict callback charset
callback = callback.replace(/[^\[\]\w$.]/g, '');
// replace chars not allowed in JavaScript that are in JSON
body = body
.replace(/\u2028/g, '\\u2028')
.replace(/\u2029/g, '\\u2029');
// the /**/ is a specific security mitigation for "Rosetta Flash JSONP abuse"
// the typeof check is just to reduce client error noise
body = '/**/ typeof ' + callback + ' === \'function\' && ' + callback + '(' + body + ');';
}
return this.send(body);
};
var jsonpDeprecated = deprecate(res.json,
'res.jsonp(obj, status): Use res.jsonp(status, obj) instead');
var jsonpNumDeprecated = deprecate(res.json,
'res.jsonp(num, status): Use res.status(status).jsonp(num) instead');
/**
* Transfer the file at the given `path`.
*
@@ -298,8 +309,11 @@ var jsonpNumDeprecated = deprecate(res.json,
*
* Options:
*
* - `maxAge` defaulting to 0
* - `root` root directory for relative filenames
* - `maxAge` defaulting to 0
* - `root` root directory for relative filenames
* - `dotfiles` serve dotfiles, defaulting to false; can be `"allow"` to send them
*
* Other options are passed along to `send`.
*
* Examples:
*
@@ -375,9 +389,7 @@ res.sendfile = function(path, options, fn){
}
// transfer
var file = send(req, path);
if (options.root) file.root(options.root);
file.maxage(options.maxAge || 0);
var file = send(req, path, options);
file.on('error', error);
file.on('directory', next);
file.on('stream', stream);
@@ -682,7 +694,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
@@ -710,11 +722,8 @@ res.location = function(url){
* res.redirect('/foo/bar');
* res.redirect('http://example.com');
* res.redirect(301, 'http://example.com');
* res.redirect('http://example.com', 301);
* res.redirect('../login'); // /blog/post/1 -> /blog/login
*
* @param {String} url
* @param {Number} code
* @api public
*/
@@ -729,6 +738,7 @@ res.redirect = function(url){
status = url;
url = arguments[1];
} else {
deprecate('res.redirect(ur, status): Use res.redirect(status, url) instead');
status = arguments[1];
}
}
@@ -744,7 +754,7 @@ res.redirect = function(url){
},
html: function(){
var u = utils.escape(url);
var u = escapeHtml(url);
body = '<p>' + statusCodes[status] + '. Redirecting to <a href="' + u + '">' + u + '</a></p>';
},
@@ -769,31 +779,12 @@ res.redirect = function(url){
*/
res.vary = function(field){
var self = this;
// nothing
// checks for back-compat
if (!field) return this;
if (Array.isArray(field) && !field.length) return this;
// array
if (Array.isArray(field)) {
field.forEach(function(field){
self.vary(field);
});
return;
}
vary(this, field);
var vary = this.get('Vary');
// append
if (vary) {
vary = vary.split(/ *, */);
if (!~vary.indexOf(field)) vary.push(field);
this.set('Vary', vary.join(', '));
return this;
}
// set
this.set('Vary', field);
return this;
};

View File

@@ -3,11 +3,11 @@
* Module dependencies.
*/
var crc = require('crc').crc32;
var mime = require('connect').mime
, deprecate = require('util').deprecate
, proxyaddr = require('proxy-addr')
, crc32 = require('buffer-crc32')
, crypto = require('crypto');
var typer = require('media-typer');
/**
* toString ref.
@@ -15,35 +15,6 @@ var mime = require('connect').mime
var toString = {}.toString;
/**
* Simple detection of charset parameter in content-type
*/
var charsetRegExp = /;\s*charset\s*=/;
/**
* Deprecate function, like core `util.deprecate`,
* but with NODE_ENV and color support.
*
* @param {Function} fn
* @param {String} msg
* @return {Function}
* @api private
*/
exports.deprecate = function(fn, msg){
if (process.env.NODE_ENV === 'test') return fn;
// prepend module name
msg = 'express: ' + msg;
if (process.stderr.isTTY) {
// colorize
msg = '\x1b[31;1m' + msg + '\x1b[0m';
}
return deprecate(fn, msg);
};
/**
* Return strong ETag for `body`.
*
@@ -85,7 +56,7 @@ exports.wetag = function wetag(body, encoding){
? body
: new Buffer(body, encoding)
var len = buf.length
return 'W/"' + len.toString(16) + '-' + crc32.unsigned(buf) + '"'
return 'W/"' + len.toString(16) + '-' + crc(buf) + '"'
};
/**
@@ -322,22 +293,6 @@ function acceptParams(str, index) {
return ret;
}
/**
* Escape special characters in the given string of html.
*
* @param {String} html
* @return {String}
* @api private
*/
exports.escape = function(html) {
return String(html)
.replace(/&/g, '&amp;')
.replace(/"/g, '&quot;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;');
};
/**
* Normalize the given path string,
* returning a regular expression.
@@ -452,21 +407,12 @@ exports.compileTrust = function(val) {
exports.setCharset = function(type, charset){
if (!type || !charset) return type;
var exists = charsetRegExp.test(type);
// parse type
var parsed = typer.parse(type);
// removing existing charset
if (exists) {
var parts = type.split(';');
// set charset
parsed.parameters.charset = charset;
for (var i = 1; i < parts.length; i++) {
if (charsetRegExp.test(';' + parts[i])) {
parts.splice(i, 1);
break;
}
}
type = parts.join(';');
}
return type + '; charset=' + charset;
// format type
return typer.format(parsed);
};

View File

@@ -1,37 +1,15 @@
{
"name": "express",
"description": "Sinatra inspired web development framework",
"version": "3.9.0",
"version": "3.17.3",
"author": "TJ Holowaychuk <tj@vision-media.ca>",
"contributors": [
{
"name": "TJ Holowaychuk",
"email": "tj@vision-media.ca"
},
{
"name": "Aaron Heckmann",
"email": "aaron.heckmann+github@gmail.com"
},
{
"name": "Ciaran Jessup",
"email": "ciaranj@gmail.com"
},
{
"name": "Douglas Christopher Wilson",
"email": "doug@somethingdoug.com"
},
{
"name": "Guillermo Rauch",
"email": "rauchg@gmail.com"
},
{
"name": "Jonathan Ong",
"email": "me@jongleberry.com"
},
{
"name": "Roman Shtylman",
"email": "shtylman+expressjs@gmail.com"
}
"Aaron Heckmann <aaron.heckmann+github@gmail.com>",
"Ciaran Jessup <ciaranj@gmail.com>",
"Douglas Christopher Wilson <doug@somethingdoug.com>",
"Guillermo Rauch <rauchg@gmail.com>",
"Jonathan Ong <me@jongleberry.com>",
"Roman Shtylman <shtylman+expressjs@gmail.com"
],
"keywords": [
"express",
@@ -44,33 +22,39 @@
"app",
"api"
],
"repository": "git://github.com/visionmedia/express",
"repository": "strongloop/express",
"license": "MIT",
"homepage": "http://expressjs.com/",
"dependencies": {
"buffer-crc32": "0.2.1",
"connect": "2.18.0",
"basic-auth": "1.0.0",
"connect": "2.26.1",
"commander": "1.3.2",
"methods": "1.0.0",
"cookie-signature": "1.0.5",
"crc": "3.0.0",
"debug": "~2.0.0",
"depd": "0.4.5",
"escape-html": "1.0.1",
"fresh": "0.2.4",
"media-typer": "0.3.0",
"methods": "1.1.0",
"mkdirp": "0.5.0",
"parseurl": "1.0.1",
"proxy-addr": "1.0.0",
"range-parser": "1.0.0",
"send": "0.4.0",
"parseurl": "~1.3.0",
"proxy-addr": "~1.0.2",
"range-parser": "~1.0.2",
"send": "0.9.2",
"vary": "~1.0.0",
"cookie": "0.1.2",
"fresh": "0.2.2",
"cookie-signature": "1.0.3",
"merge-descriptors": "0.0.2",
"debug": ">= 0.8.0 < 1"
"merge-descriptors": "0.0.2"
},
"devDependencies": {
"istanbul": "0.2.10",
"mocha": "~1.20.0",
"connect-redis": "~1.5.0",
"istanbul": "0.3.2",
"mocha": "~1.21.4",
"should": "~4.0.0",
"ejs": "~1.0.0",
"jade": "~1.3.1",
"jade": "~1.6.0",
"hjs": "~0.0.6",
"marked": "0.3.2",
"connect-redis": "~1.4.5",
"supertest": "~0.13.0"
},
"engines": {
@@ -83,6 +67,7 @@
"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

@@ -33,6 +33,7 @@ describe('mvc', function(){
it('should update the pet', function(done){
request(app)
.put('/pet/3')
.set('Content-Type', 'application/x-www-form-urlencoded')
.send({ pet: { name: 'Boots' } })
.end(function(err, res){
if (err) return done(err);
@@ -95,6 +96,7 @@ describe('mvc', function(){
it('should update the user', function(done){
request(app)
.put('/user/1')
.set('Content-Type', 'application/x-www-form-urlencoded')
.send({ user: { name: 'Tobo' }})
.end(function(err, res){
if (err) return done(err);
@@ -109,6 +111,7 @@ describe('mvc', function(){
it('should create a pet for user', function(done){
request(app)
.post('/user/2/pet')
.set('Content-Type', 'application/x-www-form-urlencoded')
.send({ pet: { name: 'Snickers' }})
.expect('Location', '/user/2')
.expect(302, function(err, res){

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

@@ -34,6 +34,8 @@ describe('HEAD', function(){
.get('/tobi')
.expect(200, function(err, res){
if (err) return done(err);
delete headers.date;
delete res.headers.date;
assert.deepEqual(res.headers, headers);
done();
});

1
test/fixtures/.name vendored Normal file
View File

@@ -0,0 +1 @@
tobi

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

@@ -0,0 +1 @@
<b>index</b>

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,6 +32,21 @@ describe('req', function(){
.expect('https', done);
})
it('should default to the socket addr if X-Forwarded-Proto not present', function(done){
var app = express();
app.enable('trust proxy');
app.use(function(req, res){
req.connection.encrypted = true;
res.end(req.protocol);
});
request(app)
.get('/')
.expect('https', done);
})
it('should ignore X-Forwarded-Proto if socket addr not trusted', function(done){
var app = express();

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

@@ -14,11 +14,8 @@ describe('res', function(){
request(app)
.get('/?callback=something')
.end(function(err, res){
res.headers.should.have.property('content-type', 'text/javascript; charset=utf-8');
res.text.should.equal('typeof something === \'function\' && something({"count":1});');
done();
})
.expect('Content-Type', 'text/javascript; charset=utf-8')
.expect(200, /something\(\{"count":1\}\);/, done);
})
it('should use first callback parameter with jsonp', function(done){
@@ -29,12 +26,9 @@ describe('res', function(){
});
request(app)
.get('/?callback=something&callback=somethingelse')
.end(function(err, res){
res.headers.should.have.property('content-type', 'text/javascript; charset=utf-8');
res.text.should.equal('typeof something === \'function\' && something({"count":1});');
done();
})
.get('/?callback=something&callback=somethingelse')
.expect('Content-Type', 'text/javascript; charset=utf-8')
.expect(200, /something\(\{"count":1\}\);/, done);
})
it('should ignore object callback parameter with jsonp', function(done){
@@ -61,11 +55,8 @@ describe('res', function(){
request(app)
.get('/?clb=something')
.end(function(err, res){
res.headers.should.have.property('content-type', 'text/javascript; charset=utf-8');
res.text.should.equal('typeof something === \'function\' && something({"count":1});');
done();
})
.expect('Content-Type', 'text/javascript; charset=utf-8')
.expect(200, /something\(\{"count":1\}\);/, done);
})
it('should allow []', function(done){
@@ -77,11 +68,8 @@ describe('res', function(){
request(app)
.get('/?callback=callbacks[123]')
.end(function(err, res){
res.headers.should.have.property('content-type', 'text/javascript; charset=utf-8');
res.text.should.equal('typeof callbacks[123] === \'function\' && callbacks[123]({"count":1});');
done();
})
.expect('Content-Type', 'text/javascript; charset=utf-8')
.expect(200, /callbacks\[123\]\(\{"count":1\}\);/, done);
})
it('should disallow arbitrary js', function(done){
@@ -93,11 +81,8 @@ describe('res', function(){
request(app)
.get('/?callback=foo;bar()')
.end(function(err, res){
res.headers.should.have.property('content-type', 'text/javascript; charset=utf-8');
res.text.should.equal('typeof foobar === \'function\' && foobar({});');
done();
})
.expect('Content-Type', 'text/javascript; charset=utf-8')
.expect(200, /foobar\(\{\}\);/, done);
})
it('should escape utf whitespace', function(done){
@@ -109,13 +94,37 @@ describe('res', function(){
request(app)
.get('/?callback=foo')
.end(function(err, res){
res.headers.should.have.property('content-type', 'text/javascript; charset=utf-8');
res.text.should.equal('typeof foo === \'function\' && foo({"str":"\\u2028 \\u2029 woot"});');
done();
});
.expect('Content-Type', 'text/javascript; charset=utf-8')
.expect(200, /foo\(\{"str":"\\u2028 \\u2029 woot"\}\);/, done);
});
it('should not escape utf whitespace for json fallback', function(done){
var app = express();
app.use(function(req, res){
res.jsonp({ str: '\u2028 \u2029 woot' });
});
request(app)
.get('/')
.expect('Content-Type', 'application/json; charset=utf-8')
.expect(200, '{"str":"\u2028 \u2029 woot"}', done);
});
it('should include security header and prologue', function (done) {
var app = express();
app.use(function(req, res){
res.jsonp({ count: 1 });
});
request(app)
.get('/?callback=something')
.expect('Content-Type', 'text/javascript; charset=utf-8')
.expect('X-Content-Type-Options', 'nosniff')
.expect(200, /^\/\*\*\//, done);
})
it('should not override previous Content-Types with no callback', function(done){
var app = express();
@@ -127,7 +136,11 @@ describe('res', function(){
request(app)
.get('/')
.expect('Content-Type', 'application/vnd.example+json; charset=utf-8')
.expect(200, '{"hello":"world"}', done);
.expect(200, '{"hello":"world"}', function (err, res) {
if (err) return done(err);
res.headers.should.not.have.property('x-content-type-options');
done();
});
})
it('should override previous Content-Types with callback', function(done){
@@ -141,6 +154,7 @@ describe('res', function(){
request(app)
.get('/?callback=cb')
.expect('Content-Type', 'text/javascript; charset=utf-8')
.expect('X-Content-Type-Options', 'nosniff')
.expect(200, /cb\(\{"hello":"world"\}\);$/, done);
})

View File

@@ -77,6 +77,21 @@ describe('res', function(){
})
})
describe('.send(code, number)', function(){
it('should send number as json', function(done){
var app = express();
app.use(function(req, res){
res.send(200, 0.123);
});
request(app)
.get('/')
.expect('Content-Type', 'application/json; charset=utf-8')
.expect(200, '0.123', done);
})
})
describe('.send(String)', function(){
it('should send as html', function(done){
var app = express();

View File

@@ -106,6 +106,54 @@ describe('res', function(){
})
describe('.sendfile(path)', function(){
it('should not serve dotfiles', function(done){
var app = express();
app.use(function(req, res){
res.sendfile('test/fixtures/.name');
});
request(app)
.get('/')
.expect(404, done);
})
it('should accept dotfiles option', function(done){
var app = express();
app.use(function(req, res){
res.sendfile('test/fixtures/.name', { dotfiles: 'allow' });
});
request(app)
.get('/')
.expect(200, 'tobi', done);
})
it('should transfer a file', function (done) {
var app = express();
app.use(function (req, res) {
res.sendfile('test/fixtures/name.txt');
});
request(app)
.get('/')
.expect(200, 'tobi', done);
});
it('should transfer a directory index file', function (done) {
var app = express();
app.use(function (req, res) {
res.sendfile('test/fixtures/blog/');
});
request(app)
.get('/')
.expect(200, '<b>index</b>', done);
});
describe('with an absolute path', function(){
it('should transfer the file', function(done){
var app = express();

View File

@@ -1,2 +1,3 @@
process.env.NODE_ENV = 'test';
process.env.NO_DEPRECATION = 'connect,express';

View File

@@ -2,28 +2,6 @@
var utils = require('../lib/utils')
, assert = require('assert');
describe('utils.deprecate(fn, msg)', function(){
var env
before(function(){
env = process.env.NODE_ENV
})
after(function(){
process.env.NODE_ENV = env
})
it('should pass-through fn in test environment', function(){
var fn = function(){}
process.env.NODE_ENV = 'test'
utils.deprecate(fn).should.equal(fn)
})
it('should return new fn in other environment', function(){
var fn = function(){}
process.env.NODE_ENV = ''
utils.deprecate(fn).should.not.equal(fn)
})
})
describe('utils.etag(body, encoding)', function(){
it('should support strings', function(){
utils.etag('express!')
@@ -94,13 +72,6 @@ describe('utils.flatten(arr)', function(){
})
})
describe('utils.escape(html)', function(){
it('should escape html entities', function(){
utils.escape('<script>foo & "bar"')
.should.equal('&lt;script&gt;foo &amp; &quot;bar&quot;')
})
})
describe('utils.parseParams(str)', function(){
it('should default quality to 1', function(){
utils.parseParams('text/html')