async function connectH1 (client, socket) {
  client[kSocket] = socket

  if (!llhttpInstance) {
    const noop = () => {}
    socket.on('error', noop)
    llhttpInstance = await llhttpPromise
    llhttpPromise = null
    socket.off('error', noop)
  }

  if (socket.errored) {
    throw socket.errored
  }

  if (socket.destroyed) {
    throw new SocketError('destroyed')
  }

  socket[kNoRef] = false
  socket[kWriting] = false
  socket[kReset] = false
  socket[kBlocking] = false
  socket[kParser] = new Parser(client, socket, llhttpInstance)

  util.addListener(socket, 'error', onHttpSocketError)
  util.addListener(socket, 'readable', onHttpSocketReadable)
  util.addListener(socket, 'end', onHttpSocketEnd)
  util.addListener(socket, 'close', onHttpSocketClose)

  socket[kClosed] = false
  socket.on('close', onSocketClose)

  return {
    version: 'h1',
    defaultPipelining: 1,
    write (request) {
      return writeH1(client, request)
    },
    resume () {
      resumeH1(client)
    },
    /**
     * @param {Error|undefined} err
     * @param {() => void} callback
     */
    destroy (err, callback) {
      if (socket[kClosed]) {
        queueMicrotask(callback)
      } else {
        socket.on('close', callback)
        socket.destroy(err)
      }
    },
    /**
     * @returns {boolean}
     */
    get destroyed () {
      return socket.destroyed
    },
    /**
     * @param {import('../core/request.js')} request
     * @returns {boolean}
     */
    busy (request) {
      if (socket[kWriting] || socket[kReset] || socket[kBlocking]) {
        return true
      }

      if (request) {
        if (client[kRunning] > 0 && !request.idempotent) {
          // Non-idempotent request cannot be retried.
          // Ensure that no other requests are inflight and
          // could cause failure.
          return true
        }

        if (client[kRunning] > 0 && (request.upgrade || request.method === 'CONNECT')) {
          // Don't dispatch an upgrade until all preceding requests have completed.
          // A misbehaving server might upgrade the connection before all pipelined
          // request has completed.
          return true
        }

        if (client[kRunning] > 0 && util.bodyLength(request.body) !== 0 &&
          (util.isStream(request.body) || util.isAsyncIterable(request.body) || util.isFormDataLike(request.body))) {
          // Request with stream or iterator body can error while other requests
          // are inflight and indirectly error those as well.
          // Ensure this doesn't happen by waiting for inflight
          // to complete before dispatching.

          // Request with stream or iterator body cannot be retried.
          // Ensure that no other requests are inflight and
          // could cause failure.
          return true
        }
      }

      return false
    }
  }
}
@param {import ('./client.js')} client
@param {import('net').Socket} socket
@returns