| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 198cf41 commit 46fbc23
14 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -35,6 +35,7 @@ const debug = util.debuglog('tls'); | |||
| 35 | 35 | const tls_wrap = process.binding('tls_wrap'); | |
| 36 | 36 | const { TCP, constants: TCPConstants } = process.binding('tcp_wrap'); | |
| 37 | 37 | const { Pipe, constants: PipeConstants } = process.binding('pipe_wrap'); | |
| 38 | + const { owner_symbol } = require('internal/async_hooks').symbols; | ||
| 38 | 39 | const { | |
| 39 | 40 | SecureContext: NativeSecureContext | |
| 40 | 41 | } = process.binding('crypto'); | |
@@ -77,7 +78,7 @@ function onhandshakestart(now) { | |||
| 77 | 78 | else | |
| 78 | 79 | this.handshakes++; | |
| 79 | 80 | ||
| 80 | - const { owner } = this; | ||
| 81 | + const owner = this[owner_symbol]; | ||
| 81 | 82 | if (this.handshakes > tls.CLIENT_RENEG_LIMIT) { | |
| 82 | 83 | owner._emitTLSError(new ERR_TLS_SESSION_ATTACK()); | |
| 83 | 84 | return; | |
@@ -90,7 +91,7 @@ function onhandshakestart(now) { | |||
| 90 | 91 | function onhandshakedone() { | |
| 91 | 92 | debug('onhandshakedone'); | |
| 92 | 93 | ||
| 93 | - const owner = this.owner; | ||
| 94 | + const owner = this[owner_symbol]; | ||
| 94 | 95 | ||
| 95 | 96 | // `newSession` callback wasn't called yet | |
| 96 | 97 | if (owner._newSessionPending) { | |
@@ -103,7 +104,7 @@ function onhandshakedone() { | |||
| 103 | 104 | ||
| 104 | 105 | ||
| 105 | 106 | function loadSession(hello) { | |
| 106 | - const owner = this.owner; | ||
| 107 | + const owner = this[owner_symbol]; | ||
| 107 | 108 | ||
| 108 | 109 | var once = false; | |
| 109 | 110 | function onSession(err, session) { | |
@@ -131,7 +132,7 @@ function loadSession(hello) { | |||
| 131 | 132 | ||
| 132 | 133 | ||
| 133 | 134 | function loadSNI(info) { | |
| 134 | - const owner = this.owner; | ||
| 135 | + const owner = this[owner_symbol]; | ||
| 135 | 136 | const servername = info.servername; | |
| 136 | 137 | if (!servername || !owner._SNICallback) | |
| 137 | 138 | return requestOCSP(owner, info); | |
@@ -213,7 +214,7 @@ function requestOCSPDone(socket) { | |||
| 213 | 214 | ||
| 214 | 215 | ||
| 215 | 216 | function onnewsession(key, session) { | |
| 216 | - const owner = this.owner; | ||
| 217 | + const owner = this[owner_symbol]; | ||
| 217 | 218 | ||
| 218 | 219 | if (!owner.server) | |
| 219 | 220 | return; | |
@@ -242,11 +243,11 @@ function onnewsession(key, session) { | |||
| 242 | 243 | ||
| 243 | 244 | ||
| 244 | 245 | function onocspresponse(resp) { | |
| 245 | - this.owner.emit('OCSPResponse', resp); | ||
| 246 | + this[owner_symbol].emit('OCSPResponse', resp); | ||
| 246 | 247 | } | |
| 247 | 248 | ||
| 248 | 249 | function onerror(err) { | |
| 249 | - const owner = this.owner; | ||
| 250 | + const owner = this[owner_symbol]; | ||
| 250 | 251 | ||
| 251 | 252 | if (owner._writableState.errorEmitted) | |
| 252 | 253 | return; | |
@@ -365,9 +366,9 @@ for (var n = 0; n < proxiedMethods.length; n++) { | |||
| 365 | 366 | ||
| 366 | 367 | tls_wrap.TLSWrap.prototype.close = function close(cb) { | |
| 367 | 368 | let ssl; | |
| 368 | - if (this.owner) { | ||
| 369 | - ssl = this.owner.ssl; | ||
| 370 | - this.owner.ssl = null; | ||
| 369 | + if (this[owner_symbol]) { | ||
| 370 | + ssl = this[owner_symbol].ssl; | ||
| 371 | + this[owner_symbol].ssl = null; | ||
| 371 | 372 | } | |
| 372 | 373 | ||
| 373 | 374 | // Invoke `destroySSL` on close to clean up possibly pending write requests | |
@@ -406,7 +407,7 @@ TLSSocket.prototype._wrapHandle = function(wrap) { | |||
| 406 | 407 | handle = options.pipe ? | |
| 407 | 408 | new Pipe(PipeConstants.SOCKET) : | |
| 408 | 409 | new TCP(TCPConstants.SOCKET); | |
| 409 | - handle.owner = this; | ||
| 410 | + handle[owner_symbol] = this; | ||
| 410 | 411 | } | |
| 411 | 412 | ||
| 412 | 413 | // Wrap socket's handle | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -47,7 +47,7 @@ const { isUint8Array } = require('internal/util/types'); | |||
| 47 | 47 | const EventEmitter = require('events'); | |
| 48 | 48 | const { | |
| 49 | 49 | defaultTriggerAsyncIdScope, | |
| 50 | - symbols: { async_id_symbol } | ||
| 50 | + symbols: { async_id_symbol, owner_symbol } | ||
| 51 | 51 | } = require('internal/async_hooks'); | |
| 52 | 52 | const { UV_UDP_REUSEADDR } = process.binding('constants').os; | |
| 53 | 53 | ||
@@ -82,7 +82,7 @@ function Socket(type, listener) { | |||
| 82 | 82 | } | |
| 83 | 83 | ||
| 84 | 84 | var handle = newHandle(type, lookup); | |
| 85 | - handle.owner = this; | ||
| 85 | + handle[owner_symbol] = this; | ||
| 86 | 86 | ||
| 87 | 87 | this[async_id_symbol] = handle.getAsyncId(); | |
| 88 | 88 | this.type = type; | |
@@ -136,7 +136,7 @@ function replaceHandle(self, newHandle) { | |||
| 136 | 136 | newHandle.lookup = oldHandle.lookup; | |
| 137 | 137 | newHandle.bind = oldHandle.bind; | |
| 138 | 138 | newHandle.send = oldHandle.send; | |
| 139 | - newHandle.owner = self; | ||
| 139 | + newHandle[owner_symbol] = self; | ||
| 140 | 140 | ||
| 141 | 141 | // Replace the existing handle by the handle we got from master. | |
| 142 | 142 | oldHandle.close(); | |
@@ -620,7 +620,7 @@ function stopReceiving(socket) { | |||
| 620 | 620 | ||
| 621 | 621 | ||
| 622 | 622 | function onMessage(nread, handle, buf, rinfo) { | |
| 623 | - var self = handle.owner; | ||
| 623 | + var self = handle[owner_symbol]; | ||
| 624 | 624 | if (nread < 0) { | |
| 625 | 625 | return self.emit('error', errnoException(nread, 'recvmsg')); | |
| 626 | 626 | } | |
@@ -730,6 +730,14 @@ Socket.prototype._stopReceiving = function() { | |||
| 730 | 730 | }; | |
| 731 | 731 | ||
| 732 | 732 | ||
| 733 | + // Legacy alias on the C++ wrapper object. This is not public API, so we may | ||
| 734 | + // want to runtime-deprecate it at some point. There's no hurry, though. | ||
| 735 | + Object.defineProperty(UDP.prototype, 'owner', { | ||
| 736 | + get() { return this[owner_symbol]; }, | ||
| 737 | + set(v) { return this[owner_symbol] = v; } | ||
| 738 | + }); | ||
| 739 | + | ||
| 740 | + | ||
| 733 | 741 | module.exports = { | |
| 734 | 742 | _createSocketHandle, | |
| 735 | 743 | createSocket, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -30,7 +30,7 @@ const async_wrap = process.binding('async_wrap'); | |||
| 30 | 30 | * It has a fixed size, so if that is exceeded, calls to the native | |
| 31 | 31 | * side are used instead in pushAsyncIds() and popAsyncIds(). | |
| 32 | 32 | */ | |
| 33 | - const { async_hook_fields, async_id_fields } = async_wrap; | ||
| 33 | + const { async_hook_fields, async_id_fields, owner_symbol } = async_wrap; | ||
| 34 | 34 | // Store the pair executionAsyncId and triggerAsyncId in a std::stack on | |
| 35 | 35 | // Environment::AsyncHooks::async_ids_stack_ tracks the resource responsible for | |
| 36 | 36 | // the current execution stack. This is unwound as each resource exits. In the | |
@@ -434,7 +434,7 @@ module.exports = { | |||
| 434 | 434 | symbols: { | |
| 435 | 435 | async_id_symbol, trigger_async_id_symbol, | |
| 436 | 436 | init_symbol, before_symbol, after_symbol, destroy_symbol, | |
| 437 | - promise_resolve_symbol | ||
| 437 | + promise_resolve_symbol, owner_symbol | ||
| 438 | 438 | }, | |
| 439 | 439 | constants: { | |
| 440 | 440 | kInit, kBefore, kAfter, kDestroy, kTotals, kPromiseResolve | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -28,6 +28,7 @@ const { TTY } = process.binding('tty_wrap'); | |||
| 28 | 28 | const { TCP } = process.binding('tcp_wrap'); | |
| 29 | 29 | const { UDP } = process.binding('udp_wrap'); | |
| 30 | 30 | const SocketList = require('internal/socket_list'); | |
| 31 | + const { owner_symbol } = require('internal/async_hooks').symbols; | ||
| 31 | 32 | const { convertToValidSignal } = require('internal/util'); | |
| 32 | 33 | const { isUint8Array } = require('internal/util/types'); | |
| 33 | 34 | const spawn_sync = process.binding('spawn_sync'); | |
@@ -210,7 +211,7 @@ function ChildProcess() { | |||
| 210 | 211 | this.spawnfile = null; | |
| 211 | 212 | ||
| 212 | 213 | this._handle = new Process(); | |
| 213 | - this._handle.owner = this; | ||
| 214 | + this._handle[owner_symbol] = this; | ||
| 214 | 215 | ||
| 215 | 216 | this._handle.onexit = (exitCode, signalCode) => { | |
| 216 | 217 | if (signalCode) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3,6 +3,7 @@ const assert = require('assert'); | |||
| 3 | 3 | const util = require('util'); | |
| 4 | 4 | const path = require('path'); | |
| 5 | 5 | const EventEmitter = require('events'); | |
| 6 | + const { owner_symbol } = require('internal/async_hooks').symbols; | ||
| 6 | 7 | const Worker = require('internal/cluster/worker'); | |
| 7 | 8 | const { internal, sendHelper } = require('internal/cluster/utils'); | |
| 8 | 9 | const cluster = new EventEmitter(); | |
@@ -207,8 +208,8 @@ function _disconnect(masterInitiated) { | |||
| 207 | 208 | delete handles[key]; | |
| 208 | 209 | waitingCount++; | |
| 209 | 210 | ||
| 210 | - if (handle.owner) | ||
| 211 | - handle.owner.close(checkWaitingCount); | ||
| 211 | + if (handle[owner_symbol]) | ||
| 212 | + handle[owner_symbol].close(checkWaitingCount); | ||
| 212 | 213 | else | |
| 213 | 214 | handle.close(checkWaitingCount); | |
| 214 | 215 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11,7 +11,10 @@ const { | |||
| 11 | 11 | getStatsFromBinding, | |
| 12 | 12 | validatePath | |
| 13 | 13 | } = require('internal/fs/utils'); | |
| 14 | - const { defaultTriggerAsyncIdScope } = require('internal/async_hooks'); | ||
| 14 | + const { | ||
| 15 | + defaultTriggerAsyncIdScope, | ||
| 16 | + symbols: { owner_symbol } | ||
| 17 | + } = require('internal/async_hooks'); | ||
| 15 | 18 | const { toNamespacedPath } = require('path'); | |
| 16 | 19 | const { validateUint32 } = require('internal/validators'); | |
| 17 | 20 | const { getPathFromURL } = require('internal/url'); | |
@@ -20,7 +23,6 @@ const assert = require('assert'); | |||
| 20 | 23 | ||
| 21 | 24 | const kOldStatus = Symbol('kOldStatus'); | |
| 22 | 25 | const kUseBigint = Symbol('kUseBigint'); | |
| 23 | - const kOwner = Symbol('kOwner'); | ||
| 24 | 26 | ||
| 25 | 27 | function emitStop(self) { | |
| 26 | 28 | self.emit('stop'); | |
@@ -36,7 +38,7 @@ function StatWatcher(bigint) { | |||
| 36 | 38 | util.inherits(StatWatcher, EventEmitter); | |
| 37 | 39 | ||
| 38 | 40 | function onchange(newStatus, stats) { | |
| 39 | - const self = this[kOwner]; | ||
| 41 | + const self = this[owner_symbol]; | ||
| 40 | 42 | if (self[kOldStatus] === -1 && | |
| 41 | 43 | newStatus === -1 && | |
| 42 | 44 | stats[2/* new nlink */] === stats[16/* old nlink */]) { | |
@@ -59,7 +61,7 @@ StatWatcher.prototype.start = function(filename, persistent, interval) { | |||
| 59 | 61 | return; | |
| 60 | 62 | ||
| 61 | 63 | this._handle = new _StatWatcher(this[kUseBigint]); | |
| 62 | - this._handle[kOwner] = this; | ||
| 64 | + this._handle[owner_symbol] = this; | ||
| 63 | 65 | this._handle.onchange = onchange; | |
| 64 | 66 | if (!persistent) | |
| 65 | 67 | this._handle.unref(); | |
@@ -104,7 +106,7 @@ function FSWatcher() { | |||
| 104 | 106 | EventEmitter.call(this); | |
| 105 | 107 | ||
| 106 | 108 | this._handle = new FSEvent(); | |
| 107 | - this._handle.owner = this; | ||
| 109 | + this._handle[owner_symbol] = this; | ||
| 108 | 110 | ||
| 109 | 111 | this._handle.onchange = (status, eventType, filename) => { | |
| 110 | 112 | // TODO(joyeecheung): we may check self._handle.initialized here | |
@@ -131,6 +133,7 @@ function FSWatcher() { | |||
| 131 | 133 | } | |
| 132 | 134 | util.inherits(FSWatcher, EventEmitter); | |
| 133 | 135 | ||
| 136 | + | ||
| 134 | 137 | // FIXME(joyeecheung): this method is not documented. | |
| 135 | 138 | // At the moment if filename is undefined, we | |
| 136 | 139 | // 1. Throw an Error if it's the first time .start() is called | |
@@ -187,6 +190,13 @@ function emitCloseNT(self) { | |||
| 187 | 190 | self.emit('close'); | |
| 188 | 191 | } | |
| 189 | 192 | ||
| 193 | + // Legacy alias on the C++ wrapper object. This is not public API, so we may | ||
| 194 | + // want to runtime-deprecate it at some point. There's no hurry, though. | ||
| 195 | + Object.defineProperty(FSEvent.prototype, 'owner', { | ||
| 196 | + get() { return this[owner_symbol]; }, | ||
| 197 | + set(v) { return this[owner_symbol] = v; } | ||
| 198 | + }); | ||
| 199 | + | ||
| 190 | 200 | module.exports = { | |
| 191 | 201 | FSWatcher, | |
| 192 | 202 | StatWatcher | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -28,6 +28,7 @@ const { | |||
| 28 | 28 | defaultTriggerAsyncIdScope, | |
| 29 | 29 | symbols: { | |
| 30 | 30 | async_id_symbol, | |
| 31 | + owner_symbol, | ||
| 31 | 32 | }, | |
| 32 | 33 | } = require('internal/async_hooks'); | |
| 33 | 34 | const { internalBinding } = require('internal/bootstrap/loaders'); | |
@@ -144,7 +145,7 @@ const kInfoHeaders = Symbol('sent-info-headers'); | |||
| 144 | 145 | const kMaybeDestroy = Symbol('maybe-destroy'); | |
| 145 | 146 | const kLocalSettings = Symbol('local-settings'); | |
| 146 | 147 | const kOptions = Symbol('options'); | |
| 147 | - const kOwner = Symbol('owner'); | ||
| 148 | + const kOwner = owner_symbol; | ||
| 148 | 149 | const kProceed = Symbol('proceed'); | |
| 149 | 150 | const kProtocol = Symbol('protocol'); | |
| 150 | 151 | const kProxySocket = Symbol('proxy-socket'); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -6,16 +6,17 @@ const { Socket } = require('net'); | |||
| 6 | 6 | const { JSStream } = process.binding('js_stream'); | |
| 7 | 7 | const uv = process.binding('uv'); | |
| 8 | 8 | const debug = util.debuglog('stream_wrap'); | |
| 9 | + const { owner_symbol } = require('internal/async_hooks').symbols; | ||
| 9 | 10 | const { ERR_STREAM_WRAP } = require('internal/errors').codes; | |
| 10 | 11 | ||
| 11 | 12 | const kCurrentWriteRequest = Symbol('kCurrentWriteRequest'); | |
| 12 | 13 | const kCurrentShutdownRequest = Symbol('kCurrentShutdownRequest'); | |
| 13 | 14 | ||
| 14 | - function isClosing() { return this.owner.isClosing(); } | ||
| 15 | - function onreadstart() { return this.owner.readStart(); } | ||
| 16 | - function onreadstop() { return this.owner.readStop(); } | ||
| 17 | - function onshutdown(req) { return this.owner.doShutdown(req); } | ||
| 18 | - function onwrite(req, bufs) { return this.owner.doWrite(req, bufs); } | ||
| 15 | + function isClosing() { return this[owner_symbol].isClosing(); } | ||
| 16 | + function onreadstart() { return this[owner_symbol].readStart(); } | ||
| 17 | + function onreadstop() { return this[owner_symbol].readStop(); } | ||
| 18 | + function onshutdown(req) { return this[owner_symbol].doShutdown(req); } | ||
| 19 | + function onwrite(req, bufs) { return this[owner_symbol].doWrite(req, bufs); } | ||
| 19 | 20 | ||
| 20 | 21 | /* This class serves as a wrapper for when the C++ side of Node wants access | |
| 21 | 22 | * to a standard JS stream. For example, TLS or HTTP do not operate on network | |
@@ -37,7 +38,7 @@ class JSStreamWrap extends Socket { | |||
| 37 | 38 | this.doClose(cb); | |
| 38 | 39 | }; | |
| 39 | 40 | // Inside of the following functions, `this` refers to the handle | |
| 40 | - // and `this.owner` refers to this JSStreamWrap instance. | ||
| 41 | + // and `this[owner_symbol]` refers to this JSStreamWrap instance. | ||
| 41 | 42 | handle.isClosing = isClosing; | |
| 42 | 43 | handle.onreadstart = onreadstart; | |
| 43 | 44 | handle.onreadstop = onreadstop; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -56,7 +56,7 @@ const { | |||
| 56 | 56 | const { | |
| 57 | 57 | newAsyncId, | |
| 58 | 58 | defaultTriggerAsyncIdScope, | |
| 59 | - symbols: { async_id_symbol } | ||
| 59 | + symbols: { async_id_symbol, owner_symbol } | ||
| 60 | 60 | } = require('internal/async_hooks'); | |
| 61 | 61 | const { | |
| 62 | 62 | createWriteWrap, | |
@@ -207,7 +207,7 @@ function initSocketHandle(self) { | |||
| 207 | 207 | ||
| 208 | 208 | // Handle creation may be deferred to bind() or connect() time. | |
| 209 | 209 | if (self._handle) { | |
| 210 | - self._handle.owner = self; | ||
| 210 | + self._handle[owner_symbol] = self; | ||
| 211 | 211 | self._handle.onread = onread; | |
| 212 | 212 | self[async_id_symbol] = getNewAsyncId(self._handle); | |
| 213 | 213 | } | |
@@ -371,7 +371,7 @@ Socket.prototype._final = function(cb) { | |||
| 371 | 371 | ||
| 372 | 372 | ||
| 373 | 373 | function afterShutdown(status, handle) { | |
| 374 | - var self = handle.owner; | ||
| 374 | + var self = handle[owner_symbol]; | ||
| 375 | 375 | ||
| 376 | 376 | debug('afterShutdown destroyed=%j', self.destroyed, | |
| 377 | 377 | self._readableState); | |
@@ -620,7 +620,7 @@ Socket.prototype._destroy = function(exception, cb) { | |||
| 620 | 620 | // buffer, or when there's an error reading. | |
| 621 | 621 | function onread(nread, buffer) { | |
| 622 | 622 | var handle = this; | |
| 623 | - var self = handle.owner; | ||
| 623 | + var self = handle[owner_symbol]; | ||
| 624 | 624 | assert(handle === self._handle, 'handle != self._handle'); | |
| 625 | 625 | ||
| 626 | 626 | self._unrefTimer(); | |
@@ -819,7 +819,7 @@ protoGetter('bytesWritten', function bytesWritten() { | |||
| 819 | 819 | ||
| 820 | 820 | ||
| 821 | 821 | function afterWrite(status, handle, err) { | |
| 822 | - var self = handle.owner; | ||
| 822 | + var self = handle[owner_symbol]; | ||
| 823 | 823 | if (self !== process.stderr && self !== process.stdout) | |
| 824 | 824 | debug('afterWrite', status); | |
| 825 | 825 | ||
@@ -1121,7 +1121,7 @@ Socket.prototype.unref = function() { | |||
| 1121 | 1121 | ||
| 1122 | 1122 | ||
| 1123 | 1123 | function afterConnect(status, handle, req, readable, writable) { | |
| 1124 | - var self = handle.owner; | ||
| 1124 | + var self = handle[owner_symbol]; | ||
| 1125 | 1125 | ||
| 1126 | 1126 | // callback may come after call to destroy | |
| 1127 | 1127 | if (self.destroyed) { | |
@@ -1323,7 +1323,7 @@ function setupListenHandle(address, port, addressType, backlog, fd) { | |||
| 1323 | 1323 | ||
| 1324 | 1324 | this[async_id_symbol] = getNewAsyncId(this._handle); | |
| 1325 | 1325 | this._handle.onconnection = onconnection; | |
| 1326 | - this._handle.owner = this; | ||
| 1326 | + this._handle[owner_symbol] = this; | ||
| 1327 | 1327 | ||
| 1328 | 1328 | // Use a backlog of 512 entries. We pass 511 to the listen() call because | |
| 1329 | 1329 | // the kernel does: backlogsize = roundup_pow_of_two(backlogsize + 1); | |
@@ -1536,7 +1536,7 @@ Server.prototype.address = function() { | |||
| 1536 | 1536 | ||
| 1537 | 1537 | function onconnection(err, clientHandle) { | |
| 1538 | 1538 | var handle = this; | |
| 1539 | - var self = handle.owner; | ||
| 1539 | + var self = handle[owner_symbol]; | ||
| 1540 | 1540 | ||
| 1541 | 1541 | debug('onconnection'); | |
| 1542 | 1542 | ||
@@ -1667,6 +1667,14 @@ function emitCloseNT(self) { | |||
| 1667 | 1667 | } | |
| 1668 | 1668 | ||
| 1669 | 1669 | ||
| 1670 | + // Legacy alias on the C++ wrapper object. This is not public API, so we may | ||
| 1671 | + // want to runtime-deprecate it at some point. There's no hurry, though. | ||
| 1672 | + Object.defineProperty(TCP.prototype, 'owner', { | ||
| 1673 | + get() { return this[owner_symbol]; }, | ||
| 1674 | + set(v) { return this[owner_symbol] = v; } | ||
| 1675 | + }); | ||
| 1676 | + | ||
| 1677 | + | ||
| 1670 | 1678 | Server.prototype.listenFD = internalUtil.deprecate(function(fd, type) { | |
| 1671 | 1679 | return this.listen({ fd: fd }); | |
| 1672 | 1680 | }, 'Server.listenFD is deprecated. Use Server.listen({fd: <number>}) instead.', | |
| Back | FazBrowse Home | New Git URL |
0 commit comments