import 'dart:io' as io show HttpClient, HttpHeaders; import 'package:http/http.dart' as http; import 'package:http/io_client.dart'; const _sessionCookie = 'session_id'; @override http.Client buildHttpClient() => _SessionClient(IOClient(io.HttpClient())); class _SessionClient extends http.BaseClient { final http.Client _inner; String? _sessionId; _SessionClient(this._inner); @override Future send(http.BaseRequest request) async { if (_sessionId != null) { request.headers[io.HttpHeaders.cookieHeader] = '$_sessionCookie=$_sessionId'; } request.followRedirects = false; request.maxRedirects = 0; http.StreamedResponse response = await _inner.send(request); _captureCookie(response.headers[io.HttpHeaders.setCookieHeader]); while (response.isRedirect) { final location = response.headers['location']; if (location == null) break; final redirected = http.Request(request.method, Uri.parse(location)) ..headers.addAll(request.headers) ..bodyBytes = await response.stream.toBytes() ..followRedirects = false ..maxRedirects = 0; response = await _inner.send(redirected); _captureCookie(response.headers[io.HttpHeaders.setCookieHeader]); } return response; } void _captureCookie(String? setCookieHeader) { if (setCookieHeader == null) return; final match = RegExp('$_sessionCookie=([^;]+)', caseSensitive: false) .firstMatch(setCookieHeader); if (match != null) _sessionId = match.group(1); } }