Skip to content

Commit

Permalink
fix(netlify, aws): omit cookies from v1 response (#834)
Browse files Browse the repository at this point in the history
* fix(aws-lambda): omit cookies from v1 response

* feat: use overloads to improve type safety

* chore: lint

* fix: netlify builder function should share netlify lambda implementation

* fix: don't strip `set-cookie` with v1 payload

* fix(netlify): don't strip `set-cookie` headers
  • Loading branch information
danielroe authored Jan 16, 2023
1 parent e7b250f commit 5e484c3
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 85 deletions.
60 changes: 32 additions & 28 deletions src/runtime/entries/aws-lambda.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,18 @@ import "#internal/nitro/virtual/polyfill";
import { withQuery } from "ufo";
import { nitroApp } from "../app";

// Compatibility types that work with AWS v1, AWS v2 & Netlify
type Event =
| Omit<
APIGatewayProxyEvent,
"pathParameters" | "stageVariables" | "requestContext" | "resource"
>
| Omit<
APIGatewayProxyEventV2,
"pathParameters" | "stageVariables" | "requestContext" | "resource"
>;
type Result = Exclude<
APIGatewayProxyResult | APIGatewayProxyResultV2,
string
> & { statusCode: number };

export const handler = async function handler(
event: Event,
export async function handler(
event: APIGatewayProxyEvent,
context: Context
): Promise<APIGatewayProxyResult>;
export async function handler(
event: APIGatewayProxyEventV2,
context: Context
): Promise<Result> {
): Promise<APIGatewayProxyResultV2>;
export async function handler(
event: APIGatewayProxyEvent | APIGatewayProxyEventV2,
context: Context
): Promise<APIGatewayProxyResult | APIGatewayProxyResultV2> {
const query = {
...event.queryStringParameters,
...(event as APIGatewayProxyEvent).multiValueQueryStringParameters,
Expand Down Expand Up @@ -57,18 +50,26 @@ export const handler = async function handler(
body: event.body, // TODO: handle event.isBase64Encoded
});

const outgoingCookies = r.headers["set-cookie"];
const cookies = Array.isArray(outgoingCookies)
? outgoingCookies
: outgoingCookies?.split(",") || [];
if ("cookies" in event || "rawPath" in event) {
const outgoingCookies = r.headers["set-cookie"];
const cookies = Array.isArray(outgoingCookies)
? outgoingCookies
: outgoingCookies?.split(",") || [];

return {
cookies,
statusCode: r.status,
headers: normalizeOutgoingHeaders(r.headers, true),
body: r.body.toString(),
};
}

return {
cookies,
statusCode: r.status,
headers: normalizeOutgoingHeaders(r.headers),
body: r.body.toString(),
};
};
}

function normalizeIncomingHeaders(headers?: APIGatewayProxyEventHeaders) {
return Object.fromEntries(
Expand All @@ -80,11 +81,14 @@ function normalizeIncomingHeaders(headers?: APIGatewayProxyEventHeaders) {
}

function normalizeOutgoingHeaders(
headers: Record<string, string | string[] | undefined>
headers: Record<string, string | string[] | undefined>,
stripCookies = false
) {
const entries = stripCookies
? Object.entries(headers).filter(([key]) => !["set-cookie"].includes(key))
: Object.entries(headers);

return Object.fromEntries(
Object.entries(headers)
.filter(([key]) => !["set-cookie"].includes(key))
.map(([k, v]) => [k, Array.isArray(v) ? v.join(",") : v!])
entries.map(([k, v]) => [k, Array.isArray(v) ? v.join(",") : v!])
);
}
4 changes: 2 additions & 2 deletions src/runtime/entries/netlify-builder.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { builder } from "@netlify/functions";
import { handler as _handler } from "#internal/nitro/entries/aws-lambda";
import { lambda } from "./netlify-lambda";

export const handler = builder(_handler);
export const handler = builder(lambda);
58 changes: 58 additions & 0 deletions src/runtime/entries/netlify-lambda.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import "#internal/nitro/virtual/polyfill";
import type {
Handler,
HandlerResponse,
HandlerContext,
HandlerEvent,
} from "@netlify/functions/dist/main";
import type { APIGatewayProxyEventHeaders } from "aws-lambda";
import { withQuery } from "ufo";
import { nitroApp } from "../app";

export async function lambda(
event: HandlerEvent,
context: HandlerContext
): Promise<HandlerResponse> {
const query = {
...event.queryStringParameters,
...event.multiValueQueryStringParameters,
};
const url = withQuery(event.path, query);
const method = event.httpMethod || "get";

const r = await nitroApp.localCall({
event,
url,
context,
headers: normalizeIncomingHeaders(event.headers),
method,
query,
body: event.body, // TODO: handle event.isBase64Encoded
});

return {
statusCode: r.status,
headers: normalizeOutgoingHeaders(r.headers),
body: r.body.toString(),
};
}

function normalizeIncomingHeaders(headers?: APIGatewayProxyEventHeaders) {
return Object.fromEntries(
Object.entries(headers || {}).map(([key, value]) => [
key.toLowerCase(),
value!,
])
);
}

function normalizeOutgoingHeaders(
headers: Record<string, string | string[] | undefined>
) {
return Object.fromEntries(
Object.entries(headers).map(([k, v]) => [
k,
Array.isArray(v) ? v.join(",") : v!,
])
);
}
57 changes: 2 additions & 55 deletions src/runtime/entries/netlify.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
import "#internal/nitro/virtual/polyfill";
import type {
Handler,
HandlerResponse,
HandlerContext,
HandlerEvent,
} from "@netlify/functions/dist/main";
import type { APIGatewayProxyEventHeaders } from "aws-lambda";
import type { Handler } from "@netlify/functions/dist/main";
import { withQuery } from "ufo";
import { nitroApp } from "../app";
import { getRouteRulesForPath } from "../route-rules";
import { lambda } from "./netlify-lambda";

export const handler: Handler = async function handler(event, context) {
const query = {
Expand All @@ -33,50 +27,3 @@ export const handler: Handler = async function handler(event, context) {

return lambda(event, context);
};

async function lambda(
event: HandlerEvent,
context: HandlerContext
): Promise<HandlerResponse> {
const query = {
...event.queryStringParameters,
...event.multiValueQueryStringParameters,
};
const url = withQuery(event.path, query);
const method = event.httpMethod || "get";

const r = await nitroApp.localCall({
event,
url,
context,
headers: normalizeIncomingHeaders(event.headers),
method,
query,
body: event.body, // TODO: handle event.isBase64Encoded
});

return {
statusCode: r.status,
headers: normalizeOutgoingHeaders(r.headers),
body: r.body.toString(),
};
}

function normalizeIncomingHeaders(headers?: APIGatewayProxyEventHeaders) {
return Object.fromEntries(
Object.entries(headers || {}).map(([key, value]) => [
key.toLowerCase(),
value!,
])
);
}

function normalizeOutgoingHeaders(
headers: Record<string, string | string[] | undefined>
) {
return Object.fromEntries(
Object.entries(headers)
.filter(([key]) => !["set-cookie"].includes(key))
.map(([k, v]) => [k, Array.isArray(v) ? v.join(",") : v!])
);
}

0 comments on commit 5e484c3

Please sign in to comment.