mirror of
https://github.com/withastro/astro.git
synced 2024-12-16 21:46:22 -05:00
fix(routing): don't attach locals to request (#12647)
* fix(routing): don't attach locals to request * apply feedback
This commit is contained in:
parent
a71e9b93b3
commit
8f8f15ca1d
7 changed files with 37 additions and 20 deletions
|
@ -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);
|
||||
|
|
|
@ -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';
|
||||
|
@ -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';
|
||||
|
|
|
@ -39,6 +39,11 @@ export type CreateContext = {
|
|||
* User defined default locale
|
||||
*/
|
||||
defaultLocale: string;
|
||||
|
||||
/**
|
||||
* Initial value of the locals
|
||||
*/
|
||||
locals: App.Locals;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -49,6 +54,7 @@ function createContext({
|
|||
params = {},
|
||||
userDefinedLocales = [],
|
||||
defaultLocale = '',
|
||||
locals,
|
||||
}: CreateContext): APIContext {
|
||||
let preferredLocale: string | undefined = undefined;
|
||||
let preferredLocaleList: string[] | undefined = undefined;
|
||||
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
@ -39,7 +37,6 @@ export function createRequest({
|
|||
method = 'GET',
|
||||
body = undefined,
|
||||
logger,
|
||||
locals,
|
||||
isPrerendered = false,
|
||||
routePattern,
|
||||
}: CreateRequestOptions): Request {
|
||||
|
@ -93,7 +90,5 @@ export function createRequest({
|
|||
});
|
||||
}
|
||||
|
||||
Reflect.set(request, clientLocalsSymbol, locals ?? {});
|
||||
|
||||
return request;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -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,
|
||||
|
|
|
@ -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' });
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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');
|
||||
|
||||
try {
|
||||
await done;
|
||||
|
||||
assert.equal(locals.cancelledByTheServer, true);
|
||||
assert.ok(true);
|
||||
|
||||
} catch (err) {
|
||||
assert.fail(err)
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue