Set Content-Length header for OPTIONS requests

Web browsers automatically issue an OPTIONS request in advance of other
HTTP requests when the document's domain does not match the target in
order to facilitate Cross-Origin Resource Sharing. These requests are
forbidden from specifying a body and typically do not specify an
(unecessary) `Length` header.

Node.js automatically adds the `Content-Encoding: chunked` header value
to requests that do not specify a `Length` header. This makes proxied
OPTIONS requests from web browsers invalid.

Explicitly set the `Content-Length` header of all `OPTIONS` requests to
"0", disabling the default "chunked" encoding behavior [2].

[1] http://www.w3.org/TR/cors/
[2] http://nodejs.org/api/http.html
This commit is contained in:
Mike Pennisi 2014-11-24 17:14:48 -05:00
parent aba505d159
commit 8a24a1e18f
2 changed files with 13 additions and 3 deletions

View File

@ -29,7 +29,8 @@ web_o = Object.keys(web_o).map(function(pass) {
*/ */
function deleteLength(req, res, options) { function deleteLength(req, res, options) {
if(req.method === 'DELETE' && !req.headers['content-length']) { if((req.method === 'DELETE' || req.method === 'OPTIONS')
&& !req.headers['content-length']) {
req.headers['content-length'] = '0'; req.headers['content-length'] = '0';
} }
}, },

View File

@ -5,14 +5,23 @@ var webPasses = require('../lib/http-proxy/passes/web-incoming'),
describe('lib/http-proxy/passes/web.js', function() { describe('lib/http-proxy/passes/web.js', function() {
describe('#deleteLength', function() { describe('#deleteLength', function() {
it('should change `content-length`', function() { it('should change `content-length` for DELETE requests', function() {
var stubRequest = { var stubRequest = {
method: 'DELETE', method: 'DELETE',
headers: {} headers: {}
}; };
webPasses.deleteLength(stubRequest, {}, {}); webPasses.deleteLength(stubRequest, {}, {});
expect(stubRequest.headers['content-length']).to.eql('0'); expect(stubRequest.headers['content-length']).to.eql('0');
}) });
it('should change `content-length` for OPTIONS requests', function() {
var stubRequest = {
method: 'OPTIONS',
headers: {}
};
webPasses.deleteLength(stubRequest, {}, {});
expect(stubRequest.headers['content-length']).to.eql('0');
});
}); });
describe('#timeout', function() { describe('#timeout', function() {