mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-17 09:36:08 +08:00
core: server: use handler mixin
This commit is contained in:
2 files changed
+92
-64
No files matched your search
@@ -717,12 +717,12 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`);
|
||||
}
|
||||
|
||||
private registerLayer(name: 'serverLayers' | 'handlerLayers' | 'wsLayers', layer: any) {
|
||||
this[name].push(layer);
|
||||
const dispose = () => {
|
||||
this[name] = this[name].filter((i) => i !== layer);
|
||||
};
|
||||
this[CordisContext.origin]?.on('dispose', dispose);
|
||||
return dispose;
|
||||
this.ctx.effect(() => {
|
||||
this[name].push(layer);
|
||||
return () => {
|
||||
this[name] = this[name].filter((i) => i !== layer);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
public addServerLayer(name: string, func: any) {
|
||||
@@ -747,9 +747,50 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`);
|
||||
}
|
||||
|
||||
public handlerMixin(MixinClass: Partial<HandlerCommon<C>>) {
|
||||
for (const val of Object.getOwnPropertyNames(MixinClass)) {
|
||||
HandlerCommon.prototype[val] = MixinClass[val];
|
||||
}
|
||||
this.ctx.effect(() => {
|
||||
for (const val of Object.getOwnPropertyNames(MixinClass)) {
|
||||
if (HandlerCommon.prototype[val]) {
|
||||
logger.warn('HandlerCommon.prototype[%s] already exists.', val);
|
||||
}
|
||||
HandlerCommon.prototype[val] = MixinClass[val];
|
||||
}
|
||||
return () => {
|
||||
for (const val of Object.getOwnPropertyNames(MixinClass)) {
|
||||
delete HandlerCommon.prototype[val];
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
public httpHandlerMixin(MixinClass: Partial<Handler<C>>) {
|
||||
this.ctx.effect(() => {
|
||||
for (const val of Object.getOwnPropertyNames(MixinClass)) {
|
||||
if (Handler.prototype[val]) {
|
||||
logger.warn('Handler.prototype[%s] already exists.', val);
|
||||
}
|
||||
Handler.prototype[val] = MixinClass[val];
|
||||
}
|
||||
return () => {
|
||||
for (const val of Object.getOwnPropertyNames(MixinClass)) {
|
||||
delete Handler.prototype[val];
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
public wsHandlerMixin(MixinClass: Partial<ConnectionHandler<C>>) {
|
||||
this.ctx.effect(() => {
|
||||
for (const val of Object.getOwnPropertyNames(MixinClass)) {
|
||||
if (ConnectionHandler.prototype[val]) {
|
||||
logger.warn('ConnectionHandler.prototype[%s] already exists.', val);
|
||||
}
|
||||
}
|
||||
return () => {
|
||||
for (const val of Object.getOwnPropertyNames(MixinClass)) {
|
||||
delete ConnectionHandler.prototype[val];
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
public registerRenderer(name: string, func: Renderer) {
|
||||
|
||||
@@ -73,62 +73,11 @@ export function requireSudo(target: any, funcName: string, obj: any) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
export interface Handler {
|
||||
domain: DomainDoc;
|
||||
}
|
||||
export class Handler extends HandlerOriginal<Context> {
|
||||
constructor(_, ctx) {
|
||||
super(_, ctx);
|
||||
this.ctx = ctx.extend({ domain: this.domain });
|
||||
this.renderHTML = ((orig) => function (name: string, args: Record<string, any>) {
|
||||
const s = name.split('.');
|
||||
let templateName = `${s[0]}.${args.domainId}.${s[1]}`;
|
||||
if (!global.Hydro.ui.template[templateName]) templateName = name;
|
||||
return orig(templateName, args);
|
||||
})(this.renderHTML).bind(this);
|
||||
}
|
||||
|
||||
async onerror(error: HydroError) {
|
||||
error.msg ||= () => error.message;
|
||||
if (error instanceof UserFacingError && !process.env.DEV) error.stack = '';
|
||||
if (!(error instanceof NotFoundError) && !('nolog' in error)) {
|
||||
// eslint-disable-next-line max-len
|
||||
logger.error(`User: ${this.user._id}(${this.user.uname}) ${this.request.method}: /d/${this.domain._id}${this.request.path}`, error.msg(), error.params);
|
||||
if (error.stack) logger.error(error.stack);
|
||||
}
|
||||
if (this.user?._id === 0 && (error instanceof PermissionError || error instanceof PrivilegeError)) {
|
||||
this.response.redirect = this.url('user_login', {
|
||||
query: {
|
||||
redirect: (this.context.originalPath || this.request.path) + this.context.search,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
this.response.status = error instanceof UserFacingError ? error.code : 500;
|
||||
this.response.template = error instanceof UserFacingError ? 'error.html' : 'bsod.html';
|
||||
this.response.body = {
|
||||
UserFacingError,
|
||||
error: { message: error.msg(), params: error.params, stack: errorMessage(error.stack || '') },
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface ConnectionHandler {
|
||||
domain: DomainDoc;
|
||||
}
|
||||
export class ConnectionHandler extends ConnectionHandlerOriginal<Context> {
|
||||
constructor(_, ctx) {
|
||||
super(_, ctx);
|
||||
this.ctx = ctx.extend({ domain: this.domain });
|
||||
}
|
||||
|
||||
onerror(err: HydroError) {
|
||||
if (![NotFoundError, PrivilegeError, PermissionError].some((i) => err instanceof i) || this.user?._id !== 0) {
|
||||
logger.error(`Path:${this.request.path}, User:${this.user?._id}(${this.user?.uname})`);
|
||||
logger.error(err);
|
||||
}
|
||||
super.onerror(err);
|
||||
}
|
||||
domain: DomainDoc;
|
||||
}
|
||||
|
||||
export async function apply(ctx: Context) {
|
||||
@@ -270,15 +219,53 @@ export async function apply(ctx: Context) {
|
||||
return `${this.translate(str)} - ${name}`;
|
||||
},
|
||||
});
|
||||
server.httpHandlerMixin({
|
||||
async onerror(error: HydroError) {
|
||||
error.msg ||= () => error.message;
|
||||
if (error instanceof UserFacingError && !process.env.DEV) error.stack = '';
|
||||
if (!(error instanceof NotFoundError) && !('nolog' in error)) {
|
||||
// eslint-disable-next-line max-len
|
||||
logger.error(`User: ${this.user._id}(${this.user.uname}) ${this.request.method}: /d/${this.domain._id}${this.request.path}`, error.msg(), error.params);
|
||||
if (error.stack) logger.error(error.stack);
|
||||
}
|
||||
if (this.user?._id === 0 && (error instanceof PermissionError || error instanceof PrivilegeError)) {
|
||||
this.response.redirect = this.url('user_login', {
|
||||
query: {
|
||||
redirect: (this.context.originalPath || this.request.path) + this.context.search,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
this.response.status = error instanceof UserFacingError ? error.code : 500;
|
||||
this.response.template = error instanceof UserFacingError ? 'error.html' : 'bsod.html';
|
||||
this.response.body = {
|
||||
UserFacingError,
|
||||
error: { message: error.msg(), params: error.params, stack: errorMessage(error.stack || '') },
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
server.wsHandlerMixin({
|
||||
async onerror(err: HydroError) {
|
||||
if (![NotFoundError, PrivilegeError, PermissionError].some((i) => err instanceof i) || this.user?._id !== 0) {
|
||||
logger.error(`Path:${this.request.path}, User:${this.user?._id}(${this.user?.uname})`);
|
||||
logger.error(err);
|
||||
}
|
||||
await super.onerror(err);
|
||||
},
|
||||
});
|
||||
|
||||
on('handler/create', async (h) => {
|
||||
h.user = h.context.HydroContext.user as any;
|
||||
h.domain = h.context.HydroContext.domain as any;
|
||||
h.translate = h.translate.bind(h);
|
||||
h.url = h.url.bind(h);
|
||||
h.ctx = h.ctx.extend({
|
||||
domain: h.domain,
|
||||
});
|
||||
h.ctx = h.ctx.extend({ domain: h.domain });
|
||||
h.renderHTML = ((orig) => function (name: string, args: Record<string, any>) {
|
||||
const s = name.split('.');
|
||||
let templateName = `${s[0]}.${args.domainId}.${s[1]}`;
|
||||
if (!global.Hydro.ui.template[templateName]) templateName = name;
|
||||
return orig(templateName, args);
|
||||
})(h.renderHTML).bind(h);
|
||||
});
|
||||
on('handler/create/http', async (h) => {
|
||||
if (!argv.options.benchmark && !h.notUsage) await h.limitRate('global', 5, 100);
|
||||
|
||||
Reference in new issue
Block a user