download method
Implementation
@override
Future<HttpStreamResponse> download(HttpRequestData request, {DRCancelToken? cancel}) {
// 手动跟随跳转:跳转后的请求不带 Authorization(对象存储的预签名地址,《媒体/3.接口设计》第 5 节)
return _guard(request.timeoutMs, cancel, (track) async {
var url = request.url;
var headers = Map.of(request.headers);
for (var hop = 0; hop < 5; hop++) {
final req = await _client.openUrl('GET', url);
track(req);
req.followRedirects = false;
headers.forEach(req.headers.set);
final response = await req.close();
final location = response.headers.value(HttpHeaders.locationHeader);
if (response.isRedirect && location != null) {
await response.drain<void>();
url = url.resolve(location);
headers = {for (final e in headers.entries) if (e.key.toLowerCase() != 'authorization') e.key: e.value};
continue;
}
return HttpStreamResponse(status: response.statusCode, headers: _headers(response.headers), stream: response);
}
throw DRException(code: LocalErrorCode.networkError, message: 'too many redirects', source: ErrorSource.http);
});
}