@jen OK, I tried to isolate the issue, remove all the other cruft from the demo, and I can easily reproduce it now. Basically, all I have to do is compare the content-length to the event.body length (once normalized as a Buffer). Here’s my demo functions:
var Buffer = require( "buffer" ).Buffer;
// ----------------------------------------------------------------------------------- //
// ----------------------------------------------------------------------------------- //
export async function handler( event, context ) {
// Normalize body into a Buffer.
var bodyBuffer = ( event.body instanceof Buffer )
? event.body
: Buffer.from( event.body, ( event.isBase64Encoded ? "base64" : "utf8" ) )
;
// Create a copy of the event for echoing that won't include the massive body.
var eventCopy = { ...event };
delete( eventCopy.body );
return({
statusCode: 200,
body: JSON.stringify({
contentLength: ( +event.headers[ "content-length" ] || "not-provided" ),
bodyLength: bodyBuffer.length,
eventCopy: eventCopy
})
});
}
As you can see, all I’m doing here is:
- Coercing the
event.body to be a Buffer based on the encoding.
- Echoing the
content-length header (sent by the client) and the .length of the Buffer.
If I run this locally using lambda-serve, I get the following output:
{
"contentLength": 70,
"bodyLength": 70,
"eventCopy": {
"path": "/inspect-body",
"httpMethod": "PUT",
"queryStringParameters": {},
"headers": {
"content-type": "application/octet-stream",
"user-agent": "PostmanRuntime/7.25.0",
"accept": "*/*",
"cache-control": "no-cache",
"postman-token": "cfa903c7-fdab-404d-9b3b-843faf7f1baa",
"host": "localhost:9000",
"accept-encoding": "gzip, deflate, br",
"connection": "keep-alive",
"content-length": "70"
},
"isBase64Encoded": false
}
}
Locally with lambda-serve it works fine – both the content-length and the body .length are 70.
Now, if I run the same request against production, I get the following:
{
"contentLength": 70,
"bodyLength": 84,
"eventCopy": {
"path": "/.netlify/functions/inspect-body",
"httpMethod": "PUT",
"headers": {
"accept": "*/*",
"cache-control": "no-cache",
"client-ip": "xxxxxxxxxx",
"connection": "keep-alive",
"content-length": "70",
"content-type": "application/octet-stream",
"origin": "xxxxxxxxxx",
"postman-token": "bb1d1a1c-3f95-4cb7-8f54-1bd270dfabe9",
"user-agent": "PostmanRuntime/7.25.0",
"via": "https/1.1 Netlify[b3024e0e-7358-451a-a734-1a757aafbf44] (ApacheTrafficServer/7.1.11)",
"x-bb-ab": "0.285616",
"x-bb-client-request-uuid": "b3024e0e-7358-451a-a734-1a757aafbf44-3451633",
"x-bb-ip": "xxxxxxxxxx",
"x-bb-loop": "1",
"x-cdn-domain": "www.bitballoon.com",
"x-country": "US",
"x-datadog-parent-id": "1434013172083956058",
"x-datadog-sampling-priority": "0",
"x-datadog-trace-id": "5612490752269226137",
"x-forwarded-for": "xxxxxxxxxx",
"x-forwarded-proto": "https",
"x-nf-client-connection-ip": "xxxxxxxxxx"
},
"multiValueHeaders": {
"Accept": [
"*/*"
],
"Cache-Control": [
"no-cache"
],
"Client-Ip": [
"xxxxxxxxxx"
],
"Connection": [
"keep-alive"
],
"Content-Length": [
"70"
],
"Content-Type": [
"application/octet-stream"
],
"Origin": [
"xxxxxxxxxx"
],
"Postman-Token": [
"bb1d1a1c-3f95-4cb7-8f54-1bd270dfabe9"
],
"User-Agent": [
"PostmanRuntime/7.25.0"
],
"Via": [
"https/1.1 Netlify[b3024e0e-7358-451a-a734-1a757aafbf44] (ApacheTrafficServer/7.1.11)"
],
"X-Bb-Ab": [
"0.285616"
],
"X-Bb-Client-Request-Uuid": [
"b3024e0e-7358-451a-a734-1a757aafbf44-3451633"
],
"X-Bb-Ip": [
"xxxxxxxxxx"
],
"X-Bb-Loop": [
"1"
],
"X-Cdn-Domain": [
"www.bitballoon.com"
],
"X-Country": [
"US"
],
"X-Datadog-Parent-Id": [
"1434013172083956058"
],
"X-Datadog-Sampling-Priority": [
"0"
],
"X-Datadog-Trace-Id": [
"5612490752269226137"
],
"X-Forwarded-For": [
"xxxxxxxxxx"
],
"X-Forwarded-Proto": [
"https"
],
"X-Nf-Client-Connection-Ip": [
"xxxxxxxxxx"
]
},
"queryStringParameters": {},
"multiValueQueryStringParameters": {},
"isBase64Encoded": false
}
}
This time, notice that the content-length is 70, but the .length on the body is 84.
Hopefully this isolated example helps!