Skip to content

Commit

Permalink
fix(routing): don't attach locals to request (withastro#12647)
Browse files Browse the repository at this point in the history
* fix(routing): don't attach locals to request

* apply feedback
  • Loading branch information
ematipico authored Dec 6, 2024
1 parent a71e9b9 commit 8f8f15c
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 20 deletions.
1 change: 0 additions & 1 deletion packages/astro/src/core/app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,6 @@ export class App {
this.#logger.error(null, error.stack!);
return this.#renderError(request, { status: 500, error, clientAddress });
}
Reflect.set(request, clientLocalsSymbol, locals);
}
if (!routeData) {
routeData = this.match(request);
Expand Down
3 changes: 0 additions & 3 deletions packages/astro/src/core/base-pipeline.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { setGetEnv } from '../env/runtime.js';
import { createI18nMiddleware } from '../i18n/middleware.js';
import type { ComponentInstance } from '../types/astro.js';
import type { MiddlewareHandler, RewritePayload } from '../types/public/common.js';
Expand All @@ -10,8 +9,6 @@ import type {
SSRResult,
} from '../types/public/internal.js';
import { createOriginCheckMiddleware } from './app/middlewares.js';
import { AstroError } from './errors/errors.js';
import { AstroErrorData } from './errors/index.js';
import type { Logger } from './logger/core.js';
import { NOOP_MIDDLEWARE_FN } from './middleware/noop-middleware.js';
import { sequence } from './middleware/sequence.js';
Expand Down
16 changes: 11 additions & 5 deletions packages/astro/src/core/middleware/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ export type CreateContext = {
* User defined default locale
*/
defaultLocale: string;

/**
* Initial value of the locals
*/
locals: App.Locals;
};

/**
Expand All @@ -49,6 +54,7 @@ function createContext({
params = {},
userDefinedLocales = [],
defaultLocale = '',
locals,
}: CreateContext): APIContext {
let preferredLocale: string | undefined = undefined;
let preferredLocaleList: string[] | undefined = undefined;
Expand Down Expand Up @@ -104,15 +110,15 @@ function createContext({
return clientIpAddress;
},
get locals() {
let locals = Reflect.get(request, clientLocalsSymbol);
// TODO: deprecate this usage. This is used only by the edge middleware for now, so its usage should be basically none.
let _locals = locals ?? Reflect.get(request, clientLocalsSymbol);
if (locals === undefined) {
locals = {};
Reflect.set(request, clientLocalsSymbol, locals);
_locals = {};
}
if (typeof locals !== 'object') {
if (typeof _locals !== 'object') {
throw new AstroError(AstroErrorData.LocalsNotAnObject);
}
return locals;
return _locals;
},
set locals(_) {
throw new AstroError(AstroErrorData.LocalsReassigned);
Expand Down
5 changes: 0 additions & 5 deletions packages/astro/src/core/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ export interface CreateRequestOptions {
routePattern: string;
}

const clientLocalsSymbol = Symbol.for('astro.locals');

/**
* Used by astro internals to create a web standard request object.
*
Expand All @@ -39,7 +37,6 @@ export function createRequest({
method = 'GET',
body = undefined,
logger,
locals,
isPrerendered = false,
routePattern,
}: CreateRequestOptions): Request {
Expand Down Expand Up @@ -93,7 +90,5 @@ export function createRequest({
});
}

Reflect.set(request, clientLocalsSymbol, locals ?? {});

return request;
}
3 changes: 2 additions & 1 deletion packages/astro/src/vite-plugin-astro-server/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ export async function handleRoute({
let mod: ComponentInstance | undefined = undefined;
let route: RouteData;
const middleware = (await loadMiddleware(loader)).onRequest;
// This is required for adapters to set locals in dev mode. They use a dev server middleware to inject locals to the `http.IncomingRequest` object.
const locals = Reflect.get(incomingRequest, clientLocalsSymbol);

const { preloadedComponent } = matchedRoute;
Expand Down Expand Up @@ -242,7 +243,7 @@ export async function handleRoute({
const fourOhFourRoute = await matchRoute('/404', manifestData, pipeline);
if (fourOhFourRoute) {
renderContext = await RenderContext.create({
locals,
locals: {},
pipeline,
pathname,
middleware: isDefaultPrerendered404(fourOhFourRoute.route) ? undefined : middleware,
Expand Down
17 changes: 17 additions & 0 deletions packages/astro/test/units/routing/api-context.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,21 @@ describe('createAPIContext', () => {

assert.equal(context.clientAddress, '192.0.2.43');
});

it('should return the correct locals', () => {
const request = new Request('http://example.com', {
headers: {
'x-forwarded-for': '192.0.2.43, 172.16.58.3',
},
});

const context = createContext({
request,
locals: {
foo: 'bar',
},
});

assert.deepEqual(context.locals, { foo: 'bar' });
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -87,16 +87,18 @@ describe('endpoints', () => {
url: '/streaming',
});

const locals = { cancelledByTheServer: false };
req[Symbol.for('astro.locals')] = locals;

container.handle(req, res);

await new Promise((resolve) => setTimeout(resolve, 500));
res.emit('close');

await done;
try {
await done;

assert.equal(locals.cancelledByTheServer, true);
assert.ok(true);

} catch (err) {
assert.fail(err)
}
});
});

0 comments on commit 8f8f15c

Please sign in to comment.