upgrade<T> method

Future<T> upgrade<T>(
  1. Future<T> handler(
    1. Socket socket
    ), {
  2. bool writeHeaders = true,
})

Upgrades the HTTP connection and yields the underlying socket to the caller.

This mirrors Shelf's Request.hijack pattern but ensures the Engine stays aware of the upgrade lifecycle. Only one upgrade is allowed per request.

Implementation

Future<T> upgrade<T>(
  Future<T> Function(Socket socket) handler, {
  bool writeHeaders = true,
}) async {
  if (_upgraded) {
    throw StateError(
      'Connection has already been upgraded for this request.',
    );
  }
  if (_response.isClosed) {
    throw StateError('Response is already closed; cannot upgrade.');
  }
  if (request.protocolVersion != '1.1') {
    throw StateError(
      'Connection upgrades are only supported for HTTP/1.1 requests.',
    );
  }

  _upgraded = true;

  await _response.flush();
  final socket = await _response.detachSocket(writeHeaders: writeHeaders);

  try {
    return await handler(socket);
  } catch (error, stack) {
    try {
      await socket.close();
    } catch (_) {}
    Error.throwWithStackTrace(error, stack);
  }
}