-
Notifications
You must be signed in to change notification settings - Fork 671
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
set Content-Length header in mapApiGatewayEventToHttpRequest #147
Conversation
- without content-length specified, it seems the body of DELETE requests get ignored - per RFC 2616, section 4.3: The presence of a message-body in a request is signaled by the inclusion of a Content-Length or Transfer-Encoding header field in the request's message-headers. A message-body MUST NOT be included in a request if the specification of the request method (section 5.1.1) does not allow sending an entity-body in requests. A server SHOULD read and forward a message-body on any request; if the request method does not include defined semantics for an entity-body, then the message-body SHOULD be ignored when handling the request. - in other words, whether or not it is recommended to have a body in a DELETE request, if the content-length header (or the transfer-encoding header) is set, the message body should be forwarded - concerns: - I'm not sure whether it is necessary to perform more type checking on `event.body`. for instance, if it is an object, it should be passed through a call to `JSON.stringify` before getting the byte length - the header should probably be set only if not already specified This commit is one possible solution to CodeGenieApp#106
will now only set the content-length header if the request has a body and the header is not already set
"if it is an object, it should be passed through a call to JSON.stringify before getting the byte length" - Could you fix the failing tests and I'll get this merged in soon. |
Could you also add a comment: |
Yeah, I can get those addressed tomorrow |
note that by the section of RFC 2616 I quoted above, the bit about content-length applies to other normally bodiless requests, like GET (i.e. if the request has a body, content-length should be set, regardless of whether it is good practice). I bring this up because the failing test cases send a GET request with a body: the header is not set when the dummy event is cloned since my changes add the content-length inside this call which means failure at the later call I'm not really sure what the best way to go about remedying this would be. Maybe something like 'x-apigateway-event': encodeURIComponent(JSON.stringify({
'Content-Length': Buffer.byteLength('Hello serverless'),
...r.eventClone
})), (or the [functionally] equivalent |
Okay. Your PR is method-agnostic so should work for GET also. Maybe make the comment a little more generic |
- fix failing test cases - add comment about motivation for change in index.js
index.js
Outdated
@@ -36,6 +36,10 @@ function mapApiGatewayEventToHttpRequest(event, context, socketPath) { | |||
const eventWithoutBody = Object.assign({}, event) | |||
delete eventWithoutBody.body | |||
|
|||
// NOTE: API Gateway is not setting Content-Length header on any requests even when they have a body |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is true. It correctly sets it for POST and PUT, right? Otherwise we'd be seeing this error on every method. Confirmed methods where it doesn't appear are GET and DELETE and I wouldn't be surprised if OPTIONS also didn't have the header.
index.js
Outdated
@@ -60,7 +64,7 @@ function forwardResponseToApiGateway(server, response, context) { | |||
const bodyBuffer = Buffer.concat(buf) | |||
const statusCode = response.statusCode | |||
const headers = response.headers | |||
|
|||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you remove this address whitespace?
- only if body is present and there are no headers - seems hacky, but ensures that the `x-apigateway-event` header is set properly(?) later (i.e. including the content-length field)
re: does it correctly set for POST/PUT? @ajstocchetti set up a little test for this. running the following lambda as an API gateway integration: const awsServerlessExpress = require('aws-serverless-express');
const app = require('./app');
const server = awsServerlessExpress.createServer(app);
exports.handler = (event, context) => {
const headers = event.headers;
const len = headers && headers['Content-Length'] ? headers['Content-Length'] : null;
const cl = {
method: event.httpMethod,
headers,
contentlength: len,
body: !!event.body,
};
console.log(cl);
return awsServerlessExpress.proxy(server, event, context);
} produces the following output in cloudwatch:
|
also, I'm not sure why that last test is failing, but I don't think it has to do specifically with the changes I've made... |
It's failing in latest version of Node due to Buffer deprecation. I'll remove it from Travis config. I'll open a ticket internally to investigate the content-length header not being sent. Thanks! I'll have my integ tests out for PR soon. I'll merge this in immediately after that gets merged in. |
Could you rebase? The travis config has changed to support the new tests. You may also need to fix some tests. Alternatively if you want to push this to develop branch I can merge and fix from there. |
@brettstack I've changed the base branch to develop |
I've implemented this in a separate branch with some changes. The integ tests are already paying off as they found an issue with doing this with base64Encoded requests. Thanks for all your help and patience. |
<a name="3.3.5"></a> ## [3.3.5](CodeGenieApp/serverless-express@v3.3.4...v3.3.5) (2018-08-20) ### Bug Fixes * apply Content-Length header when missing ([b0927b8](CodeGenieApp/serverless-express@b0927b8)), closes [#147](CodeGenieApp/serverless-express#147) [#106](CodeGenieApp/serverless-express#106) [#130](CodeGenieApp/serverless-express#130) * apply Content-Length header when missing ([#175](CodeGenieApp/serverless-express#175)) ([c2f416b](CodeGenieApp/serverless-express@c2f416b))
Issue #, if available:
#106
Description of changes:
I'm not sure whether it is necessary to perform more type checking onnot necessaryevent.body
. for instance, if it is an object, it should be passed through a call toJSON.stringify
before getting the byte lengththe header should probably be set only if not already specified1ef34b8I would love feedback on this 🙇
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.