upgrade<T> method
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);
}
}