Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added response "header" event allowing augmentation

this will be used in the session middleware, and could
be used elsewhere. Ideally Node would provide a hook for us...
  • Loading branch information...
commit 1ce13cbcdf6d9122ba97aa5c3abac4f88d4d96e5 1 parent 04af2c6
@tj tj authored
Showing with 76 additions and 29 deletions.
  1. +45 −29 lib/patch.js
  2. +31 −0 test/connect.test.js
View
74 lib/patch.js
@@ -16,36 +16,52 @@ var http = require('http')
var setHeader = res.setHeader;
+// original _renderHeaders()
-if (!res._hasConnectPatch) {
-
- /**
- * Set header `field` to `val`, special-casing
- * the `Set-Cookie` field for multiple support.
- *
- * @param {String} field
- * @param {String} val
- * @api public
- */
-
- res.setHeader = function(field, val){
- var key = field.toLowerCase()
- , prev;
-
- // special-case Set-Cookie
- if (this._headers && 'set-cookie' == key) {
- if (prev = this.getHeader(field)) {
- val = Array.isArray(prev)
- ? prev.concat(val)
- : [prev, val];
- }
- // charset
- } else if ('content-type' == key && this.charset) {
- val += '; charset=' + this.charset;
+var _renderHeaders = res._renderHeaders;
+
+if (res._hasConnectPatch) return;
+
+/**
+ * Set header `field` to `val`, special-casing
+ * the `Set-Cookie` field for multiple support.
+ *
+ * @param {String} field
+ * @param {String} val
+ * @api public
+ */
+
+res.setHeader = function(field, val){
+ var key = field.toLowerCase()
+ , prev;
+
+ // special-case Set-Cookie
+ if (this._headers && 'set-cookie' == key) {
+ if (prev = this.getHeader(field)) {
+ val = Array.isArray(prev)
+ ? prev.concat(val)
+ : [prev, val];
}
+ // charset
+ } else if ('content-type' == key && this.charset) {
+ val += '; charset=' + this.charset;
+ }
+
+ return setHeader.call(this, field, val);
+};
+
+/**
+ * Proxy `res.end()` to expose a 'header' event,
+ * allowing arbitrary augmentation before the header
+ * fields are written to the socket.
+ *
+ * NOTE: this _only_ supports node's progressive header
+ * field API aka `res.setHeader()`.
+ */
- return setHeader.call(this, field, val);
- };
+res._renderHeaders = function(){
+ this.emit('header');
+ return _renderHeaders.call(this);
+};
- res._hasConnectPatch = true;
-}
+res._hasConnectPatch = true;
View
31 test/connect.test.js
@@ -52,6 +52,37 @@ module.exports = {
{ body: 'blog', status: 200 });
},
+ 'test "header" event': function(){
+ var app = connect.createServer();
+
+ app.use(function(req, res, next){
+ res.on('header', function(){
+ if (req.headers['x-foo']) {
+ res.setHeader('X-Bar', 'baz');
+ }
+ });
+
+ next();
+ });
+
+ app.use(function(req, res){
+ // FIXME: this fails if you do not have any res._headers
+ res.setHeader('Content-Length', 5);
+ res.end('hello');
+ });
+
+ assert.response(app,
+ { url: '/' },
+ function(res){
+ res.headers.should.not.have.property('x-foo');
+ res.headers.should.not.have.property('x-bar');
+ });
+
+ assert.response(app,
+ { url: '/', headers: { 'X-Foo': 'bar' }},
+ { body: 'hello', headers: { 'X-Bar': 'baz' }});
+ },
+
'test path matching': function(){
var n = 0
, app = connect.createServer();
Please sign in to comment.
Something went wrong with that request. Please try again.