Skip to content

Commit

Permalink
feat(lambda-at-edge): no-op rewrite support (#759)
Browse files Browse the repository at this point in the history
  • Loading branch information
dphang authored Nov 3, 2020
1 parent dff1d46 commit 2107ab1
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 9 deletions.
12 changes: 9 additions & 3 deletions packages/libs/lambda-at-edge/src/api-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,21 @@ export const handler = async (
let isNonDynamicRoute =
buildManifest.apis.nonDynamic[normaliseUri(request.uri)];

let uri = normaliseUri(request.uri);

if (!isNonDynamicRoute) {
const customRewrite = getRewritePath(request.uri, routesManifest);
const customRewrite = getRewritePath(
request.uri,
routesManifest,
router(manifest),
uri
);
if (customRewrite) {
request.uri = customRewrite;
uri = normaliseUri(request.uri);
}
}

const uri = normaliseUri(request.uri);

const pagePath = router(manifest)(uri);

if (!pagePath) {
Expand Down
11 changes: 10 additions & 1 deletion packages/libs/lambda-at-edge/src/default-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ const router = (
return ssr.nonDynamic[normalisedUri];
}

if (html.nonDynamic[normalisedUri]) {
return html.nonDynamic[normalisedUri];
}

for (const route in allDynamicRoutes) {
const { file, regex } = allDynamicRoutes[route];

Expand Down Expand Up @@ -311,7 +315,12 @@ const handleOriginRequest = async ({

// Handle custom rewrites, but don't rewrite non-dynamic pages, public files or data requests per Next.js docs: https://nextjs.org/docs/api-reference/next.config.js/rewrites
if (!isNonDynamicRoute && !isDataReq) {
const customRewrite = getRewritePath(request.uri, routesManifest);
const customRewrite = getRewritePath(
request.uri,
routesManifest,
router(manifest),
uri
);
if (customRewrite) {
request.uri = customRewrite;
uri = normaliseUri(request.uri);
Expand Down
19 changes: 17 additions & 2 deletions packages/libs/lambda-at-edge/src/routing/rewriter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,33 @@ import { RewriteData, RoutesManifest } from "../../types";
* Get the rewrite of the given path, if it exists. Otherwise return null.
* @param path
* @param routesManifest
* @param router
* @param normalisedPath
*/
export function getRewritePath(
path: string,
routesManifest: RoutesManifest
routesManifest: RoutesManifest,
router: (uri: string) => string | null,
normalisedPath: string
): string | null {
const rewrites: RewriteData[] = routesManifest.rewrites;

for (const rewrite of rewrites) {
const match = matchPath(path, rewrite.source);

if (match) {
return compileDestination(rewrite.destination, match.params);
const destination = compileDestination(rewrite.destination, match.params);

// No-op rewrite support: skip to next rewrite if path does not map to existing non-dynamic and dynamic routes
if (path === destination) {
const url = router(normalisedPath);

if (url === "pages/404.html" || url === "pages/_error.js") {
continue;
}
}

return destination;
}
}

Expand Down
57 changes: 54 additions & 3 deletions packages/libs/lambda-at-edge/tests/routing/rewriter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { RoutesManifest } from "../../types";
describe("Rewriter Tests", () => {
describe("getRewritePath()", () => {
let routesManifest: RoutesManifest;
let router: (path: string) => string | null;

beforeAll(() => {
routesManifest = {
Expand Down Expand Up @@ -32,7 +33,12 @@ describe("Rewriter Tests", () => {
regex: "^/invalid-destination$"
}
],
redirects: []
redirects: [],
headers: []
};

router = (path: string): string | null => {
return path;
};
});

Expand All @@ -46,9 +52,54 @@ describe("Rewriter Tests", () => {
${"/external"} | ${"https://example.com"}
${"/invalid-destination"} | ${null}
`(
"redirects path $path to $expectedRedirect",
"rewrites path $path to $expectedRewrite",
({ path, expectedRewrite }) => {
const rewrite = getRewritePath(path, routesManifest);
const rewrite = getRewritePath(path, routesManifest, router, path);

if (expectedRewrite) {
expect(rewrite).toEqual(expectedRewrite);
} else {
expect(rewrite).toBeNull();
}
}
);

it.each`
path | expectedRewrite
${"/a"} | ${"/a"}
${"/b"} | ${"/another/b"}
`(
"no-op rewrite: rewrites $path to $expectedRewrite",
({ path, expectedRewrite }) => {
routesManifest = {
basePath: "",
rewrites: [
{
source: "/:path*",
destination: "/:path*",
regex: "^(?:/((?:[^/]+?)(?:/(?:[^/]+?))*))?$"
},
{
source: "/:path*",
destination: "/another/:path*",
regex: "^/path(?:/([^/]+?))$"
}
],
redirects: [],
headers: []
};

router = (path: string): string | null => {
if (path === "/a") {
return "pages/a.html";
} else if (path === "/b") {
return "pages/404.html";
} else {
return null;
}
};

const rewrite = getRewritePath(path, routesManifest, router, path);

if (expectedRewrite) {
expect(rewrite).toEqual(expectedRewrite);
Expand Down
1 change: 1 addition & 0 deletions packages/libs/lambda-at-edge/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export type RedirectData = {
export type RewriteData = {
source: string;
destination: string;
regex: string;
};

export type Header = {
Expand Down

0 comments on commit 2107ab1

Please sign in to comment.