mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +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) {
|
private registerLayer(name: 'serverLayers' | 'handlerLayers' | 'wsLayers', layer: any) {
|
||||||
this[name].push(layer);
|
this.ctx.effect(() => {
|
||||||
const dispose = () => {
|
this[name].push(layer);
|
||||||
this[name] = this[name].filter((i) => i !== layer);
|
return () => {
|
||||||
};
|
this[name] = this[name].filter((i) => i !== layer);
|
||||||
this[CordisContext.origin]?.on('dispose', dispose);
|
};
|
||||||
return dispose;
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public addServerLayer(name: string, func: any) {
|
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>>) {
|
public handlerMixin(MixinClass: Partial<HandlerCommon<C>>) {
|
||||||
for (const val of Object.getOwnPropertyNames(MixinClass)) {
|
this.ctx.effect(() => {
|
||||||
HandlerCommon.prototype[val] = MixinClass[val];
|
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) {
|
public registerRenderer(name: string, func: Renderer) {
|
||||||
|
|||||||
@@ -73,62 +73,11 @@ export function requireSudo(target: any, funcName: string, obj: any) {
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Handler {
|
|
||||||
domain: DomainDoc;
|
|
||||||
}
|
|
||||||
export class Handler extends HandlerOriginal<Context> {
|
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;
|
domain: DomainDoc;
|
||||||
}
|
}
|
||||||
export class ConnectionHandler extends ConnectionHandlerOriginal<Context> {
|
export class ConnectionHandler extends ConnectionHandlerOriginal<Context> {
|
||||||
constructor(_, ctx) {
|
domain: DomainDoc;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function apply(ctx: Context) {
|
export async function apply(ctx: Context) {
|
||||||
@@ -270,15 +219,53 @@ export async function apply(ctx: Context) {
|
|||||||
return `${this.translate(str)} - ${name}`;
|
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) => {
|
on('handler/create', async (h) => {
|
||||||
h.user = h.context.HydroContext.user as any;
|
h.user = h.context.HydroContext.user as any;
|
||||||
h.domain = h.context.HydroContext.domain as any;
|
h.domain = h.context.HydroContext.domain as any;
|
||||||
h.translate = h.translate.bind(h);
|
h.translate = h.translate.bind(h);
|
||||||
h.url = h.url.bind(h);
|
h.url = h.url.bind(h);
|
||||||
h.ctx = h.ctx.extend({
|
h.ctx = h.ctx.extend({ domain: h.domain });
|
||||||
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) => {
|
on('handler/create/http', async (h) => {
|
||||||
if (!argv.options.benchmark && !h.notUsage) await h.limitRate('global', 5, 100);
|
if (!argv.options.benchmark && !h.notUsage) await h.limitRate('global', 5, 100);
|
||||||
|
|||||||
Reference in new issue
Block a user