Skip to content

Commit ee964c4

Browse files
authored
Merge pull request #12 from thefrontside/cl/redirect-response
✨ respond with redirects
2 parents 1e71844 + 4373ed9 commit ee964c4

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

lib/middleware/http-responses.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,21 @@ export function* respondNotFound(): Operation<never> {
2222
throw new Error("This code is unreachable, but TypeScript don't know.");
2323
}
2424

25+
export interface RedirectOptions {
26+
permanent?: boolean;
27+
}
28+
29+
export function* respondRedirect(
30+
url: string | URL,
31+
options: RedirectOptions = {},
32+
): Operation<never> {
33+
let status = options.permanent ? 308 : 307;
34+
let respond = yield* ResponseContext;
35+
respond(Response.redirect(url, status));
36+
yield* suspend();
37+
throw new Error("This code is unreachable, but TypeScript don't know.");
38+
}
39+
2540
export function httpResponsesMiddleware(): HTTPMiddleware {
2641
return function* httpResponses(request, next): Operation<Response> {
2742
try {

test/middleware/http-responses.test.ts

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import { describe, expect, it } from "../suite.ts";
2-
import { concat, httpResponsesMiddleware, respondNotFound } from "../../mod.ts";
2+
import {
3+
concat,
4+
httpResponsesMiddleware,
5+
respondNotFound,
6+
respondRedirect,
7+
} from "../../mod.ts";
38

49
describe("http responses middleware", () => {
510
it("can short circuit a middleware stack with a 404", function* () {
@@ -18,4 +23,46 @@ describe("http responses middleware", () => {
1823

1924
expect(response.status).toEqual(404);
2025
});
26+
27+
it("can short circuit a middleware stack with a temporary redirect", function* () {
28+
let handler = concat(
29+
httpResponsesMiddleware(),
30+
function* () {
31+
return yield* respondRedirect("https://localhost/other.html");
32+
},
33+
);
34+
35+
let request = new Request("http://localhost/test.html");
36+
37+
let response = yield* handler(request, function* () {
38+
throw new Error(`should not reach here.`);
39+
});
40+
41+
expect(response.status).toEqual(307);
42+
expect(response.headers.get("location")).toEqual(
43+
"https://localhost/other.html",
44+
);
45+
});
46+
47+
it("can short circuit a middleware stack with a permanent redirect", function* () {
48+
let handler = concat(
49+
httpResponsesMiddleware(),
50+
function* () {
51+
return yield* respondRedirect("https://localhost/other.html", {
52+
permanent: true,
53+
});
54+
},
55+
);
56+
57+
let request = new Request("http://localhost/test.html");
58+
59+
let response = yield* handler(request, function* () {
60+
throw new Error(`should not reach here.`);
61+
});
62+
63+
expect(response.status).toEqual(308);
64+
expect(response.headers.get("location")).toEqual(
65+
"https://localhost/other.html",
66+
);
67+
});
2168
});

0 commit comments

Comments
 (0)