From afa8f93a4b07a462c264ff9bbb6152b0b644b9a4 Mon Sep 17 00:00:00 2001 From: Arnaud Gissinger Date: Mon, 24 Aug 2020 11:25:37 +0200 Subject: [PATCH 1/3] fix(lambda) File uploads Ignoring base64 decoding in graphqlHandler for Multipart queries --- packages/apollo-server-lambda/src/lambdaApollo.ts | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/apollo-server-lambda/src/lambdaApollo.ts b/packages/apollo-server-lambda/src/lambdaApollo.ts index fad594122e9..a85e37239f0 100644 --- a/packages/apollo-server-lambda/src/lambdaApollo.ts +++ b/packages/apollo-server-lambda/src/lambdaApollo.ts @@ -32,9 +32,12 @@ export function graphqlLambda( callback, ): void => { context.callbackWaitsForEmptyEventLoop = false; - let { body, isBase64Encoded } = event; + let { body, headers, isBase64Encoded } = event; + let query: Record | Record[]; + const contentType = headers["content-type"] || headers["Content-Type"]; + const isMultipart = (contentType || "").startsWith("multipart/form-data"); - if (body && isBase64Encoded) { + if (body && isBase64Encoded && !isMultipart) { body = Buffer.from(body, 'base64').toString(); } @@ -45,12 +48,7 @@ export function graphqlLambda( }); } - const contentType = event.headers["content-type"] || event.headers["Content-Type"]; - let query: Record | Record[]; - - if (body && event.httpMethod === 'POST' && - contentType && contentType.startsWith("multipart/form-data") - ) { + if (body && event.httpMethod === 'POST' && isMultipart) { query = body as any; } else if (body && event.httpMethod === 'POST') { query = JSON.parse(body); From 034176b3959f6c40417115664e8933e35a693bca Mon Sep 17 00:00:00 2001 From: Arnaud Gissinger Date: Fri, 23 Oct 2020 15:04:39 +0200 Subject: [PATCH 2/3] Update Content-Type comparison to be case insensitive --- packages/apollo-server-lambda/src/ApolloServer.ts | 11 ++++++----- packages/apollo-server-lambda/src/lambdaApollo.ts | 6 ++++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/apollo-server-lambda/src/ApolloServer.ts b/packages/apollo-server-lambda/src/ApolloServer.ts index 34bb0b899e9..09f69a95d60 100644 --- a/packages/apollo-server-lambda/src/ApolloServer.ts +++ b/packages/apollo-server-lambda/src/ApolloServer.ts @@ -252,15 +252,16 @@ export class ApolloServer extends ApolloServerBase { }; const fileUploadHandler = (next: Function) => { - const contentType = - event.headers["content-type"] || event.headers["Content-Type"]; - if (contentType && contentType.startsWith("multipart/form-data") - && typeof processFileUploads === "function") { + const contentType = ( + event.headers['content-type'] || event.headers['Content-Type'] || '' + ).toLowerCase(); + if (contentType.startsWith('multipart/form-data') + && typeof processFileUploads === 'function') { const request = new FileUploadRequest() as IncomingMessage; request.push( Buffer.from( event.body, - event.isBase64Encoded ? "base64" : "ascii" + event.isBase64Encoded ? 'base64' : 'ascii' ) ); request.push(null); diff --git a/packages/apollo-server-lambda/src/lambdaApollo.ts b/packages/apollo-server-lambda/src/lambdaApollo.ts index a85e37239f0..dad6cbba53c 100644 --- a/packages/apollo-server-lambda/src/lambdaApollo.ts +++ b/packages/apollo-server-lambda/src/lambdaApollo.ts @@ -34,8 +34,10 @@ export function graphqlLambda( context.callbackWaitsForEmptyEventLoop = false; let { body, headers, isBase64Encoded } = event; let query: Record | Record[]; - const contentType = headers["content-type"] || headers["Content-Type"]; - const isMultipart = (contentType || "").startsWith("multipart/form-data"); + const contentType = ( + headers['content-type'] || headers['Content-Type'] || '' + ).toLowerCase(); + const isMultipart = contentType.startsWith('multipart/form-data'); if (body && isBase64Encoded && !isMultipart) { body = Buffer.from(body, 'base64').toString(); From 139003f99ccbdb6c6522b8ba79876d1626b63104 Mon Sep 17 00:00:00 2001 From: Trevor Scheer Date: Fri, 30 Oct 2020 12:05:31 -0700 Subject: [PATCH 3/3] Update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd27dafb58f..2661d3fa668 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,7 @@ The version headers in this history reflect the versions of Apollo Server itself - `apollo-server-testing`: types: Allow generic `variables` usage of `query` and `mutate` functions. [PR #4383](https://github.com/apollograpqh/apollo-server/pull/4383) - `apollo-server-core`: Update dependency for `@apollographql/graphql-playground-react` to `v1.7.34` to incorporate [`33c48183`](https://github.com/apollographql/graphql-playground/commit/33c48183229e59f0d21f7f4fdd57bed5a973a5cf) which, as an upstream change, should improve support for `graphql@15` features, like interfaces implementing interfaces. - `apollo-server-express`: Export the `GetMiddlewareOptions` type. [PR #4599](https://github.com/apollograpqh/apollo-server/pull/4599) - +- `apollo-server-lambda`: Fix file uploads - ignore base64 decoding for multipart queries. [PR #4506](https://github.com/apollographql/apollo-server/pull/4506) ## v2.18.2 - `apollo-server-core`: Explicitly include `lru-cache` dependency in `apollo-server-core`'s dependencies. [PR #4600](https://github.com/apollographql/apollo-server/pull/4600)