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
-}