Skip to content

Commit

Permalink
http: Improve HTTP Expect header handling
Browse files Browse the repository at this point in the history
  • Loading branch information
faridnsh committed Feb 16, 2014
1 parent dbb8b27 commit 3227160
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 7 deletions.
11 changes: 11 additions & 0 deletions doc/api/http.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,17 @@ request body.
Note that when this event is emitted and handled, the `request` event will
not be emitted.

### Event: 'checkExpectation'

`function (request, response) { }`

Emitted each time a request with an http Expect header is received, where the
value is not 100-continue. If this event isn't listened for, the server will
automatically respond with a 417 Expectation Failed as appropriate.

Note that when this event is emitted and handled, the `request` event will
not be emitted.

### Event: 'connect'

`function (request, socket, head) { }`
Expand Down
22 changes: 15 additions & 7 deletions lib/_http_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -492,14 +492,22 @@ function connectionListener(socket) {
}

if (!util.isUndefined(req.headers.expect) &&
(req.httpVersionMajor == 1 && req.httpVersionMinor == 1) &&
continueExpression.test(req.headers['expect'])) {
res._expect_continue = true;
if (EventEmitter.listenerCount(self, 'checkContinue') > 0) {
self.emit('checkContinue', req, res);
(req.httpVersionMajor == 1 && req.httpVersionMinor == 1)) {
if (continueExpression.test(req.headers['expect'])) {
res._expect_continue = true;
if (EventEmitter.listenerCount(self, 'checkContinue') > 0) {
self.emit('checkContinue', req, res);
} else {
res.writeContinue();
self.emit('request', req, res);
}
} else {
res.writeContinue();
self.emit('request', req, res);
if (EventEmitter.listenerCount(self, 'checkExpectation') > 0) {
self.emit('checkExpectation', req, res);
} else {
res.writeHead(417);
res.end();
}
}
} else {
self.emit('request', req, res);
Expand Down
43 changes: 43 additions & 0 deletions test/simple/test-http-expect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var common = require('../common');
var assert = require('assert');
var http = require('http');
var server = http.createServer(function (req, res) {
throw new Error('This shouldn\'t have been called');
}).listen(common.PORT);

server.on('listening', function() {
var options = {
port: common.PORT,
headers: { 'Expect': 'meoww' }
};
http.request(options).on('response', function(res) {
assert.equal(417, res.statusCode, 'Final status code was ' + res.statusCode + ', not 417.');
server.on('checkExpectation', common.mustCall(function checkExpectaionHandler(req, res) {
res.end();
}));
http.request(options).on('response', function(res) {
process.exit();
});
});
});

0 comments on commit 3227160

Please sign in to comment.