wangzhibo
2026-05-09 53418655c061ac26f66058253f39200aced1ab1d
1
{"version":3,"file":"message-io.js","names":["_nativeDuplexpair","_interopRequireDefault","require","tls","_interopRequireWildcard","_events","_message","_packet","_incomingMessageStream","_outgoingMessageStream","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","MessageIO","EventEmitter","constructor","socket","packetSize","debug","tlsNegotiationComplete","incomingMessageStream","IncomingMessageStream","incomingMessageIterator","Symbol","asyncIterator","outgoingMessageStream","OutgoingMessageStream","pipe","args","length","log","securePair","cleartext","setMaxSendFragment","startTls","credentialsDetails","hostname","trustServerCertificate","maxVersion","includes","secureContext","createSecureContext","Promise","resolve","reject","duplexpair","DuplexPair","connect","socket1","servername","rejectUnauthorized","encrypted","socket2","onSecureConnect","removeListener","onReadable","onError","once","err","destroy","cipher","getCipher","name","version","emit","unpipe","message","Message","type","TYPE","PRELOGIN","resetConnection","chunk","read","write","end","readMessage","then","response","data","catch","sendMessage","packetType","result","next","done","Error","value","_default","exports","module"],"sources":["../src/message-io.ts"],"sourcesContent":["import DuplexPair from 'native-duplexpair';\n\nimport { Duplex } from 'stream';\nimport * as tls from 'tls';\nimport { Socket } from 'net';\nimport { EventEmitter } from 'events';\n\nimport Debug from './debug';\n\nimport Message from './message';\nimport { TYPE } from './packet';\n\nimport IncomingMessageStream from './incoming-message-stream';\nimport OutgoingMessageStream from './outgoing-message-stream';\n\nclass MessageIO extends EventEmitter {\n  declare socket: Socket;\n  declare debug: Debug;\n\n  declare tlsNegotiationComplete: boolean;\n\n  declare private incomingMessageStream: IncomingMessageStream;\n  declare outgoingMessageStream: OutgoingMessageStream;\n\n  declare securePair?: {\n    cleartext: tls.TLSSocket;\n    encrypted: Duplex;\n  };\n\n  declare incomingMessageIterator: AsyncIterableIterator<Message>;\n\n  constructor(socket: Socket, packetSize: number, debug: Debug) {\n    super();\n\n    this.socket = socket;\n    this.debug = debug;\n\n    this.tlsNegotiationComplete = false;\n\n    this.incomingMessageStream = new IncomingMessageStream(this.debug);\n    this.incomingMessageIterator = this.incomingMessageStream[Symbol.asyncIterator]();\n\n    this.outgoingMessageStream = new OutgoingMessageStream(this.debug, { packetSize: packetSize });\n\n    this.socket.pipe(this.incomingMessageStream);\n    this.outgoingMessageStream.pipe(this.socket);\n  }\n\n  packetSize(...args: [number]) {\n    if (args.length > 0) {\n      const packetSize = args[0];\n      this.debug.log('Packet size changed from ' + this.outgoingMessageStream.packetSize + ' to ' + packetSize);\n      this.outgoingMessageStream.packetSize = packetSize;\n    }\n\n    if (this.securePair) {\n      this.securePair.cleartext.setMaxSendFragment(this.outgoingMessageStream.packetSize);\n    }\n\n    return this.outgoingMessageStream.packetSize;\n  }\n\n  // Negotiate TLS encryption.\n  startTls(credentialsDetails: tls.SecureContextOptions, hostname: string, trustServerCertificate: boolean) {\n    if (!credentialsDetails.maxVersion || !['TLSv1.2', 'TLSv1.1', 'TLSv1'].includes(credentialsDetails.maxVersion)) {\n      credentialsDetails.maxVersion = 'TLSv1.2';\n    }\n\n    const secureContext = tls.createSecureContext(credentialsDetails);\n\n    return new Promise<void>((resolve, reject) => {\n      const duplexpair = new DuplexPair();\n      const securePair = this.securePair = {\n        cleartext: tls.connect({\n          socket: duplexpair.socket1 as Socket,\n          servername: hostname,\n          secureContext: secureContext,\n          rejectUnauthorized: !trustServerCertificate\n        }),\n        encrypted: duplexpair.socket2\n      };\n\n      const onSecureConnect = () => {\n        securePair.encrypted.removeListener('readable', onReadable);\n        securePair.cleartext.removeListener('error', onError);\n        securePair.cleartext.removeListener('secureConnect', onSecureConnect);\n\n        // If we encounter any errors from this point on,\n        // we just forward them to the actual network socket.\n        securePair.cleartext.once('error', (err) => {\n          this.socket.destroy(err);\n        });\n\n        const cipher = securePair.cleartext.getCipher();\n        if (cipher) {\n          this.debug.log('TLS negotiated (' + cipher.name + ', ' + cipher.version + ')');\n        }\n\n        this.emit('secure', securePair.cleartext);\n\n        securePair.cleartext.setMaxSendFragment(this.outgoingMessageStream.packetSize);\n\n        this.outgoingMessageStream.unpipe(this.socket);\n        this.socket.unpipe(this.incomingMessageStream);\n\n        this.socket.pipe(securePair.encrypted);\n        securePair.encrypted.pipe(this.socket);\n\n        securePair.cleartext.pipe(this.incomingMessageStream);\n        this.outgoingMessageStream.pipe(securePair.cleartext);\n\n        this.tlsNegotiationComplete = true;\n\n        resolve();\n      };\n\n      const onError = (err?: Error) => {\n        securePair.encrypted.removeListener('readable', onReadable);\n        securePair.cleartext.removeListener('error', onError);\n        securePair.cleartext.removeListener('secureConnect', onSecureConnect);\n\n        securePair.cleartext.destroy();\n        securePair.encrypted.destroy();\n\n        reject(err);\n      };\n\n      const onReadable = () => {\n        // When there is handshake data on the encrypted stream of the secure pair,\n        // we wrap it into a `PRELOGIN` message and send it to the server.\n        //\n        // For each `PRELOGIN` message we sent we get back exactly one response message\n        // that contains the server's handshake response data.\n        const message = new Message({ type: TYPE.PRELOGIN, resetConnection: false });\n\n        let chunk;\n        while (chunk = securePair.encrypted.read()) {\n          message.write(chunk);\n        }\n        this.outgoingMessageStream.write(message);\n        message.end();\n\n        this.readMessage().then(async (response) => {\n          // Setup readable handler for the next round of handshaking.\n          // If we encounter a `secureConnect` on the cleartext side\n          // of the secure pair, the `readable` handler is cleared\n          // and no further handshake handling will happen.\n          securePair.encrypted.once('readable', onReadable);\n\n          for await (const data of response) {\n            // We feed the server's handshake response back into the\n            // encrypted end of the secure pair.\n            securePair.encrypted.write(data);\n          }\n        }).catch(onError);\n      };\n\n      securePair.cleartext.once('error', onError);\n      securePair.cleartext.once('secureConnect', onSecureConnect);\n      securePair.encrypted.once('readable', onReadable);\n    });\n  }\n\n  // TODO listen for 'drain' event when socket.write returns false.\n  // TODO implement incomplete request cancelation (2.2.1.6)\n  sendMessage(packetType: number, data?: Buffer, resetConnection?: boolean) {\n    const message = new Message({ type: packetType, resetConnection: resetConnection });\n    message.end(data);\n    this.outgoingMessageStream.write(message);\n    return message;\n  }\n\n  /**\n   * Read the next incoming message from the socket.\n   */\n  async readMessage(): Promise<Message> {\n    const result = await this.incomingMessageIterator.next();\n\n    if (result.done) {\n      throw new Error('unexpected end of message stream');\n    }\n\n    return result.value;\n  }\n}\n\nexport default MessageIO;\nmodule.exports = MessageIO;\n"],"mappings":"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","ignoreList":[]}