connect()

in src/js/node/net.ts [457:663]


    connect(...args) {
      const [options, connectListener] = normalizeArgs(args);
      let connection = this.#socket;

      let upgradeDuplex = false;

      let {
        fd,
        port,
        host,
        path,
        socket,
        // TODOs
        localAddress,
        localPort,
        family,
        hints,
        lookup,
        noDelay,
        keepAlive,
        keepAliveInitialDelay,
        requestCert,
        rejectUnauthorized,
        pauseOnConnect,
        servername,
        checkServerIdentity,
        session,
      } = options;

      this.servername = servername;

      if (socket) {
        connection = socket;
      }
      if (fd) {
        bunConnect({
          data: this,
          fd: fd,
          socket: this.#handlers,
        }).catch(error => {
          this.emit("error", error);
          this.emit("close");
        });
      }

      this.pauseOnConnect = pauseOnConnect;
      if (!pauseOnConnect) {
        process.nextTick(() => {
          this.resume();
        });
        this.connecting = true;
      }

      if (fd) {
        return this;
      }

      this.remotePort = port;

      const bunTLS = this[bunTlsSymbol];
      var tls = undefined;

      if (typeof bunTLS === "function") {
        tls = bunTLS.$call(this, port, host, true);
        // Client always request Cert
        this._requestCert = true;

        if (tls) {
          if (typeof rejectUnauthorized !== "undefined") {
            this._rejectUnauthorized = rejectUnauthorized;
            tls.rejectUnauthorized = rejectUnauthorized;
          } else {
            this._rejectUnauthorized = tls.rejectUnauthorized;
          }
          tls.requestCert = true;
          tls.session = session || tls.session;
          this.servername = tls.servername;
          tls.checkServerIdentity = checkServerIdentity || tls.checkServerIdentity;
          this[bunTLSConnectOptions] = tls;
          if (!connection && tls.socket) {
            connection = tls.socket;
          }
        }
        if (connection) {
          if (
            typeof connection !== "object" ||
            !(connection instanceof Socket) ||
            typeof connection[bunTlsSymbol] === "function"
          ) {
            if (connection instanceof Duplex) {
              upgradeDuplex = true;
            } else {
              throw new TypeError("socket must be an instance of net.Socket or Duplex");
            }
          }
        }
        this.authorized = false;
        this.secureConnecting = true;
        this._secureEstablished = false;
        this._securePending = true;

        if (connectListener) this.on("secureConnect", connectListener);
      } else if (connectListener) this.on("connect", connectListener);

      // start using existing connection
      try {
        if (connection) {
          if (upgradeDuplex) {
            this.connecting = true;
            this.#upgraded = connection;

            const [result, events] = upgradeDuplexToTLS(connection, {
              data: this,
              tls,
              socket: this.#handlers,
            });

            connection.on("data", events[0]);
            connection.on("end", events[1]);
            connection.on("drain", events[2]);
            connection.on("close", events[3]);

            this[bunSocketInternal] = result;
          } else {
            const socket = connection[bunSocketInternal];

            if (socket) {
              this.connecting = true;
              this.#upgraded = connection;
              const result = socket.upgradeTLS({
                data: this,
                tls,
                socket: this.#handlers,
              });
              if (result) {
                const [raw, tls] = result;
                // replace socket
                connection[bunSocketInternal] = raw;
                this.once("end", this.#closeRawConnection);
                raw.connecting = false;
                this[bunSocketInternal] = tls;
              } else {
                this[bunSocketInternal] = null;
                throw new Error("Invalid socket");
              }
            } else {
              // wait to be connected
              connection.once("connect", () => {
                const socket = connection[bunSocketInternal];
                if (!socket) return;

                this.connecting = true;
                this.#upgraded = connection;
                const result = socket.upgradeTLS({
                  data: this,
                  tls,
                  socket: this.#handlers,
                });

                if (result) {
                  const [raw, tls] = result;
                  // replace socket
                  connection[bunSocketInternal] = raw;
                  this.once("end", this.#closeRawConnection);
                  raw.connecting = false;
                  this[bunSocketInternal] = tls;
                } else {
                  this[bunSocketInternal] = null;
                  throw new Error("Invalid socket");
                }
              });
            }
          }
        } else if (path) {
          // start using unix socket
          bunConnect({
            data: this,
            unix: path,
            socket: this.#handlers,
            tls,
          }).catch(error => {
            this.emit("error", error);
            this.emit("close");
          });
        } else {
          // default start
          bunConnect({
            data: this,
            hostname: host || "localhost",
            port: port,
            socket: this.#handlers,
            tls,
          }).catch(error => {
            this.emit("error", error);
            this.emit("close");
          });
        }
      } catch (error) {
        process.nextTick(emitErrorAndCloseNextTick, this, error);
      }
      // reset the underlying writable object when establishing a new connection
      // this is a function on `Duplex`, originally defined on `Writable`
      // https://github.com/nodejs/node/blob/c5cfdd48497fe9bd8dbd55fd1fca84b321f48ec1/lib/net.js#L311
      // https://github.com/nodejs/node/blob/c5cfdd48497fe9bd8dbd55fd1fca84b321f48ec1/lib/net.js#L1126
      this._undestroy();
      return this;
    }