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!);
|
this.#logger.error(null, error.stack!);
|
||||||
return this.#renderError(request, { status: 500, error, clientAddress });
|
return this.#renderError(request, { status: 500, error, clientAddress });
|
||||||
}
|
}
|
||||||
Reflect.set(request, clientLocalsSymbol, locals);
|
|
||||||
}
|
}
|
||||||
if (!routeData) {
|
if (!routeData) {
|
||||||
routeData = this.match(request);
|
routeData = this.match(request);
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import { setGetEnv } from '../env/runtime.js';
|
|
||||||
import { createI18nMiddleware } from '../i18n/middleware.js';
|
import { createI18nMiddleware } from '../i18n/middleware.js';
|
||||||
import type { ComponentInstance } from '../types/astro.js';
|
import type { ComponentInstance } from '../types/astro.js';
|
||||||
import type { MiddlewareHandler, RewritePayload } from '../types/public/common.js';
|
import type { MiddlewareHandler, RewritePayload } from '../types/public/common.js';
|
||||||
|
@ -10,8 +9,6 @@ import type {
|
||||||
SSRResult,
|
SSRResult,
|
||||||
} from '../types/public/internal.js';
|
} from '../types/public/internal.js';
|
||||||
import { createOriginCheckMiddleware } from './app/middlewares.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 type { Logger } from './logger/core.js';
|
||||||
import { NOOP_MIDDLEWARE_FN } from './middleware/noop-middleware.js';
|
import { NOOP_MIDDLEWARE_FN } from './middleware/noop-middleware.js';
|
||||||
import { sequence } from './middleware/sequence.js';
|
import { sequence } from './middleware/sequence.js';
|
||||||
|
|
|
@ -39,6 +39,11 @@ export type CreateContext = {
|
||||||
* User defined default locale
|
* User defined default locale
|
||||||
*/
|
*/
|
||||||
defaultLocale: string;
|
defaultLocale: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initial value of the locals
|
||||||
|
*/
|
||||||
|
locals: App.Locals;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -49,6 +54,7 @@ function createContext({
|
||||||
params = {},
|
params = {},
|
||||||
userDefinedLocales = [],
|
userDefinedLocales = [],
|
||||||
defaultLocale = '',
|
defaultLocale = '',
|
||||||
|
locals,
|
||||||
}: CreateContext): APIContext {
|
}: CreateContext): APIContext {
|
||||||
let preferredLocale: string | undefined = undefined;
|
let preferredLocale: string | undefined = undefined;
|
||||||
let preferredLocaleList: string[] | undefined = undefined;
|
let preferredLocaleList: string[] | undefined = undefined;
|
||||||
|
@ -104,15 +110,15 @@ function createContext({
|
||||||
return clientIpAddress;
|
return clientIpAddress;
|
||||||
},
|
},
|
||||||
get locals() {
|
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) {
|
if (locals === undefined) {
|
||||||
locals = {};
|
_locals = {};
|
||||||
Reflect.set(request, clientLocalsSymbol, locals);
|
|
||||||
}
|
}
|
||||||
if (typeof locals !== 'object') {
|
if (typeof _locals !== 'object') {
|
||||||
throw new AstroError(AstroErrorData.LocalsNotAnObject);
|
throw new AstroError(AstroErrorData.LocalsNotAnObject);
|
||||||
}
|
}
|
||||||
return locals;
|
return _locals;
|
||||||
},
|
},
|
||||||
set locals(_) {
|
set locals(_) {
|
||||||
throw new AstroError(AstroErrorData.LocalsReassigned);
|
throw new AstroError(AstroErrorData.LocalsReassigned);
|
||||||
|
|
|
@ -24,8 +24,6 @@ export interface CreateRequestOptions {
|
||||||
routePattern: string;
|
routePattern: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const clientLocalsSymbol = Symbol.for('astro.locals');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used by astro internals to create a web standard request object.
|
* Used by astro internals to create a web standard request object.
|
||||||
*
|
*
|
||||||
|
@ -39,7 +37,6 @@ export function createRequest({
|
||||||
method = 'GET',
|
method = 'GET',
|
||||||
body = undefined,
|
body = undefined,
|
||||||
logger,
|
logger,
|
||||||
locals,
|
|
||||||
isPrerendered = false,
|
isPrerendered = false,
|
||||||
routePattern,
|
routePattern,
|
||||||
}: CreateRequestOptions): Request {
|
}: CreateRequestOptions): Request {
|
||||||
|
@ -93,7 +90,5 @@ export function createRequest({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Reflect.set(request, clientLocalsSymbol, locals ?? {});
|
|
||||||
|
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
|
@ -160,6 +160,7 @@ export async function handleRoute({
|
||||||
let mod: ComponentInstance | undefined = undefined;
|
let mod: ComponentInstance | undefined = undefined;
|
||||||
let route: RouteData;
|
let route: RouteData;
|
||||||
const middleware = (await loadMiddleware(loader)).onRequest;
|
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 locals = Reflect.get(incomingRequest, clientLocalsSymbol);
|
||||||
|
|
||||||
const { preloadedComponent } = matchedRoute;
|
const { preloadedComponent } = matchedRoute;
|
||||||
|
@ -242,7 +243,7 @@ export async function handleRoute({
|
||||||
const fourOhFourRoute = await matchRoute('/404', manifestData, pipeline);
|
const fourOhFourRoute = await matchRoute('/404', manifestData, pipeline);
|
||||||
if (fourOhFourRoute) {
|
if (fourOhFourRoute) {
|
||||||
renderContext = await RenderContext.create({
|
renderContext = await RenderContext.create({
|
||||||
locals,
|
locals: {},
|
||||||
pipeline,
|
pipeline,
|
||||||
pathname,
|
pathname,
|
||||||
middleware: isDefaultPrerendered404(fourOhFourRoute.route) ? undefined : middleware,
|
middleware: isDefaultPrerendered404(fourOhFourRoute.route) ? undefined : middleware,
|
||||||
|
|
|
@ -16,4 +16,21 @@ describe('createAPIContext', () => {
|
||||||
|
|
||||||
assert.equal(context.clientAddress, '192.0.2.43');
|
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',
|
url: '/streaming',
|
||||||
});
|
});
|
||||||
|
|
||||||
const locals = { cancelledByTheServer: false };
|
|
||||||
req[Symbol.for('astro.locals')] = locals;
|
|
||||||
|
|
||||||
container.handle(req, res);
|
container.handle(req, res);
|
||||||
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||||
res.emit('close');
|
res.emit('close');
|
||||||
|
|
||||||
await done;
|
try {
|
||||||
|
await done;
|
||||||
|
|
||||||
assert.equal(locals.cancelledByTheServer, true);
|
assert.ok(true);
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
assert.fail(err)
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue