-
Notifications
You must be signed in to change notification settings - Fork 63
Description
Support plan
- is this issue currently blocking your project? (no):
- is this issue affecting a production system? (no):
Context
- node version: 14.15.3
- module version with issue: 9.0.2
- last module version without issue: I don't know but I do know the commit when this was added which is 7988c2d
- environment (e.g. node, browser, native): node
- used with (e.g. hapi application, another framework, standalone, ...): hapi application
- any other relevant information: This is replicable with a simple example. Although I talk about DELETE having the issue, the other methods of
GET, HEAD, DELETE, OPTIONS and CONNECT.probably have the same problem.
What are you trying to achieve or the steps to reproduce?
I am trying to use h2o2 to proxy a DELETE method with a body attached to the DELETE method when using passThrough: true. I get back a Bad Request because h2o2 is deleting the content-length header
https://github.com/hapijs/h2o2/blob/master/lib/index.js#L111
The content-length looks to have been removed due to this earlier issue #77 from this commit 7988c2d
Since h2o2 removes the content-length, there is an assumption that all REST methods such as DELETE, OPTIONS, GET, etc... will default to Transfer-Encoding: chunked when they have a body for NodeJS but it looks like only POST does that per this comment from NodeJS:
nodejs/node#19179 (comment)
Example code below reproduces this issue with curl commands as well as a workaround for anyone facing this currently who are not using this proxy with bassmaster:
'use strict';
const Hapi = require('@hapi/hapi');
const H2o2 = require('@hapi/h2o2');
/**
* Add this to a index.js and then:
* npm init
* npm install @hapi/h2o2
* npm install @hapi/hapi
*
* node index.js
*
* Then run any of the curl commands below to see the bug and workaround:
* curl -H 'Content-Type: application/json' -d '{ "test": "test" }' -X DELETE http://127.0.0.1:5050/bug
* curl -H 'Content-Type: application/json' -d '{ "test": "test" }' -X DELETE http://127.0.0.1:5050/work_around
*/
const start = async function() {
const server = Hapi.server({ address: '127.0.0.1', port: 5050 });
await server.register(H2o2);
// non-proxy delete route you can send a body through curl without issues:
// curl -H 'Content-Type: application/json' -d '{ "test": "test" }' -X DELETE http://127.0.0.1:5050/
server.route({
method: 'DELETE',
path: '/',
handler: function () {
return Promise.resolve({ status: "ok" });
}
});
// proxy route with the bug where you cannot send a body through curl because of the deletion of content-length
// curl -H 'Content-Type: application/json' -d '{ "test": "test" }' -X DELETE http://127.0.0.1:5050/bug
server.route({
method: 'DELETE',
path: '/bug',
handler: {
proxy: {
passThrough: true,
uri: 'http://127.0.0.1:5050',
}
}
});
// workaround proxy route where I readd the content-length even though it was deleted.
// curl -H 'Content-Type: application/json' -d '{ "test": "test" }' -X DELETE http://127.0.0.1:5050/work_around
server.route({
method: 'DELETE',
path: '/work_around',
handler: {
proxy: {
passThrough: true,
mapUri: function (request) {
return {
headers: { 'content-length': request.headers['content-length'] },
uri: 'http://127.0.0.1:5050'
};
},
}
}
});
await server.start();
console.log(`Direct connection example: curl -H 'Content-Type: application/json' -d '{ "test": "test" }' -X DELETE http://${server.info.address}:${server.info.port}/`);
console.log(`bug example: curl -H 'Content-Type: application/json' -d '{ "test": "test" }' -X DELETE http://${server.info.address}:${server.info.port}/bug`);
console.log(`work around example: curl -H 'Content-Type: application/json' -d '{ "test": "test" }' -X DELETE http://${server.info.address}:${server.info.port}/work_around`);
console.log(`Server started at: http://${server.info.address}:${server.info.port}`);
}
start();What was the result you got?
I get back invalid Bad Request from trying to proxy a body through DELETE method when passThrough is true.
What result did you expect?
I should be able to use a body with DELETE through the proxy without workarounds.