Ejemplo n.º 1
0
        public DownloaderResult Download(Uri url, DownloaderOptions options)
        {
            var head = CreateRequest(url, options);
            head.Method = "HEAD";
            var headResponse = (HttpWebResponse)head.GetResponse();
            headResponse.Close();

            if (this.IsRedirect(headResponse)) {
                var target = headResponse.Headers[HttpResponseHeader.Location];
                if (target.IsNullOrEmpty())
                    throw new Exception("Response is a redirect, but location header was not set.");

                return Download(new Uri(target), options);
            }

            if (headResponse.StatusCode != HttpStatusCode.OK)
                throw new NotSupportedException(string.Format("HEAD request returned a response code {0}: {1} that is currently not supported.", headResponse.StatusCode, headResponse.StatusDescription));

            while (true) {
                try {
                    return Download(url, headResponse, options);
                }
                catch (DownloadException ex) {
                    this.logger.LogError("Download error {0}, retrying.", ex.Message);
                }
            }
        }
Ejemplo n.º 2
0
        private static HttpWebRequest CreateRequest(Uri url, DownloaderOptions options)
        {
            var request = (HttpWebRequest)WebRequest.Create(url);
            request.Credentials = options.Credentials;
            request.AllowAutoRedirect = false;

            return request;
        }
Ejemplo n.º 3
0
        private DownloaderResult Download(Uri url, HttpWebResponse headResponse, DownloaderOptions options)
        {
            var fullLength = headResponse.ContentLength;
            var fileName = GetFileName(headResponse);
            var file = this.mapPath(url, fileName);
            file.Directory.Create();

            logger.LogMessage("-> {0}", file.FullName);

            var get = CreateRequest(url, options);
            get.Method = "GET";
            var lengthDownloadedBefore = 0L;
            var fileMode = FileMode.Append;
            if (file.Exists && file.Length > 0) {
                if (file.Length == fullLength) {
                    this.logger.LogMessage("File is already fully downloaded.");
                    return new DownloaderResult(url, file, headResponse.ContentType);
                }

                if (file.Length < fullLength) {
                    this.logger.LogMessage("File already exists, requesting range {0}-{1}.", file.Length, headResponse.ContentLength);
                    get.AddRange(file.Length, fullLength);
                    lengthDownloadedBefore = file.Length;
                }
                else if (fullLength <= 0) {
                    this.logger.LogWarning("File already exists, but server did not provide length, so it will be fully redownloaded.");
                    fileMode = FileMode.Create;
                }
                else {
                    this.logger.LogWarning("File already exists, but it is larger than file on server, so it will be fully redownloaded. ");
                    fileMode = FileMode.Create;
                }
            }

            var response = get.GetResponse();
            var downloadedTotal = 0L;
            using (response)
            using (var fileStream = file.Open(fileMode, FileAccess.Write, FileShare.Read))
            using (var webStream = response.GetResponseStream()) {
                var buffer = new byte[1024];
                var time = new Stopwatch();
                time.Start();

                while (true) {
                    int count;
                    try {
                        count = webStream.Read(buffer, 0, buffer.Length);
                    }
                    catch (IOException ex) {
                        throw new DownloadException(ex.Message, ex);
                    }
                    if (count == 0)
                        break;

                    downloadedTotal += count;
                    fileStream.Write(buffer, 0, count);

                    options.ReportProgress(new DownloaderProgress {
                        File = file,

                        BytesDownloadedBefore = lengthDownloadedBefore,
                        BytesDownloaded = downloadedTotal,
                        BytesTotal = fullLength,
                        TimeElapsed = time.Elapsed
                    });
                }
            }

            this.logger.LogMessage("Download completed.");
            var contentType = new ContentType(headResponse.ContentType);
            return new DownloaderResult(url, file, contentType.MediaType);
        }