Comparar commits
46 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| d853c833f0 | |||
| 03a796c460 | |||
| 75e47f2883 | |||
| a4b2e48dfe | |||
| 57cda1578d | |||
| 6b1d7a94ff | |||
| 49abd7bec1 | |||
| 0ebebd80fe | |||
| d157d47c6e | |||
| e3ac2c5b02 | |||
| cd54faa4af | |||
| 5beb1c4e30 | |||
| 4031aaa591 | |||
| ba00e23630 | |||
| 8beb1f21ef | |||
| fa8eec449b | |||
| ab75fa048e | |||
| bb29da5980 | |||
| a4d7b75129 | |||
| 0fdceb3de3 | |||
| 480d0064e1 | |||
| 17bf04d1ef | |||
| 3ab30210a2 | |||
| 14fcfdee7e | |||
| d4e56c1fa2 | |||
| 39ee6f8e79 | |||
| 8d21f1e45c | |||
| 618484a4fe | |||
| 64a234958a | |||
| e4907ce8e8 | |||
| 33eaa8329c | |||
| 3c4fd57e51 | |||
| a1e42ac33f | |||
| ce7d7bfd8d | |||
| 9bd86cdddc | |||
| 0117464ac2 | |||
| 6f6eec7d8d | |||
| a4e93c0fb8 | |||
| e2ad0d3d6e | |||
| 763be5e631 | |||
| c8526932f3 | |||
| 5cf29a3d29 | |||
| 18a3cc03ee | |||
| ea5e254c7d | |||
| 060653bd4c | |||
| c70db96b06 |
+2
-1
@@ -1,3 +1,4 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 0.6
|
||||
- 0.6
|
||||
- 0.8
|
||||
|
||||
+119
-84
@@ -1,23 +1,58 @@
|
||||
|
||||
3.0.3 / 2012-11-13
|
||||
3.1.0 / 2013-01-25
|
||||
==================
|
||||
|
||||
* add support for leading "." in "view engine" setting
|
||||
* add array support to `res.set()`
|
||||
* add node 0.8.x to travis.yml
|
||||
* add "subdomain offset" setting for tweaking `req.subdomains`
|
||||
* add `res.location(url)` implementing `res.redirect()`-like setting of Location
|
||||
* use app.get() for x-powered-by setting for inheritance
|
||||
* fix colons in passwords for `req.auth`
|
||||
|
||||
3.0.6 / 2013-01-04
|
||||
==================
|
||||
|
||||
* add http verb methods to Router
|
||||
* update connect
|
||||
* fix mangling of the `res.cookie()` options object
|
||||
* fix jsonp whitespace escape. Closes #1132
|
||||
|
||||
3.0.5 / 2012-12-19
|
||||
==================
|
||||
|
||||
* add throwing when a non-function is passed to a route
|
||||
* fix: explicitly remove Transfer-Encoding header from 204 and 304 responses
|
||||
* revert "add 'etag' option"
|
||||
|
||||
3.0.4 / 2012-12-05
|
||||
==================
|
||||
|
||||
* add 'etag' option to disable `res.send()` Etags
|
||||
* add escaping of urls in text/plain in `res.redirect()`
|
||||
for old browsers interpreting as html
|
||||
* change crc32 module for a more liberal license
|
||||
* update connect
|
||||
|
||||
3.0.3 / 2012-11-13
|
||||
==================
|
||||
|
||||
* update connect
|
||||
* update cookie module
|
||||
* fix cookie max-age
|
||||
|
||||
3.0.2 / 2012-11-08
|
||||
3.0.2 / 2012-11-08
|
||||
==================
|
||||
|
||||
* add OPTIONS to cors example. Closes #1398
|
||||
* fix route chaining regression. Closes #1397
|
||||
|
||||
3.0.1 / 2012-11-01
|
||||
3.0.1 / 2012-11-01
|
||||
==================
|
||||
|
||||
* update connect
|
||||
|
||||
3.0.0 / 2012-10-23
|
||||
3.0.0 / 2012-10-23
|
||||
==================
|
||||
|
||||
* add `make clean`
|
||||
@@ -32,7 +67,7 @@
|
||||
* fix view-locals example. Closes #1370
|
||||
* fix route-separation example
|
||||
|
||||
3.0.0rc5 / 2012-09-18
|
||||
3.0.0rc5 / 2012-09-18
|
||||
==================
|
||||
|
||||
* update connect
|
||||
@@ -41,7 +76,7 @@
|
||||
* add "x-powered-by" setting (`app.disable('x-powered-by')`)
|
||||
* add "application/octet-stream" redirect Accept test case. Closes #1317
|
||||
|
||||
3.0.0rc4 / 2012-08-30
|
||||
3.0.0rc4 / 2012-08-30
|
||||
==================
|
||||
|
||||
* add `res.jsonp()`. Closes #1307
|
||||
@@ -54,14 +89,14 @@
|
||||
* fix jsonp callback char restrictions
|
||||
* remove old OPTIONS default response
|
||||
|
||||
3.0.0rc3 / 2012-08-13
|
||||
3.0.0rc3 / 2012-08-13
|
||||
==================
|
||||
|
||||
* update connect dep
|
||||
* fix signed cookies to work with `connect.cookieParser()` ("s:" prefix was missing) [tnydwrds]
|
||||
* fix `res.render()` clobbering of "locals"
|
||||
|
||||
3.0.0rc2 / 2012-08-03
|
||||
3.0.0rc2 / 2012-08-03
|
||||
==================
|
||||
|
||||
* add CORS example
|
||||
@@ -70,7 +105,7 @@
|
||||
* fix: escape `res.redirect()` link
|
||||
* fix vhost example
|
||||
|
||||
3.0.0rc1 / 2012-07-24
|
||||
3.0.0rc1 / 2012-07-24
|
||||
==================
|
||||
|
||||
* add more examples to view-locals
|
||||
@@ -81,12 +116,12 @@
|
||||
* fix `express(1)` -h flag, use -H for hogan. Closes #1245
|
||||
* fix `res.sendfile()` socket error handling regression
|
||||
|
||||
3.0.0beta7 / 2012-07-16
|
||||
3.0.0beta7 / 2012-07-16
|
||||
==================
|
||||
|
||||
* update connect dep for `send()` root normalization regression
|
||||
|
||||
3.0.0beta6 / 2012-07-13
|
||||
3.0.0beta6 / 2012-07-13
|
||||
==================
|
||||
|
||||
* add `err.view` property for view errors. Closes #1226
|
||||
@@ -96,7 +131,7 @@
|
||||
* change `res.send` to use "response-send" module
|
||||
* remove `app.locals.use` and `res.locals.use`, use regular middleware
|
||||
|
||||
3.0.0beta5 / 2012-07-03
|
||||
3.0.0beta5 / 2012-07-03
|
||||
==================
|
||||
|
||||
* add "make check" support
|
||||
@@ -107,7 +142,7 @@
|
||||
* update auth example to utilize cores pbkdf2
|
||||
* updated tests to use "supertest"
|
||||
|
||||
3.0.0beta4 / 2012-06-25
|
||||
3.0.0beta4 / 2012-06-25
|
||||
==================
|
||||
|
||||
* Added `req.auth`
|
||||
@@ -119,7 +154,7 @@
|
||||
* Revert "Added + support to the router"
|
||||
* Fixed `res.send()` freshness check, respect res.statusCode
|
||||
|
||||
3.0.0beta3 / 2012-06-15
|
||||
3.0.0beta3 / 2012-06-15
|
||||
==================
|
||||
|
||||
* Added hogan `--hjs` to express(1) [nullfirm]
|
||||
@@ -128,7 +163,7 @@
|
||||
* Changed: `res.send()` always checks freshness
|
||||
* Fixed: expose connects mime module. Cloases #1165
|
||||
|
||||
3.0.0beta2 / 2012-06-06
|
||||
3.0.0beta2 / 2012-06-06
|
||||
==================
|
||||
|
||||
* Added `+` support to the router
|
||||
@@ -136,13 +171,13 @@
|
||||
* Changed `req.param()` to check route first
|
||||
* Update connect dep
|
||||
|
||||
3.0.0beta1 / 2012-06-01
|
||||
3.0.0beta1 / 2012-06-01
|
||||
==================
|
||||
|
||||
* Added `res.format()` callback to override default 406 behaviour
|
||||
* Fixed `res.redirect()` 406. Closes #1154
|
||||
|
||||
3.0.0alpha5 / 2012-05-30
|
||||
3.0.0alpha5 / 2012-05-30
|
||||
==================
|
||||
|
||||
* Added `req.ip`
|
||||
@@ -151,14 +186,14 @@
|
||||
* Changed: dont reverse `req.ips`
|
||||
* Fixed "trust proxy" setting check for `req.ips`
|
||||
|
||||
3.0.0alpha4 / 2012-05-09
|
||||
3.0.0alpha4 / 2012-05-09
|
||||
==================
|
||||
|
||||
* Added: allow `[]` in jsonp callback. Closes #1128
|
||||
* Added `PORT` env var support in generated template. Closes #1118 [benatkin]
|
||||
* Updated: connect 2.2.2
|
||||
|
||||
3.0.0alpha3 / 2012-05-04
|
||||
3.0.0alpha3 / 2012-05-04
|
||||
==================
|
||||
|
||||
* Added public `app.routes`. Closes #887
|
||||
@@ -173,7 +208,7 @@
|
||||
* Changed: `make test` now runs unit / acceptance tests
|
||||
* Fixed req/res proto inheritance
|
||||
|
||||
3.0.0alpha2 / 2012-04-26
|
||||
3.0.0alpha2 / 2012-04-26
|
||||
==================
|
||||
|
||||
* Added `make benchmark` back
|
||||
@@ -189,7 +224,7 @@
|
||||
* Fixed session example. Closes #1105
|
||||
* Fixed generated express dep. Closes #1078
|
||||
|
||||
3.0.0alpha1 / 2012-04-15
|
||||
3.0.0alpha1 / 2012-04-15
|
||||
==================
|
||||
|
||||
* Added `app.locals.use(callback)`
|
||||
@@ -244,54 +279,54 @@
|
||||
* Fixed `res.sendfile()` with non-GET. Closes #723
|
||||
* Fixed express(1) public dir for windows. Closes #866
|
||||
|
||||
2.5.9/ 2012-04-02
|
||||
2.5.9/ 2012-04-02
|
||||
==================
|
||||
|
||||
* Added support for PURGE request method [pbuyle]
|
||||
* Fixed `express(1)` generated app `app.address()` before `listening` [mmalecki]
|
||||
|
||||
2.5.8 / 2012-02-08
|
||||
2.5.8 / 2012-02-08
|
||||
==================
|
||||
|
||||
* Update mkdirp dep. Closes #991
|
||||
|
||||
2.5.7 / 2012-02-06
|
||||
2.5.7 / 2012-02-06
|
||||
==================
|
||||
|
||||
* Fixed `app.all` duplicate DELETE requests [mscdex]
|
||||
|
||||
2.5.6 / 2012-01-13
|
||||
2.5.6 / 2012-01-13
|
||||
==================
|
||||
|
||||
* Updated hamljs dev dep. Closes #953
|
||||
|
||||
2.5.5 / 2012-01-08
|
||||
2.5.5 / 2012-01-08
|
||||
==================
|
||||
|
||||
* Fixed: set `filename` on cached templates [matthewleon]
|
||||
|
||||
2.5.4 / 2012-01-02
|
||||
2.5.4 / 2012-01-02
|
||||
==================
|
||||
|
||||
* Fixed `express(1)` eol on 0.4.x. Closes #947
|
||||
|
||||
2.5.3 / 2011-12-30
|
||||
2.5.3 / 2011-12-30
|
||||
==================
|
||||
|
||||
* Fixed `req.is()` when a charset is present
|
||||
|
||||
2.5.2 / 2011-12-10
|
||||
2.5.2 / 2011-12-10
|
||||
==================
|
||||
|
||||
* Fixed: express(1) LF -> CRLF for windows
|
||||
|
||||
2.5.1 / 2011-11-17
|
||||
2.5.1 / 2011-11-17
|
||||
==================
|
||||
|
||||
* Changed: updated connect to 1.8.x
|
||||
* Removed sass.js support from express(1)
|
||||
|
||||
2.5.0 / 2011-10-24
|
||||
2.5.0 / 2011-10-24
|
||||
==================
|
||||
|
||||
* Added ./routes dir for generated app by default
|
||||
@@ -300,7 +335,7 @@
|
||||
* Removed `make test-cov` since it wont work with node 0.5.x
|
||||
* Fixed express(1) public dir for windows. Closes #866
|
||||
|
||||
2.4.7 / 2011-10-05
|
||||
2.4.7 / 2011-10-05
|
||||
==================
|
||||
|
||||
* Added mkdirp to express(1). Closes #795
|
||||
@@ -311,17 +346,17 @@
|
||||
* Fixed `req.flash()`, only escape args
|
||||
* Fixed absolute path checking on windows. Closes #829 [reported by andrewpmckenzie]
|
||||
|
||||
2.4.6 / 2011-08-22
|
||||
2.4.6 / 2011-08-22
|
||||
==================
|
||||
|
||||
* Fixed multiple param callback regression. Closes #824 [reported by TroyGoode]
|
||||
|
||||
2.4.5 / 2011-08-19
|
||||
2.4.5 / 2011-08-19
|
||||
==================
|
||||
|
||||
* Added support for routes to handle errors. Closes #809
|
||||
* Added `app.routes.all()`. Closes #803
|
||||
* Added "basepath" setting to work in conjunction with reverse proxies etc.
|
||||
* Added "basepath" setting to work in conjunction with reverse proxies etc.
|
||||
* Refactored `Route` to use a single array of callbacks
|
||||
* Added support for multiple callbacks for `app.param()`. Closes #801
|
||||
Closes #805
|
||||
@@ -329,25 +364,25 @@ Closes #805
|
||||
* Dependency: `qs >= 0.3.1`
|
||||
* Fixed `res.redirect()` on windows due to `join()` usage. Closes #808
|
||||
|
||||
2.4.4 / 2011-08-05
|
||||
2.4.4 / 2011-08-05
|
||||
==================
|
||||
|
||||
* Fixed `res.header()` intention of a set, even when `undefined`
|
||||
* Fixed `*`, value no longer required
|
||||
* Fixed `res.send(204)` support. Closes #771
|
||||
|
||||
2.4.3 / 2011-07-14
|
||||
2.4.3 / 2011-07-14
|
||||
==================
|
||||
|
||||
* Added docs for `status` option special-case. Closes #739
|
||||
* Fixed `options.filename`, exposing the view path to template engines
|
||||
|
||||
2.4.2. / 2011-07-06
|
||||
2.4.2. / 2011-07-06
|
||||
==================
|
||||
|
||||
* Revert "removed jsonp stripping" for XSS
|
||||
|
||||
2.4.1 / 2011-07-06
|
||||
2.4.1 / 2011-07-06
|
||||
==================
|
||||
|
||||
* Added `res.json()` JSONP support. Closes #737
|
||||
@@ -359,14 +394,14 @@ Closes #805
|
||||
* Changed; default cookie path to "home" setting. Closes #731
|
||||
* Removed _pids/logs_ creation from express(1)
|
||||
|
||||
2.4.0 / 2011-06-28
|
||||
2.4.0 / 2011-06-28
|
||||
==================
|
||||
|
||||
* Added chainable `res.status(code)`
|
||||
* Added `res.json()`, an explicit version of `res.send(obj)`
|
||||
* Added simple web-service example
|
||||
|
||||
2.3.12 / 2011-06-22
|
||||
2.3.12 / 2011-06-22
|
||||
==================
|
||||
|
||||
* \#express is now on freenode! come join!
|
||||
@@ -378,7 +413,7 @@ Closes #805
|
||||
* Fixed view layout bug. Closes #720
|
||||
* Fixed; ignore body on 304. Closes #701
|
||||
|
||||
2.3.11 / 2011-06-04
|
||||
2.3.11 / 2011-06-04
|
||||
==================
|
||||
|
||||
* Added `npm test`
|
||||
@@ -386,14 +421,14 @@ Closes #805
|
||||
* Fixed; `express(1)` adds express as a dep
|
||||
* Fixed; prune on `prepublish`
|
||||
|
||||
2.3.10 / 2011-05-27
|
||||
2.3.10 / 2011-05-27
|
||||
==================
|
||||
|
||||
* Added `req.route`, exposing the current route
|
||||
* Added _package.json_ generation support to `express(1)`
|
||||
* Fixed call to `app.param()` function for optional params. Closes #682
|
||||
|
||||
2.3.9 / 2011-05-25
|
||||
2.3.9 / 2011-05-25
|
||||
==================
|
||||
|
||||
* Fixed bug-ish with `../' in `res.partial()` calls
|
||||
@@ -412,7 +447,7 @@ Closes #805
|
||||
* Removed module.parent check from express(1) generated app. Closes #670
|
||||
* Refactored router. Closes #639
|
||||
|
||||
2.3.6 / 2011-05-20
|
||||
2.3.6 / 2011-05-20
|
||||
==================
|
||||
|
||||
* Changed; using devDependencies instead of git submodules
|
||||
@@ -420,30 +455,30 @@ Closes #805
|
||||
* Fixed markdown example
|
||||
* Fixed view caching, should not be enabled in development
|
||||
|
||||
2.3.5 / 2011-05-20
|
||||
2.3.5 / 2011-05-20
|
||||
==================
|
||||
|
||||
* Added export `.view` as alias for `.View`
|
||||
|
||||
2.3.4 / 2011-05-08
|
||||
2.3.4 / 2011-05-08
|
||||
==================
|
||||
|
||||
* Added `./examples/say`
|
||||
* Fixed `res.sendfile()` bug preventing the transfer of files with spaces
|
||||
|
||||
2.3.3 / 2011-05-03
|
||||
2.3.3 / 2011-05-03
|
||||
==================
|
||||
|
||||
* Added "case sensitive routes" option.
|
||||
* Changed; split methods supported per rfc [slaskis]
|
||||
* Fixed route-specific middleware when using the same callback function several times
|
||||
|
||||
2.3.2 / 2011-04-27
|
||||
2.3.2 / 2011-04-27
|
||||
==================
|
||||
|
||||
* Fixed view hints
|
||||
|
||||
2.3.1 / 2011-04-26
|
||||
2.3.1 / 2011-04-26
|
||||
==================
|
||||
|
||||
* Added `app.match()` as `app.match.all()`
|
||||
@@ -453,7 +488,7 @@ Closes #805
|
||||
* Fixed template caching collision issue. Closes #644
|
||||
* Moved router over from connect and started refactor
|
||||
|
||||
2.3.0 / 2011-04-25
|
||||
2.3.0 / 2011-04-25
|
||||
==================
|
||||
|
||||
* Added options support to `res.clearCookie()`
|
||||
@@ -462,18 +497,18 @@ Closes #805
|
||||
* Changed; auto set Content-Type in res.attachement [Aaron Heckmann]
|
||||
* Renamed "cache views" to "view cache". Closes #628
|
||||
* Fixed caching of views when using several apps. Closes #637
|
||||
* Fixed gotcha invoking `app.param()` callbacks once per route middleware.
|
||||
* Fixed gotcha invoking `app.param()` callbacks once per route middleware.
|
||||
Closes #638
|
||||
* Fixed partial lookup precedence. Closes #631
|
||||
Shaw]
|
||||
|
||||
2.2.2 / 2011-04-12
|
||||
2.2.2 / 2011-04-12
|
||||
==================
|
||||
|
||||
* Added second callback support for `res.download()` connection errors
|
||||
* Fixed `filename` option passing to template engine
|
||||
|
||||
2.2.1 / 2011-04-04
|
||||
2.2.1 / 2011-04-04
|
||||
==================
|
||||
|
||||
* Added `layout(path)` helper to change the layout within a view. Closes #610
|
||||
@@ -487,7 +522,7 @@ Shaw]
|
||||
* Removed `request` and `response` locals
|
||||
* Changed; errorHandler page title is now `Express` instead of `Connect`
|
||||
|
||||
2.2.0 / 2011-03-30
|
||||
2.2.0 / 2011-03-30
|
||||
==================
|
||||
|
||||
* Added `app.lookup.VERB()`, ex `app.lookup.put('/user/:id')`. Closes #606
|
||||
@@ -495,14 +530,14 @@ Shaw]
|
||||
* Added `app.VERB(path)` as alias of `app.lookup.VERB()`.
|
||||
* Dependency `connect >= 1.2.0`
|
||||
|
||||
2.1.1 / 2011-03-29
|
||||
2.1.1 / 2011-03-29
|
||||
==================
|
||||
|
||||
* Added; expose `err.view` object when failing to locate a view
|
||||
* Fixed `res.partial()` call `next(err)` when no callback is given [reported by aheckmann]
|
||||
* Fixed; `res.send(undefined)` responds with 204 [aheckmann]
|
||||
|
||||
2.1.0 / 2011-03-24
|
||||
2.1.0 / 2011-03-24
|
||||
==================
|
||||
|
||||
* Added `<root>/_?<name>` partial lookup support. Closes #447
|
||||
@@ -513,20 +548,20 @@ Shaw]
|
||||
* Fixed stylus example for latest version
|
||||
* Fixed; wrap try/catch around `res.render()`
|
||||
|
||||
2.0.0 / 2011-03-17
|
||||
2.0.0 / 2011-03-17
|
||||
==================
|
||||
|
||||
* Fixed up index view path alternative.
|
||||
* Changed; `res.locals()` without object returns the locals
|
||||
|
||||
2.0.0rc3 / 2011-03-17
|
||||
2.0.0rc3 / 2011-03-17
|
||||
==================
|
||||
|
||||
* Added `res.locals(obj)` to compliment `res.local(key, val)`
|
||||
* Added `res.partial()` callback support
|
||||
* Fixed recursive error reporting issue in `res.render()`
|
||||
|
||||
2.0.0rc2 / 2011-03-17
|
||||
2.0.0rc2 / 2011-03-17
|
||||
==================
|
||||
|
||||
* Changed; `partial()` "locals" are now optional
|
||||
@@ -535,14 +570,14 @@ Shaw]
|
||||
* Fixed blog example
|
||||
* Fixed `{req,res}.app` reference when mounting [Ben Weaver]
|
||||
|
||||
2.0.0rc / 2011-03-14
|
||||
2.0.0rc / 2011-03-14
|
||||
==================
|
||||
|
||||
* Fixed; expose `HTTPSServer` constructor
|
||||
* Fixed express(1) default test charset. Closes #579 [reported by secoif]
|
||||
* Fixed; default charset to utf-8 instead of utf8 for lame IE [reported by NickP]
|
||||
|
||||
2.0.0beta3 / 2011-03-09
|
||||
2.0.0beta3 / 2011-03-09
|
||||
==================
|
||||
|
||||
* Added support for `res.contentType()` literal
|
||||
@@ -560,13 +595,13 @@ Shaw]
|
||||
* Fixed; default `res.send()` string charset to utf8
|
||||
* Removed `Partial` constructor (not currently used)
|
||||
|
||||
2.0.0beta2 / 2011-03-07
|
||||
2.0.0beta2 / 2011-03-07
|
||||
==================
|
||||
|
||||
* Added res.render() `.locals` support back to aid in migration process
|
||||
* Fixed flash example
|
||||
|
||||
2.0.0beta / 2011-03-03
|
||||
2.0.0beta / 2011-03-03
|
||||
==================
|
||||
|
||||
* Added HTTPS support
|
||||
@@ -599,46 +634,46 @@ Shaw]
|
||||
* Fixed; strip unsafe chars from jsonp callbacks
|
||||
* Removed "stream threshold" setting
|
||||
|
||||
1.0.8 / 2011-03-01
|
||||
1.0.8 / 2011-03-01
|
||||
==================
|
||||
|
||||
* Allow `req.query` to be pre-defined (via middleware or other parent app)
|
||||
* "connect": ">= 0.5.0 < 1.0.0". Closes #547
|
||||
* Removed the long deprecated __EXPRESS_ENV__ support
|
||||
|
||||
1.0.7 / 2011-02-07
|
||||
1.0.7 / 2011-02-07
|
||||
==================
|
||||
|
||||
* Fixed `render()` setting inheritance.
|
||||
Mounted apps would not inherit "view engine"
|
||||
|
||||
1.0.6 / 2011-02-07
|
||||
1.0.6 / 2011-02-07
|
||||
==================
|
||||
|
||||
* Fixed `view engine` setting bug when period is in dirname
|
||||
|
||||
1.0.5 / 2011-02-05
|
||||
1.0.5 / 2011-02-05
|
||||
==================
|
||||
|
||||
* Added secret to generated app `session()` call
|
||||
|
||||
1.0.4 / 2011-02-05
|
||||
1.0.4 / 2011-02-05
|
||||
==================
|
||||
|
||||
* Added `qs` dependency to _package.json_
|
||||
* Fixed namespaced `require()`s for latest connect support
|
||||
|
||||
1.0.3 / 2011-01-13
|
||||
1.0.3 / 2011-01-13
|
||||
==================
|
||||
|
||||
* Remove unsafe characters from JSONP callback names [Ryan Grove]
|
||||
|
||||
1.0.2 / 2011-01-10
|
||||
1.0.2 / 2011-01-10
|
||||
==================
|
||||
|
||||
* Removed nested require, using `connect.router`
|
||||
|
||||
1.0.1 / 2010-12-29
|
||||
1.0.1 / 2010-12-29
|
||||
==================
|
||||
|
||||
* Fixed for middleware stacked via `createServer()`
|
||||
@@ -646,7 +681,7 @@ Shaw]
|
||||
would not have access to Express methods such as `res.send()`
|
||||
or props like `req.query` etc.
|
||||
|
||||
1.0.0 / 2010-11-16
|
||||
1.0.0 / 2010-11-16
|
||||
==================
|
||||
|
||||
* Added; deduce partial object names from the last segment.
|
||||
@@ -660,7 +695,7 @@ Shaw]
|
||||
* Added _-s, --session[s]_ flag to express(1) to add session related middleware
|
||||
* Added _--template_ flag to express(1) to specify the
|
||||
template engine to use.
|
||||
* Added _--css_ flag to express(1) to specify the
|
||||
* Added _--css_ flag to express(1) to specify the
|
||||
stylesheet engine to use (or just plain css by default).
|
||||
* Added `app.all()` support [thanks aheckmann]
|
||||
* Added partial direct object support.
|
||||
@@ -673,7 +708,7 @@ Shaw]
|
||||
* Fixed partial local inheritance precedence. [reported by Nick Poulden] Closes #454
|
||||
* Fixed jsonp support; _text/javascript_ as per mailinglist discussion
|
||||
|
||||
1.0.0rc4 / 2010-10-14
|
||||
1.0.0rc4 / 2010-10-14
|
||||
==================
|
||||
|
||||
* Added _NODE_ENV_ support, _EXPRESS_ENV_ is deprecated and will be removed in 1.0.0
|
||||
@@ -692,7 +727,7 @@ Shaw]
|
||||
* Fixed; exposing _./support_ libs to examples so they can run without installs
|
||||
* Fixed mvc example
|
||||
|
||||
1.0.0rc3 / 2010-09-20
|
||||
1.0.0rc3 / 2010-09-20
|
||||
==================
|
||||
|
||||
* Added confirmation for `express(1)` app generation. Closes #391
|
||||
@@ -715,7 +750,7 @@ Shaw]
|
||||
* Fixed bug messing with error handlers when `listenFD()` is called instead of `listen()`. [thanks guillermo]
|
||||
|
||||
|
||||
1.0.0rc2 / 2010-08-17
|
||||
1.0.0rc2 / 2010-08-17
|
||||
==================
|
||||
|
||||
* Added `app.register()` for template engine mapping. Closes #390
|
||||
@@ -728,7 +763,7 @@ Shaw]
|
||||
* Fixed `res.sendfile()` error handling, defer via `next()`
|
||||
* Fixed `res.render()` callback when a layout is used [thanks guillermo]
|
||||
* Fixed; `make install` creating ~/.node_libraries when not present
|
||||
* Fixed issue preventing error handlers from being defined anywhere. Closes #387
|
||||
* Fixed issue preventing error handlers from being defined anywhere. Closes #387
|
||||
|
||||
1.0.0rc / 2010-07-28
|
||||
==================
|
||||
@@ -746,7 +781,7 @@ Shaw]
|
||||
* Fixed "home" setting
|
||||
* Fixed middleware/router precedence issue. Closes #366
|
||||
* Fixed; _configure()_ callbacks called immediately. Closes #368
|
||||
|
||||
|
||||
1.0.0beta2 / 2010-07-23
|
||||
==================
|
||||
|
||||
@@ -881,7 +916,7 @@ Shaw]
|
||||
* Updated dependencies
|
||||
* Removed set("session cookie") in favour of use(Session, { cookie: { ... }})
|
||||
* Removed utils.mixin(); use Object#mergeDeep()
|
||||
|
||||
|
||||
0.8.0 / 2010-03-19
|
||||
==================
|
||||
|
||||
@@ -948,16 +983,16 @@ Shaw]
|
||||
|
||||
* Added seed.yml for kiwi package management support
|
||||
* Added HTTP client query string support when method is GET. Closes #205
|
||||
|
||||
|
||||
* Added support for arbitrary view engines.
|
||||
For example "foo.engine.html" will now require('engine'),
|
||||
the exports from this module are cached after the first require().
|
||||
|
||||
|
||||
* Added async plugin support
|
||||
|
||||
|
||||
* Removed usage of RESTful route funcs as http client
|
||||
get() etc, use http.get() and friends
|
||||
|
||||
|
||||
* Removed custom exceptions
|
||||
|
||||
0.5.0 / 2010-03-10
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
@@ -21,6 +20,7 @@ api.use(express.bodyParser());
|
||||
*/
|
||||
|
||||
api.all('*', function(req, res, next){
|
||||
if (!req.get('Origin')) return next();
|
||||
// use "*" here to accept any origin
|
||||
res.set('Access-Control-Allow-Origin', 'http://localhost:3000');
|
||||
res.set('Access-Control-Allow-Methods', 'GET, POST');
|
||||
|
||||
+17
-20
@@ -5,46 +5,43 @@
|
||||
|
||||
var express = require('../..');
|
||||
|
||||
// Edit /etc/vhosts
|
||||
/*
|
||||
edit /etc/vhosts:
|
||||
|
||||
// First app
|
||||
127.0.0.1 foo.example.com
|
||||
127.0.0.1 bar.example.com
|
||||
127.0.0.1 example.com
|
||||
*/
|
||||
|
||||
var one = express();
|
||||
// Main app
|
||||
|
||||
one.use(express.logger());
|
||||
var main = express();
|
||||
|
||||
one.get('/', function(req, res){
|
||||
res.send('Hello from app one!')
|
||||
main.use(express.logger('dev'));
|
||||
|
||||
main.get('/', function(req, res){
|
||||
res.send('Hello from main app!')
|
||||
});
|
||||
|
||||
one.get('/:sub', function(req, res){
|
||||
main.get('/:sub', function(req, res){
|
||||
res.send('requsted ' + req.params.sub);
|
||||
});
|
||||
|
||||
// App two
|
||||
|
||||
var two = express();
|
||||
|
||||
two.get('/', function(req, res){
|
||||
res.send('Hello from app two!')
|
||||
});
|
||||
|
||||
// Redirect app
|
||||
|
||||
var redirect = express();
|
||||
|
||||
redirect.all('*', function(req, res){
|
||||
console.log(req.subdomains);
|
||||
res.redirect('http://localhost:3000/' + req.subdomains[0]);
|
||||
res.redirect('http://example.com:3000/' + req.subdomains[0]);
|
||||
});
|
||||
|
||||
// Main app
|
||||
|
||||
var app = express();
|
||||
|
||||
app.use(express.vhost('*.localhost', redirect))
|
||||
app.use(express.vhost('localhost', one));
|
||||
app.use(express.vhost('dev', two));
|
||||
app.use(express.vhost('*.example.com', redirect))
|
||||
app.use(express.vhost('example.com', main));
|
||||
|
||||
app.listen(3000);
|
||||
console.log('Express app started on port 3000');
|
||||
console.log('Express app started on port 3000');
|
||||
|
||||
@@ -48,6 +48,7 @@ app.defaultConfiguration = function(){
|
||||
// default settings
|
||||
this.enable('x-powered-by');
|
||||
this.set('env', process.env.NODE_ENV || 'development');
|
||||
this.set('subdomain offset', 2);
|
||||
debug('booting in %s mode', this.get('env'));
|
||||
|
||||
// implicit middleware
|
||||
@@ -160,7 +161,7 @@ app.use = function(route, fn){
|
||||
* [Consolidate.js](https://github.com/visionmedia/consolidate.js)
|
||||
* library was created to map all of node's popular template
|
||||
* engines to follow this convention, thus allowing them to
|
||||
* work seemlessly within Express.
|
||||
* work seeessly within Express.
|
||||
*
|
||||
* @param {String} ext
|
||||
* @param {Function} fn
|
||||
@@ -397,15 +398,18 @@ app.configure = function(env, fn){
|
||||
};
|
||||
|
||||
/**
|
||||
* Delegate `.VERB(...)` calls to `.route(VERB, ...)`.
|
||||
* Delegate `.VERB(...)` calls to `router.VERB(...)`.
|
||||
*/
|
||||
|
||||
methods.forEach(function(method){
|
||||
app[method] = function(path){
|
||||
if ('get' == method && 1 == arguments.length) return this.set(path);
|
||||
var args = [method].concat([].slice.call(arguments));
|
||||
|
||||
// if no router attacked yet, attach the router
|
||||
if (!this._usedRouter) this.use(this.router);
|
||||
this._router.route.apply(this._router, args);
|
||||
|
||||
// setup route
|
||||
this._router[method].apply(this._router, arguments);
|
||||
return this;
|
||||
};
|
||||
});
|
||||
|
||||
+2
-2
@@ -20,7 +20,7 @@ exports = module.exports = createApplication;
|
||||
* Framework version.
|
||||
*/
|
||||
|
||||
exports.version = '3.0.3';
|
||||
exports.version = '3.1.0';
|
||||
|
||||
/**
|
||||
* Expose mime.
|
||||
@@ -46,7 +46,7 @@ function createApplication() {
|
||||
|
||||
/**
|
||||
* Expose connect.middleware as express.*
|
||||
* for example `express.logger` etc.
|
||||
* for example `express.logger` etc.
|
||||
*/
|
||||
|
||||
for (var key in connect.middleware) {
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ var utils = require('./utils');
|
||||
exports.init = function(app){
|
||||
return function expressInit(req, res, next){
|
||||
req.app = res.app = app;
|
||||
if (app.settings['x-powered-by']) res.setHeader('X-Powered-By', 'Express');
|
||||
if (app.enabled('x-powered-by')) res.setHeader('X-Powered-By', 'Express');
|
||||
req.res = res;
|
||||
res.req = req;
|
||||
req.next = next;
|
||||
|
||||
+23
-16
@@ -29,21 +29,21 @@ var req = exports = module.exports = {
|
||||
*
|
||||
* req.get('Content-Type');
|
||||
* // => "text/plain"
|
||||
*
|
||||
*
|
||||
* req.get('content-type');
|
||||
* // => "text/plain"
|
||||
*
|
||||
*
|
||||
* req.get('Something');
|
||||
* // => undefined
|
||||
*
|
||||
* Aliased as `req.header()`.
|
||||
*
|
||||
* @param {String} name
|
||||
* @return {String}
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.get =
|
||||
req.get =
|
||||
req.header = function(name){
|
||||
switch (name = name.toLowerCase()) {
|
||||
case 'referer':
|
||||
@@ -67,7 +67,7 @@ req.header = function(name){
|
||||
* or array is given the _best_ match, if any is returned.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
*
|
||||
* // Accept: text/html
|
||||
* req.accepts('html');
|
||||
* // => "html"
|
||||
@@ -261,7 +261,7 @@ req.param = function(name, defaultValue){
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the incoming request contains the "Content-Type"
|
||||
* Check if the incoming request contains the "Content-Type"
|
||||
* header field, and it contains the give mime `type`.
|
||||
*
|
||||
* Examples:
|
||||
@@ -271,16 +271,16 @@ req.param = function(name, defaultValue){
|
||||
* req.is('text/html');
|
||||
* req.is('text/*');
|
||||
* // => true
|
||||
*
|
||||
*
|
||||
* // When Content-Type is application/json
|
||||
* req.is('json');
|
||||
* req.is('application/json');
|
||||
* req.is('application/*');
|
||||
* // => true
|
||||
*
|
||||
*
|
||||
* req.is('html');
|
||||
* // => false
|
||||
*
|
||||
*
|
||||
* @param {String} type
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
@@ -303,7 +303,7 @@ req.is = function(type){
|
||||
|
||||
/**
|
||||
* Return the protocol string "http" or "https"
|
||||
* when requested with TLS. When the "trust proxy"
|
||||
* when requested with TLS. When the "trust proxy"
|
||||
* setting is enabled the "X-Forwarded-Proto" header
|
||||
* field will be trusted. If you're running behind
|
||||
* a reverse proxy that supplies https for you this
|
||||
@@ -393,25 +393,32 @@ req.__defineGetter__('auth', function(){
|
||||
auth = parts[1];
|
||||
|
||||
// credentials
|
||||
auth = new Buffer(auth, 'base64').toString().split(':');
|
||||
return { username: auth[0], password: auth[1] };
|
||||
auth = new Buffer(auth, 'base64').toString().match(/^([^:]*):(.*)$/);
|
||||
if (!auth) return;
|
||||
return { username: auth[1], password: auth[2] };
|
||||
});
|
||||
|
||||
/**
|
||||
* Return subdomains as an array.
|
||||
*
|
||||
* For example "tobi.ferrets.example.com"
|
||||
* would provide `["ferrets", "tobi"]`.
|
||||
* Subdomains are the dot-separated parts of the host before the main domain of
|
||||
* the app. By default, the domain of the app is assumed to be the last two
|
||||
* parts of the host. This can be changed by setting "subdomain offset".
|
||||
*
|
||||
* For example, if the domain is "tobi.ferrets.example.com":
|
||||
* If "subdomain offset" is not set, req.subdomains is `["ferrets", "tobi"]`.
|
||||
* If "subdomain offset" is 3, req.subdomains is `["tobi"]`.
|
||||
*
|
||||
* @return {Array}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.__defineGetter__('subdomains', function(){
|
||||
var offset = this.app.get('subdomain offset');
|
||||
return this.get('Host')
|
||||
.split('.')
|
||||
.slice(0, -2)
|
||||
.reverse();
|
||||
.reverse()
|
||||
.slice(offset);
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
+86
-49
@@ -141,6 +141,7 @@ res.send = function(body){
|
||||
if (204 == this.statusCode || 304 == this.statusCode) {
|
||||
this.removeHeader('Content-Type');
|
||||
this.removeHeader('Content-Length');
|
||||
this.removeHeader('Transfer-Encoding');
|
||||
body = '';
|
||||
}
|
||||
|
||||
@@ -186,7 +187,7 @@ res.json = function(obj){
|
||||
// content-type
|
||||
this.charset = this.charset || 'utf-8';
|
||||
this.get('Content-Type') || this.set('Content-Type', 'application/json');
|
||||
|
||||
|
||||
return this.send(body);
|
||||
};
|
||||
|
||||
@@ -222,13 +223,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);
|
||||
var body = JSON.stringify(obj, replacer, spaces)
|
||||
.replace(/\u2028/g, '\\u2028')
|
||||
.replace(/\u2029/g, '\\u2029');
|
||||
var callback = this.req.query[app.get('jsonp callback name')];
|
||||
|
||||
// content-type
|
||||
this.charset = this.charset || 'utf-8';
|
||||
this.set('Content-Type', 'application/json');
|
||||
|
||||
|
||||
// jsonp
|
||||
if (callback) {
|
||||
this.set('Content-Type', 'text/javascript');
|
||||
@@ -241,7 +244,7 @@ res.jsonp = function(obj){
|
||||
|
||||
/**
|
||||
* Transfer the file at the given `path`.
|
||||
*
|
||||
*
|
||||
* Automatically sets the _Content-Type_ response header field.
|
||||
* The callback `fn(err)` is invoked when the transfer is complete
|
||||
* or when an error occurs. Be sure to check `res.sentHeader`
|
||||
@@ -263,7 +266,7 @@ res.jsonp = function(obj){
|
||||
* app.get('/user/:uid/photos/:file', function(req, res){
|
||||
* var uid = req.params.uid
|
||||
* , file = req.params.file;
|
||||
*
|
||||
*
|
||||
* req.user.mayViewFilesFrom(uid, function(yes){
|
||||
* if (yes) {
|
||||
* res.sendfile('/uploads/' + uid + '/' + file);
|
||||
@@ -408,11 +411,11 @@ res.type = function(type){
|
||||
* 'text/plain': function(){
|
||||
* res.send('hey');
|
||||
* },
|
||||
*
|
||||
*
|
||||
* 'text/html': function(){
|
||||
* res.send('<p>hey</p>');
|
||||
* },
|
||||
*
|
||||
*
|
||||
* 'appliation/json': function(){
|
||||
* res.send({ message: 'hey' });
|
||||
* }
|
||||
@@ -425,11 +428,11 @@ res.type = function(type){
|
||||
* text: function(){
|
||||
* res.send('hey');
|
||||
* },
|
||||
*
|
||||
*
|
||||
* html: function(){
|
||||
* res.send('<p>hey</p>');
|
||||
* },
|
||||
*
|
||||
*
|
||||
* json: function(){
|
||||
* res.send({ message: 'hey' });
|
||||
* }
|
||||
@@ -495,24 +498,27 @@ res.attachment = function(filename){
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* res.set('Foo', ['bar', 'baz']);
|
||||
* res.set('Accept', 'application/json');
|
||||
* res.set({ Accept: 'text/plain', 'X-API-Key': 'tobi' });
|
||||
*
|
||||
* Aliased as `res.header()`.
|
||||
* Aliased as `res.header()`.
|
||||
*
|
||||
* @param {String|Object} field
|
||||
* @param {String|Object|Array} field
|
||||
* @param {String} val
|
||||
* @return {ServerResponse} for chaining
|
||||
* @api public
|
||||
*/
|
||||
|
||||
res.set =
|
||||
res.set =
|
||||
res.header = function(field, val){
|
||||
if (2 == arguments.length) {
|
||||
this.setHeader(field, '' + val);
|
||||
if (Array.isArray(val)) val = val.map(String);
|
||||
else val = String(val);
|
||||
this.setHeader(field, val);
|
||||
} else {
|
||||
for (var key in field) {
|
||||
this.setHeader(key, '' + field[key]);
|
||||
this.set(key, field[key]);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
@@ -570,22 +576,24 @@ res.clearCookie = function(name, options){
|
||||
*/
|
||||
|
||||
res.cookie = function(name, val, options){
|
||||
options = options || {};
|
||||
options = utils.merge({}, options);
|
||||
var secret = this.req.secret;
|
||||
var signed = options.signed;
|
||||
if (signed && !secret) throw new Error('connect.cookieParser("secret") required for signed cookies');
|
||||
if ('object' == typeof val) val = 'j:' + JSON.stringify(val);
|
||||
if (signed) val = 's:' + sign(val, secret);
|
||||
if ('maxAge' in options) options.expires = new Date(Date.now() + options.maxAge);
|
||||
if ('maxAge' in options) {
|
||||
options.expires = new Date(Date.now() + options.maxAge);
|
||||
options.maxAge /= 1000;
|
||||
}
|
||||
if (null == options.path) options.path = '/';
|
||||
options.maxAge /= 1000;
|
||||
this.set('Set-Cookie', cookie.serialize(name, String(val), options));
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Redirect to the given `url` with optional response `status`
|
||||
* defaulting to 302.
|
||||
* Set the location header to `url`.
|
||||
*
|
||||
* The given `url` can also be the name of a mapped url, for
|
||||
* example by default express supports "back" which redirects
|
||||
@@ -593,46 +601,30 @@ res.cookie = function(name, val, options){
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* 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
|
||||
* res.location('/foo/bar').;
|
||||
* res.location('http://example.com');
|
||||
* res.location('../login'); // /blog/post/1 -> /blog/login
|
||||
*
|
||||
* Mounting:
|
||||
*
|
||||
* When an application is mounted, and `res.redirect()`
|
||||
* is given a path that does _not_ lead with "/". For
|
||||
* example suppose a "blog" app is mounted at "/blog",
|
||||
* the following redirect would result in "/blog/login":
|
||||
* When an application is mounted and `res.location()`
|
||||
* is given a path that does _not_ lead with "/" it becomes
|
||||
* relative to the mount-point. For example if the application
|
||||
* is mounted at "/blog", the following would become "/blog/login".
|
||||
*
|
||||
* res.redirect('login');
|
||||
* res.location('login');
|
||||
*
|
||||
* While the leading slash would result in a redirect to "/login":
|
||||
* While the leading slash would result in a location of "/login":
|
||||
*
|
||||
* res.redirect('/login');
|
||||
* res.location('/login');
|
||||
*
|
||||
* @param {String} url
|
||||
* @param {Number} code
|
||||
* @api public
|
||||
*/
|
||||
|
||||
res.redirect = function(url){
|
||||
res.location = function(url){
|
||||
var app = this.app
|
||||
, req = this.req
|
||||
, head = 'HEAD' == req.method
|
||||
, status = 302
|
||||
, body;
|
||||
|
||||
// allow status / url
|
||||
if (2 == arguments.length) {
|
||||
if ('number' == typeof url) {
|
||||
status = url;
|
||||
url = arguments[1];
|
||||
} else {
|
||||
status = arguments[1];
|
||||
}
|
||||
}
|
||||
, req = this.req;
|
||||
|
||||
// setup redirect map
|
||||
var map = { back: req.get('Referrer') || '/' };
|
||||
@@ -653,10 +645,56 @@ res.redirect = function(url){
|
||||
}
|
||||
}
|
||||
|
||||
// Respond
|
||||
this.set('Location', url);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Redirect to the given `url` with optional response `status`
|
||||
* defaulting to 302.
|
||||
*
|
||||
* The resulting `url` is determined by `res.location()`, so
|
||||
* it will play nicely with mounted apps, relative paths,
|
||||
* `"back"` etc.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
res.redirect = function(url){
|
||||
var app = this.app
|
||||
, head = 'HEAD' == this.req.method
|
||||
, status = 302
|
||||
, body;
|
||||
|
||||
// allow status / url
|
||||
if (2 == arguments.length) {
|
||||
if ('number' == typeof url) {
|
||||
status = url;
|
||||
url = arguments[1];
|
||||
} else {
|
||||
status = arguments[1];
|
||||
}
|
||||
}
|
||||
|
||||
// Set location header
|
||||
this.location(url);
|
||||
url = this.get('Location');
|
||||
|
||||
// Support text/{plain,html} by default
|
||||
this.format({
|
||||
text: function(){
|
||||
body = statusCodes[status] + '. Redirecting to ' + url;
|
||||
body = statusCodes[status] + '. Redirecting to ' + encodeURI(url);
|
||||
},
|
||||
|
||||
html: function(){
|
||||
@@ -671,7 +709,6 @@ res.redirect = function(url){
|
||||
|
||||
// Respond
|
||||
this.statusCode = status;
|
||||
this.set('Location', url);
|
||||
this.set('Content-Length', Buffer.byteLength(body));
|
||||
this.end(head ? null : body);
|
||||
};
|
||||
|
||||
+21
-4
@@ -4,6 +4,7 @@
|
||||
|
||||
var Route = require('./route')
|
||||
, utils = require('../utils')
|
||||
, methods = require('methods')
|
||||
, debug = require('debug')('express:router')
|
||||
, parse = require('connect').utils.parseUrl;
|
||||
|
||||
@@ -15,7 +16,7 @@ exports = module.exports = Router;
|
||||
|
||||
/**
|
||||
* Initialize a new `Router` with the given `options`.
|
||||
*
|
||||
*
|
||||
* @param {Object} options
|
||||
* @api private
|
||||
*/
|
||||
@@ -139,7 +140,7 @@ Router.prototype._dispatch = function(req, res, next){
|
||||
};
|
||||
|
||||
param(err);
|
||||
|
||||
|
||||
// single param callbacks
|
||||
function paramCallback(err) {
|
||||
var fn = paramCallbacks[paramIndex++];
|
||||
@@ -243,14 +244,30 @@ Router.prototype.route = function(method, path, callbacks){
|
||||
// ensure path was given
|
||||
if (!path) throw new Error('Router#' + method + '() requires a path');
|
||||
|
||||
// ensure all callbacks are functions
|
||||
callbacks.forEach(function(fn, i){
|
||||
if ('function' == typeof fn) return;
|
||||
var type = {}.toString.call(fn);
|
||||
var msg = '.' + method + '() requires callback functions but got a ' + type;
|
||||
throw new Error(msg);
|
||||
});
|
||||
|
||||
// create the route
|
||||
debug('defined %s %s', method, path);
|
||||
var route = new Route(method, path, callbacks, {
|
||||
sensitive: this.caseSensitive
|
||||
, strict: this.strict
|
||||
sensitive: this.caseSensitive,
|
||||
strict: this.strict
|
||||
});
|
||||
|
||||
// add it
|
||||
(this.map[method] = this.map[method] || []).push(route);
|
||||
return this;
|
||||
};
|
||||
|
||||
methods.forEach(function(method){
|
||||
Router.prototype[method] = function(path){
|
||||
var args = [method].concat([].slice.call(arguments));
|
||||
this.route.apply(this, args);
|
||||
return this;
|
||||
};
|
||||
});
|
||||
|
||||
+2
-4
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
var mime = require('connect').mime
|
||||
, crc = require('crc');
|
||||
, crc32 = require('buffer-crc32');
|
||||
|
||||
/**
|
||||
* Return ETag for `body`.
|
||||
@@ -15,9 +15,7 @@ var mime = require('connect').mime
|
||||
*/
|
||||
|
||||
exports.etag = function(body){
|
||||
return '"' + (Buffer.isBuffer(body)
|
||||
? crc.buffer.crc32(body)
|
||||
: crc.crc32(body)) + '"';
|
||||
return '"' + crc32.signed(body) + '"';
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ function View(name, options) {
|
||||
var engines = options.engines;
|
||||
this.defaultEngine = options.defaultEngine;
|
||||
var ext = this.ext = extname(name);
|
||||
if (!ext) name += (ext = this.ext = '.' + this.defaultEngine);
|
||||
if (!ext) name += (ext = this.ext = ('.' != this.defaultEngine[0] ? '.' : '') + this.defaultEngine);
|
||||
this.engine = engines[ext] || (engines[ext] = require(ext.slice(1)).__express);
|
||||
this.path = this.lookup(name);
|
||||
}
|
||||
|
||||
+5
-5
@@ -1,21 +1,21 @@
|
||||
{
|
||||
"name": "express",
|
||||
"description": "Sinatra inspired web development framework",
|
||||
"version": "3.0.3",
|
||||
"version": "3.1.0",
|
||||
"author": "TJ Holowaychuk <tj@vision-media.ca>",
|
||||
"contributors": [
|
||||
{ "name": "TJ Holowaychuk", "email": "tj@vision-media.ca" },
|
||||
"contributors": [
|
||||
{ "name": "TJ Holowaychuk", "email": "tj@vision-media.ca" },
|
||||
{ "name": "Aaron Heckmann", "email": "aaron.heckmann+github@gmail.com" },
|
||||
{ "name": "Ciaran Jessup", "email": "ciaranj@gmail.com" },
|
||||
{ "name": "Guillermo Rauch", "email": "rauchg@gmail.com" }
|
||||
],
|
||||
"dependencies": {
|
||||
"connect": "2.7.0",
|
||||
"connect": "2.7.2",
|
||||
"commander": "0.6.1",
|
||||
"range-parser": "0.0.4",
|
||||
"mkdirp": "0.3.3",
|
||||
"cookie": "0.0.5",
|
||||
"crc": "0.2.0",
|
||||
"buffer-crc32": "0.1.1",
|
||||
"fresh": "0.1.0",
|
||||
"methods": "0.0.1",
|
||||
"send": "0.1.0",
|
||||
|
||||
+25
-1
@@ -76,4 +76,28 @@ describe('Router', function(){
|
||||
.expect('foo', done);
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('.multiple callbacks', function(){
|
||||
it('should throw if a callback is null', function(){
|
||||
assert.throws(function () {
|
||||
router.route('get', '/foo', null, function(){});
|
||||
})
|
||||
})
|
||||
|
||||
it('should throw if a callback is undefined', function(){
|
||||
assert.throws(function () {
|
||||
router.route('get', '/foo', undefined, function(){});
|
||||
})
|
||||
})
|
||||
|
||||
it('should throw if a callback is not a function', function(){
|
||||
assert.throws(function () {
|
||||
router.route('get', '/foo', 'not a function', function(){});
|
||||
})
|
||||
})
|
||||
|
||||
it('should not throw if all callbacks are functions', function(){
|
||||
router.route('get', '/foo', function(){}, function(){});
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -61,5 +61,20 @@ describe('app', function(){
|
||||
done();
|
||||
})
|
||||
})
|
||||
|
||||
it('should work "view engine" with leading "."', function(done){
|
||||
var app = express();
|
||||
|
||||
app.set('views', __dirname + '/fixtures');
|
||||
app.engine('.html', render);
|
||||
app.set('view engine', '.html');
|
||||
app.locals.user = { name: 'tobi' };
|
||||
|
||||
app.render('user', function(err, str){
|
||||
if (err) return done(err);
|
||||
str.should.equal('<p>tobi</p>');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -48,6 +48,36 @@ describe('req', function(){
|
||||
})
|
||||
})
|
||||
|
||||
describe('when encoded string is malformed', function(){
|
||||
it('should return undefined', function(done){
|
||||
var app = express();
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.send(req.auth || 'none');
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Authorization', 'Basic Z21ldGh2aW4=')
|
||||
.expect('none', done)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when password contains a colon', function(){
|
||||
it('should return .username and .password', function(done){
|
||||
var app = express();
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.send(req.auth || 'none');
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Authorization', 'Basic dG9iaTpmZXJyZXQ6ZmVycmV0')
|
||||
.expect('{"username":"tobi","password":"ferret:ferret"}', done)
|
||||
})
|
||||
})
|
||||
|
||||
it('should return .username and .password', function(done){
|
||||
var app = express();
|
||||
|
||||
|
||||
@@ -33,5 +33,55 @@ describe('req', function(){
|
||||
.expect('[]', done);
|
||||
})
|
||||
})
|
||||
|
||||
describe('when subdomain offset is set', function(){
|
||||
describe('when subdomain offset is zero', function(){
|
||||
it('should return an array with the whole domain', function(done){
|
||||
var app = express();
|
||||
app.set('subdomain offset', 0);
|
||||
|
||||
app.use(function(req, res){
|
||||
res.send(req.subdomains);
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Host', 'tobi.ferrets.sub.example.com')
|
||||
.expect('["com","example","sub","ferrets","tobi"]', done);
|
||||
})
|
||||
})
|
||||
|
||||
describe('when present', function(){
|
||||
it('should return an array', function(done){
|
||||
var app = express();
|
||||
app.set('subdomain offset', 3);
|
||||
|
||||
app.use(function(req, res){
|
||||
res.send(req.subdomains);
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Host', 'tobi.ferrets.sub.example.com')
|
||||
.expect('["ferrets","tobi"]', done);
|
||||
})
|
||||
})
|
||||
|
||||
describe('otherwise', function(){
|
||||
it('should return an empty array', function(done){
|
||||
var app = express();
|
||||
app.set('subdomain offset', 3);
|
||||
|
||||
app.use(function(req, res){
|
||||
res.send(req.subdomains);
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Host', 'sub.example.com')
|
||||
.expect('[]', done);
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
var express = require('../')
|
||||
, request = require('./support/http')
|
||||
, utils = require('connect').utils
|
||||
, cookie = require('cookie');
|
||||
|
||||
describe('res', function(){
|
||||
@@ -108,6 +109,25 @@ describe('res', function(){
|
||||
done();
|
||||
})
|
||||
})
|
||||
|
||||
it('should not mutate the options object', function(done){
|
||||
var app = express();
|
||||
|
||||
var options = { maxAge: 1000 };
|
||||
var optionsCopy = utils.merge({}, options);
|
||||
|
||||
app.use(function(req, res){
|
||||
res.cookie('name', 'tobi', options)
|
||||
res.end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
options.should.eql(optionsCopy);
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('signed', function(){
|
||||
|
||||
@@ -71,6 +71,22 @@ describe('res', function(){
|
||||
})
|
||||
})
|
||||
|
||||
it('should escape utf whitespace', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.jsonp({ str: '\u2028 \u2029 woot' });
|
||||
});
|
||||
|
||||
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('foo && foo({"str":"\\u2028 \\u2029 woot"});');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when given primitives', function(){
|
||||
it('should respond with json', function(done){
|
||||
var app = express();
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
|
||||
var express = require('../')
|
||||
, request = require('./support/http');
|
||||
|
||||
describe('res', function(){
|
||||
describe('.location(url)', function(){
|
||||
it('should set the header', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.location('http://google.com').end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', 'http://google.com');
|
||||
done();
|
||||
})
|
||||
})
|
||||
|
||||
describe('with leading //', function(){
|
||||
it('should pass through scheme-relative urls', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.location('//cuteoverload.com').end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '//cuteoverload.com');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('with leading /', function(){
|
||||
it('should construct scheme-relative urls', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.location('/login').end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '/login');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('with leading ./', function(){
|
||||
it('should construct path-relative urls', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.location('./edit').end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/post/1')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '/post/1/./edit');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('with leading ../', function(){
|
||||
it('should construct path-relative urls', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.location('../new').end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/post/1')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '/post/1/../new');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('without leading /', function(){
|
||||
it('should construct mount-point relative urls', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.location('login').end();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '/login');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('when mounted', function(){
|
||||
describe('deeply', function(){
|
||||
it('should respect the mount-point', function(done){
|
||||
var app = express()
|
||||
, blog = express()
|
||||
, admin = express();
|
||||
|
||||
admin.use(function(req, res){
|
||||
res.location('login').end();
|
||||
});
|
||||
|
||||
app.use('/blog', blog);
|
||||
blog.use('/admin', admin);
|
||||
|
||||
request(app)
|
||||
.get('/blog/admin')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '/blog/admin/login');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('omitting leading /', function(){
|
||||
it('should respect the mount-point', function(done){
|
||||
var app = express()
|
||||
, admin = express();
|
||||
|
||||
admin.use(function(req, res){
|
||||
res.location('admin/login').end();
|
||||
});
|
||||
|
||||
app.use('/blog', admin);
|
||||
|
||||
request(app)
|
||||
.get('/blog')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '/blog/admin/login');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('providing leading /', function(){
|
||||
it('should ignore mount-point', function(done){
|
||||
var app = express()
|
||||
, admin = express();
|
||||
|
||||
admin.use(function(req, res){
|
||||
res.location('/admin/login').end();
|
||||
});
|
||||
|
||||
app.use('/blog', admin);
|
||||
|
||||
request(app)
|
||||
.get('/blog')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '/admin/login');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
+17
-158
@@ -19,164 +19,6 @@ describe('res', function(){
|
||||
done();
|
||||
})
|
||||
})
|
||||
|
||||
describe('with leading //', function(){
|
||||
it('should pass through scheme-relative urls', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.redirect('//cuteoverload.com');
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Host', 'example.com')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '//cuteoverload.com');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
describe('with leading /', function(){
|
||||
it('should construct scheme-relative urls', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.redirect('/login');
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Host', 'example.com')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '/login');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('with leading ./', function(){
|
||||
it('should construct path-relative urls', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.redirect('./edit');
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/post/1')
|
||||
.set('Host', 'example.com')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '/post/1/./edit');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('with leading ../', function(){
|
||||
it('should construct path-relative urls', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.redirect('../new');
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/post/1')
|
||||
.set('Host', 'example.com')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '/post/1/../new');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('without leading /', function(){
|
||||
it('should construct mount-point relative urls', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.redirect('login');
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Host', 'example.com')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '/login');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('when mounted', function(){
|
||||
describe('deeply', function(){
|
||||
it('should respect the mount-point', function(done){
|
||||
var app = express()
|
||||
, blog = express()
|
||||
, admin = express();
|
||||
|
||||
admin.use(function(req, res){
|
||||
res.redirect('login');
|
||||
});
|
||||
|
||||
app.use('/blog', blog);
|
||||
blog.use('/admin', admin);
|
||||
|
||||
request(app)
|
||||
.get('/blog/admin')
|
||||
.set('Host', 'example.com')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '/blog/admin/login');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('omitting leading /', function(){
|
||||
it('should respect the mount-point', function(done){
|
||||
var app = express()
|
||||
, admin = express();
|
||||
|
||||
admin.use(function(req, res){
|
||||
res.redirect('admin/login');
|
||||
});
|
||||
|
||||
app.use('/blog', admin);
|
||||
|
||||
request(app)
|
||||
.get('/blog')
|
||||
.set('Host', 'example.com')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '/blog/admin/login');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('providing leading /', function(){
|
||||
it('should ignore mount-point', function(done){
|
||||
var app = express()
|
||||
, admin = express();
|
||||
|
||||
admin.use(function(req, res){
|
||||
res.redirect('/admin/login');
|
||||
});
|
||||
|
||||
app.use('/blog', admin);
|
||||
|
||||
request(app)
|
||||
.get('/blog')
|
||||
.set('Host', 'example.com')
|
||||
.end(function(err, res){
|
||||
res.headers.should.have.property('location', '/admin/login');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('.redirect(status, url)', function(){
|
||||
@@ -287,6 +129,23 @@ describe('res', function(){
|
||||
done();
|
||||
})
|
||||
})
|
||||
|
||||
it('should encode the url', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.redirect('http://example.com/?param=<script>alert("hax");</script>');
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.set('Host', 'http://example.com')
|
||||
.set('Accept', 'text/plain, */*')
|
||||
.end(function(err, res){
|
||||
res.text.should.equal('Moved Temporarily. Redirecting to http://example.com/?param=%3Cscript%3Ealert(%22hax%22);%3C/script%3E');
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('when accepting neither text or html', function(){
|
||||
|
||||
+6
-4
@@ -206,11 +206,11 @@ describe('res', function(){
|
||||
})
|
||||
|
||||
describe('when .statusCode is 204', function(){
|
||||
it('should strip Content-* fields & body', function(done){
|
||||
it('should strip Content-* fields, Transfer-Encoding field, and body', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.status(204).send('foo');
|
||||
res.status(204).set('Transfer-Encoding', 'chunked').send('foo');
|
||||
});
|
||||
|
||||
request(app)
|
||||
@@ -218,6 +218,7 @@ describe('res', function(){
|
||||
.end(function(err, res){
|
||||
res.headers.should.not.have.property('content-type');
|
||||
res.headers.should.not.have.property('content-length');
|
||||
res.headers.should.not.have.property('transfer-encoding');
|
||||
res.text.should.equal('');
|
||||
done();
|
||||
})
|
||||
@@ -225,11 +226,11 @@ describe('res', function(){
|
||||
})
|
||||
|
||||
describe('when .statusCode is 304', function(){
|
||||
it('should strip Content-* fields & body', function(done){
|
||||
it('should strip Content-* fields, Transfer-Encoding field, and body', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.status(304).send('foo');
|
||||
res.status(304).set('Transfer-Encoding', 'chunked').send('foo');
|
||||
});
|
||||
|
||||
request(app)
|
||||
@@ -237,6 +238,7 @@ describe('res', function(){
|
||||
.end(function(err, res){
|
||||
res.headers.should.not.have.property('content-type');
|
||||
res.headers.should.not.have.property('content-length');
|
||||
res.headers.should.not.have.property('transfer-encoding');
|
||||
res.text.should.equal('');
|
||||
done();
|
||||
})
|
||||
|
||||
@@ -127,7 +127,7 @@ describe('res', function(){
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
describe('with a relative path', function(){
|
||||
it('should transfer the file', function(done){
|
||||
var app = express();
|
||||
@@ -144,7 +144,7 @@ describe('res', function(){
|
||||
done();
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
it('should serve relative to "root"', function(done){
|
||||
var app = express();
|
||||
|
||||
@@ -160,7 +160,7 @@ describe('res', function(){
|
||||
done();
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
it('should consider ../ malicious when "root" is not set', function(done){
|
||||
var app = express();
|
||||
|
||||
@@ -172,7 +172,7 @@ describe('res', function(){
|
||||
.get('/')
|
||||
.expect(403, done);
|
||||
})
|
||||
|
||||
|
||||
it('should allow ../ when "root" is set', function(done){
|
||||
var app = express();
|
||||
|
||||
@@ -184,7 +184,7 @@ describe('res', function(){
|
||||
.get('/')
|
||||
.expect(200, done);
|
||||
})
|
||||
|
||||
|
||||
it('should disallow requesting out of "root"', function(done){
|
||||
var app = express();
|
||||
|
||||
@@ -196,7 +196,7 @@ describe('res', function(){
|
||||
.get('/')
|
||||
.expect(403, done);
|
||||
})
|
||||
|
||||
|
||||
it('should next(404) when not found', function(done){
|
||||
var app = express()
|
||||
, calls = 0;
|
||||
@@ -208,7 +208,7 @@ describe('res', function(){
|
||||
app.use(function(req, res){
|
||||
assert(0, 'this should not be called');
|
||||
});
|
||||
|
||||
|
||||
app.use(function(err, req, res, next){
|
||||
++calls;
|
||||
next(err);
|
||||
|
||||
@@ -24,6 +24,27 @@ describe('res', function(){
|
||||
res.get('ETag').should.equal('123');
|
||||
})
|
||||
})
|
||||
|
||||
describe('.set(field, values)', function(){
|
||||
it('should set multiple response header fields', function(done){
|
||||
var app = express();
|
||||
|
||||
app.use(function(req, res){
|
||||
res.set('Set-Cookie', ["type=ninja", "language=javascript"]);
|
||||
res.send(res.get('Set-Cookie'));
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/')
|
||||
.expect('["type=ninja","language=javascript"]', done);
|
||||
})
|
||||
|
||||
it('should coerce to an array of strings', function(){
|
||||
res.headers = {};
|
||||
res.set('ETag', [123, 456]);
|
||||
JSON.stringify(res.get('ETag')).should.equal('["123","456"]');
|
||||
})
|
||||
})
|
||||
|
||||
describe('.set(object)', function(){
|
||||
it('should set multiple fields', function(done){
|
||||
|
||||
@@ -2,6 +2,26 @@
|
||||
var utils = require('../lib/utils')
|
||||
, assert = require('assert');
|
||||
|
||||
describe('utils.etag(body)', function(){
|
||||
|
||||
var str = 'Hello CRC';
|
||||
var strUTF8 = '<!DOCTYPE html>\n<html>\n<head>\n</head>\n<body><p>自動販売</p></body></html>';
|
||||
|
||||
it('should support strings', function(){
|
||||
utils.etag(str).should.eql('"-2034458343"');
|
||||
})
|
||||
|
||||
it('should support utf8 strings', function(){
|
||||
utils.etag(strUTF8).should.eql('"1395090196"');
|
||||
})
|
||||
|
||||
it('should support buffer', function(){
|
||||
utils.etag(new Buffer(strUTF8)).should.eql('"1395090196"');
|
||||
utils.etag(new Buffer(str)).should.eql('"-2034458343"');
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe('utils.isAbsolute()', function(){
|
||||
it('should support windows', function(){
|
||||
assert(utils.isAbsolute('c:\\'));
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário