download method

  1. @override
Future<HttpStreamResponse> download(
  1. HttpRequestData request, {
  2. DRCancelToken? cancel,
})
override

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);
  });
}