handle method
Performs req and returns the proxied response, or an error response on a
rejected target / transport failure.
Implementation
Future<HttpProxyResponse> handle(HttpProxyRequest req) async {
final uri = Uri.tryParse(req.url);
if (uri == null || !uri.hasScheme) {
return _error(req, 'invalid url');
}
if (uri.scheme != 'https') {
return _error(req, 'only https is allowed');
}
if (!_allowedHosts.contains(uri.host)) {
return _error(req, 'host not allowed: ${uri.host}');
}
final headers = <String, String>{...req.headers};
final Uri target;
try {
target = _applyCredentials(req, uri, headers);
} on _CredentialError catch (e) {
return _error(req, e.message);
}
final stopwatch = Stopwatch()..start();
try {
final request = http.Request(req.method, target)
..headers.addAll(headers)
..body = req.body;
final streamed = await httpClient.send(request).timeout(timeout);
final response = await http.Response.fromStream(streamed);
stopwatch.stop();
// Report the real upstream duration so a proxied client measures the
// model's generation speed without the browser↔Hub round-trip (see
// [aiRequestMs]).
return HttpProxyResponse(
requestId: req.requestId,
statusCode: response.statusCode,
headers: {
...response.headers,
kAiProxyElapsedMsHeader: '${stopwatch.elapsedMilliseconds}',
},
body: response.body,
);
} on Object catch (e) {
return _error(req, 'request failed: $e');
}
}