Skip to content

Commit

Permalink
fix(rewrite): copy body from the request
Browse files Browse the repository at this point in the history
  • Loading branch information
ematipico committed Jun 4, 2024
1 parent ff8004f commit 0409ac1
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/swift-phones-rhyme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Fixes an issue where `Astro.rewrite` wasn't carrying over the body of a `Request` in on-demand pages.
5 changes: 3 additions & 2 deletions packages/astro/src/core/render-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { callMiddleware } from './middleware/callMiddleware.js';
import { sequence } from './middleware/index.js';
import { renderRedirect } from './redirects/render.js';
import { type Pipeline, Slots, getParams, getProps } from './render/index.js';
import { copyRequest } from "./routing/index.js";

/**
* Each request is rendered using a `RenderContext`.
Expand Down Expand Up @@ -224,7 +225,7 @@ export class RenderContext {
if (reroutePayload instanceof Request) {
this.request = reroutePayload;
} else {
this.request = new Request(
this.request = await copyRequest(
new URL(routeData.pathname ?? routeData.route, this.url.origin),
this.request
);
Expand Down Expand Up @@ -416,7 +417,7 @@ export class RenderContext {
if (reroutePayload instanceof Request) {
this.request = reroutePayload;
} else {
this.request = new Request(
this.request = await copyRequest(
new URL(routeData.pathname ?? routeData.route, this.url.origin),
this.request
);
Expand Down
1 change: 1 addition & 0 deletions packages/astro/src/core/routing/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export { createRouteManifest } from './manifest/create.js';
export { deserializeRouteData, serializeRouteData } from './manifest/serialization.js';
export { matchAllRoutes, matchRoute } from './match.js';
export { validateDynamicRouteModule, validateGetStaticPathsResult } from './validation.js';
export { copyRequest } from "./request.js"
27 changes: 27 additions & 0 deletions packages/astro/src/core/routing/request.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* Utility function that creates a new `Request` with a new URL from an old `Request`.
*
* @param newUrl The new `URL`
* @param oldRequest The old `Request`
*/
export async function copyRequest(newUrl: URL, oldRequest: Request): Promise<Request> {
const body = oldRequest.headers.get('content-type') ? oldRequest.blob() : Promise.resolve(undefined);
return body.then((requestBody) => {
return new Request(newUrl, {
method: oldRequest.method,
headers: oldRequest.headers,
body: requestBody,
referrer: oldRequest.referrer,
referrerPolicy: oldRequest.referrerPolicy,
mode: oldRequest.mode,
credentials: oldRequest.credentials,
cache: oldRequest.cache,
redirect: oldRequest.redirect,
integrity: oldRequest.integrity,
signal: oldRequest.signal,
keepalive: oldRequest.keepalive,
})
}

);
}
14 changes: 14 additions & 0 deletions packages/astro/test/fixtures/reroute/src/pages/post/post-a.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
let email = ''
if (Astro.request.method === 'POST') {
try {
const data = await Astro.request.formData();
email = data.get('email')?.toString().trim();
} catch {}
}
return Astro.rewrite('/post/post-b')
---

<h1>Post A</h1>

<h2>{email}</h2>
13 changes: 13 additions & 0 deletions packages/astro/test/fixtures/reroute/src/pages/post/post-b.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
let email = ''
if (Astro.request.method === 'POST') {
try {
const data = await Astro.request.formData();
email = data.get('email')?.toString().trim();
} catch {}
}
---

<h1>Post B</h1>

<h2>{email}</h2>
23 changes: 21 additions & 2 deletions packages/astro/test/rewrite.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { load as cheerioLoad } from 'cheerio';
import testAdapter from './test-adapter.js';
import { loadFixture } from './test-utils.js';

describe('Dev reroute', () => {
describe.only('Dev reroute', () => {
/** @type {import('./test-utils').Fixture} */
let fixture;
let devServer;
Expand Down Expand Up @@ -61,6 +61,7 @@ describe('Dev reroute', () => {

assert.equal($('h1').text(), '404: Not found');
});

});

describe('Build reroute', () => {
Expand Down Expand Up @@ -112,7 +113,7 @@ describe('Build reroute', () => {

it('should render the 404 built-in page', async () => {
try {
const html = await fixture.readFile('/spread/oops/index.html');
await fixture.readFile('/spread/oops/index.html');
assert.fail('Not found');
} catch {
assert.ok;
Expand Down Expand Up @@ -187,6 +188,24 @@ describe('SSR reroute', () => {
const html = await response.text();
assert.equal(html, 'Not found');
});

it.only('should pass the POST data from one page to another', async () => {
const html = await fixture.fetch('/post/post-a', {
method: "POST",
body: JSON.stringify({
email: "[email protected]",
title: "Fix my bugs",
completed: false
}),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
}).then((res) => res.text());
const $ = cheerioLoad(html);

assert.equal($('h1').text(), 'Post B');
assert.match($('h2').text(), /example@example.com/);
});
});

describe('Middleware', () => {
Expand Down

0 comments on commit 0409ac1

Please sign in to comment.