Permalink
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...
1 parent 04af2c6 commit 1ce13cbcdf6d9122ba97aa5c3abac4f88d4d96e5 @tj tj committed Jul 20, 2011
Showing with 76 additions and 29 deletions.
  1. +45 −29 lib/patch.js
  2. +31 −0 test/connect.test.js
View
@@ -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
@@ -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();

0 comments on commit 1ce13cb

Please sign in to comment.