private async Task <object> GetFileStream() { var totalLength = Length; long glostart = _start ?? 0; long gloend = _end == null || (_start == _end && _end == 0) ? totalLength : _end.Value + 1; long fileStart = 0; long fileEnd = 0; _task = Task.FromResult((WebResponse)null); foreach (var file in _files) { var clofile = file; fileEnd += clofile.Size; if (glostart >= fileEnd || gloend <= fileStart) { fileStart += clofile.Size; continue; } long clostart = Math.Max(0, glostart - fileStart); long cloend = gloend - fileStart - 1; _task = _task.ContinueWith(task1 => { WebResponse response; int retryCnt = 0; while (true) { try { var request = CreateRequest(clostart, cloend, clofile, retryCnt > 0); Logger.Debug($"HTTP:{request.Method}:{request.RequestUri.AbsoluteUri}"); response = request.GetResponse(); break; } catch (Exception wex) { if (++retryCnt <= 3) { Logger.Warn($"HTTP: Failed with {wex.Message} "); continue; } Logger.Error($"GetFileStream failed with {wex}"); _innerStream.Dispose(); throw; } } using (Stream responseStream = response.GetResponseStream()) { responseStream?.CopyTo(_innerStream); } return(response); }, TaskContinuationOptions.OnlyOnRanToCompletion); fileStart += file.Size; } _task = _task.ContinueWith(task1 => { _innerStream.Flush(); return((WebResponse)null); }, TaskContinuationOptions.OnlyOnRanToCompletion); return(_innerStream); }
private async Task <object> GetFileStream() { var totalLength = Length; long glostart = _start ?? 0; long gloend = _end == null || (_start == _end && _end == 0) ? totalLength : _end.Value + 1; long fileStart = 0; long fileEnd = 0; _task = Task.FromResult((WebResponse)null); foreach (var file in _files) { var clofile = file; fileEnd += clofile.Size; if (glostart >= fileEnd || gloend <= fileStart) { fileStart += clofile.Size; continue; } var instart = Math.Max(0, glostart - fileStart); var inend = gloend - fileStart - 1; _task = _task.ContinueWith(task1 => { WebResponse response; int cnt = 0; while (true) { try { //TODO: refact string downloadkey = string.Empty; if (_shard.Type == ShardType.WeblinkGet) { downloadkey = _cloud.Account.DownloadToken.Value; } var request = _shard.Type == ShardType.Get ? (HttpWebRequest)WebRequest.Create($"{_shard.Url}{Uri.EscapeDataString(file.FullPath)}") : (HttpWebRequest)WebRequest.Create($"{_shard.Url}{new Uri(file.PublicLink).PathAndQuery.Remove(0, "/public".Length)}?key={downloadkey}"); Logger.Debug($"HTTP:{request.Method}:{request.RequestUri.AbsoluteUri}"); request.Headers.Add("Accept-Ranges", "bytes"); request.AddRange(instart, inend); request.Proxy = _cloud.Account.Proxy; request.CookieContainer = _cloud.Account.Cookies; request.Method = "GET"; request.ContentType = MediaTypeNames.Application.Octet; request.Accept = "*/*"; request.UserAgent = ConstSettings.UserAgent; request.AllowReadStreamBuffering = false; response = request.GetResponse(); break; } catch (WebException wex) { if (wex.Status == WebExceptionStatus.ProtocolError) { if (wex.Response is HttpWebResponse wexresp && wexresp.StatusCode == HttpStatusCode.GatewayTimeout && ++cnt <= 3) { continue; } } _innerStream.Close(); throw; } } using (Stream responseStream = response.GetResponseStream()) //ReadResponseAsByte(response, CancellationToken.None, _innerStream); { responseStream?.CopyTo(_innerStream); } return(response); }, TaskContinuationOptions.OnlyOnRanToCompletion); fileStart += file.Size; } _task = _task.ContinueWith(task1 => { _innerStream.Flush(); return((WebResponse)null); }, TaskContinuationOptions.OnlyOnRanToCompletion); return(_innerStream); }