Example #1
0
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            if (!disposing)
            {
                return;
            }

            _task.Wait();
            _innerStream.Close();
        }
        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);
        }