@samitouri / QOSami-HFS / commits / 508fdbd9

plugins: ctx.disconnect method

Massimo Melina committed Sep 15, 2025 at 11:20 UTC 508fdbd9e0b326a2a9a1fd134b4bd286d3bea98d
3 files changed +31 -19
dev-plugins.md
+9 -4
@@ -771,12 +771,16 @@ HFS.getNotifications('test', console.log)
771
772 HFS is currently based on [Koa](https://koajs.com), so you'll see some things related to it in the backend API.
773 The most prominent is the `ctx` object, short for "context".
774 -To know what the Context object contains please refer to [Koa documentation](https://github.com/koajs/koa/blob/master/docs/api/context.md).
774 +To know what the Context object offers, please refer to [Koa documentation](https://github.com/koajs/koa/blob/master/docs/api/context.md).
775 +Additional methods you may be interested in:
776 +- `ctx.disconnect(logMessage?: string)`
777 +- `ctx.stop()` (explained in the *middleware* section)
778 +- `ctx.isAborted(): boolean` if the client will actually never receive the response
779
776 -HFS adds a few useful properties in the `ctx.state` object. Some of it may turn to be useful,
780 +HFS adds a few useful properties in the `ctx.state` object. Some of it may turn out to be useful,
781 so we prepared this list as a quick reference, but beware that it may become out of date and needs a double check.
782 If so, please report, and we'll do our best to update it asap.
779 -Where information is too little, you'll have to consult the source code, sorry.
783 +Where there is too little information, you'll have to consult the source code. Apologies.
784
785 originalPath: string // before roots is applied
786 browsing?: string // for admin/monitoring
@@ -1064,4 +1068,5 @@ If you want to override a text regardless of the language, use the special langu
1068 - 12.92 (v0.57.16)
1069 - fixed checkVfsPermission
1070 - 12.93 (v0.57.17)
1067 - - uploadStart now gets fullPath, tempName, resume, fullSize
\ No newline at end of file
1071 + - uploadStart now gets fullPath, tempName, resume, fullSize
1072 + - ctx.disconnect(logMessage)
\ No newline at end of file
src/connections.ts
+22 -5
@@ -88,17 +88,34 @@ export function updateConnection(conn: Connection, change: Partial<Connection>,
88
89 export const disconnectionsLog: { ts: Date, ip: string, country?: string, msg?: string }[] = []
90
91 -export function disconnect(what: Context | Socket | Connection, debugLog='') {
91 +export function disconnect(what: Context | Socket | Connection, logMessage='') {
92 if ('socket' in what)
93 what = what.socket
94 const ip = normalizeIp(what.remoteAddress || '')
95 - if (debugLog)
96 - console.debug("disconnection:", debugLog, ip)
95 + if (logMessage)
96 + console.debug("disconnection:", logMessage, ip)
97 ip2country(ip).then(res => {
98 - const rec = { ip, country: res || undefined, ts: new Date, msg: debugLog || undefined }
98 + const rec = { ip, country: res || undefined, ts: new Date, msg: logMessage || undefined }
99 disconnectionsLog.unshift(rec)
100 disconnectionsLog.length = Math.min(1000, disconnectionsLog.length)
101 events.emit('disconnection', rec)
102 })
103 return what.destroy()
104 -}
\ No newline at end of file
104 +}
105 +
106 +
107 +declare module "koa" {
108 + interface BaseContext {
109 + isAborted(): boolean
110 + disconnect(logMessage?: string): unknown
111 + }
112 +}
113 +events.once('app', app => { // can't simply import 'app', as it's not defined at this point (this file is required by 'plugins.ts' which is required by 'index.ts')
114 + app.context.isAborted = function() {
115 + return this.res.destroyed || this.req.aborted // investigate: "aborted" is deprecated, but "destroyed" will cause failure of some tests
116 + || this.socket.destroyed
117 + }
118 + app.context.disconnect = function(logMessage='') {
119 + return disconnect(this as Context, logMessage)
120 + }
121 +})
\ No newline at end of file
src/index.ts
-10
@@ -83,13 +83,3 @@ defineConfig('proxies', 0).sub(n => {
83 app.proxy = n > 0
84 app.maxIpsCount = n
85 })
86 -
87 -declare module "koa" {
88 - interface BaseContext {
89 - isAborted(): boolean
90 - }
91 -}
92 -app.context.isAborted = function() {
93 - return this.res.destroyed || this.req.aborted // investigate: "aborted" is deprecated, but "destroyed" will cause failure of some tests
94 - || this.socket.destroyed
95 -}