/// <summary> /// Called to Build the instance HttpWebRequest request with the proxy parameters /// and SSL/X509 with the WW user certificate /// </summary> /// protected HttpWebRequest BuildRequest() { // Create the request object. request = (HttpWebRequest)WebRequest.Create(Url); request.UserAgent = UserAgent; request.Credentials = RequestCredentials; if (RequestTimeout != 0) { request.Timeout = RequestTimeout; } if (this.Compressed) { request.Headers.Add("Accept-Encoding", "gzip,deflate"); } request.Proxy = ProxyHelper.DetermineProxyForUrl( Url, useWindowsDefaultProxy, useDynamicProxy, proxyUrl, proxyUserName, proxyPassword); X509Store certStore = new X509Store(StoreLocation.CurrentUser); certStore.Open(OpenFlags.OpenExistingOnly); col = new X509CertificateCollection(certStore.Certificates); certStore.Close(); ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(VerifyServerCertificate); request.ClientCertificates = col; return(request); }
/// <summary> /// Synchronous HTTP download /// </summary> protected void Download() { Log.Write(Log.Levels.Debug, "Starting download thread..."); Debug.Assert(Url.StartsWith("http://")); DownloadStartTime = DateTime.Now; try { try { // If a registered progress-callback, inform it of our download progress so far. OnProgressCallback(0, 1); OnDebugCallback(this); // check to see if thread was aborted (multiple such checks within the thread function) if (stopFlag) { IsComplete = true; return; } // create content stream from memory or file if (isMemoryDownload && ContentStream == null) { ContentStream = new MemoryStream(); } else { // Download to file string targetDirectory = Path.GetDirectoryName(SavedFilePath); if (targetDirectory.Length > 0) { Directory.CreateDirectory(targetDirectory); } ContentStream = new FileStream(SavedFilePath, FileMode.Create); } // Create the request object. request = (HttpWebRequest)WebRequest.Create(Url); request.UserAgent = UserAgent; if (this.Compressed) { request.Headers.Add("Accept-Encoding", "gzip,deflate"); } if (stopFlag) { IsComplete = true; return; } request.Proxy = ProxyHelper.DetermineProxyForUrl( Url, useWindowsDefaultProxy, useDynamicProxy, proxyUrl, proxyUserName, proxyPassword); // TODO: probably better done via BeginGetResponse() / EndGetResponse() because this may block for a while // causing warnings in thread abortion. using (response = request.GetResponse() as HttpWebResponse) { // only if server responds 200 OK if (response.StatusCode == HttpStatusCode.OK) { ContentType = response.ContentType; ContentEncoding = response.ContentEncoding; // Find the data size from the headers. string strContentLength = response.Headers["Content-Length"]; if (strContentLength != null) { ContentLength = int.Parse(strContentLength, CultureInfo.InvariantCulture); } byte[] readBuffer = new byte[1500]; using (Stream responseStream = response.GetResponseStream()) { while (true) { if (stopFlag) { IsComplete = true; return; } // Pass do.readBuffer to BeginRead. int bytesRead = responseStream.Read(readBuffer, 0, readBuffer.Length); if (bytesRead <= 0) { break; } //TODO: uncompress responseStream if necessary so that ContentStream is always uncompressed // - at the moment, ContentStream is compressed if the requesting code sets // download.Compressed == true, so ContentStream must be decompressed // by whatever code is requesting the gzipped download // - this hack only works for requests made using the methods that download to memory, // requests downloading to file will result in a gzipped file // - requests that do not explicity set download.Compressed = true should be unaffected ContentStream.Write(readBuffer, 0, bytesRead); BytesProcessed += bytesRead; // If a registered progress-callback, inform it of our download progress so far. OnProgressCallback(BytesProcessed, ContentLength); OnDebugCallback(this); } } } } HandleErrors(); } catch (ThreadAbortException) { // re-throw to avoid it being caught by the catch-all below Log.Write(Log.Levels.Verbose, "Re-throwing ThreadAbortException."); throw; } catch (System.Configuration.ConfigurationException) { // is thrown by WebRequest.Create if App.config is not in the correct format // TODO: don't know what to do with it throw; } catch (Exception caught) { try { // Remove broken file download if (ContentStream != null) { ContentStream.Close(); ContentStream = null; } if (SavedFilePath != null && SavedFilePath.Length > 0) { File.Delete(SavedFilePath); } } catch (Exception) { } SaveException(caught); } if (stopFlag) { IsComplete = true; return; } if (ContentLength == 0) { ContentLength = BytesProcessed; // If a registered progress-callback, inform it of our completion OnProgressCallback(BytesProcessed, ContentLength); } if (ContentStream is MemoryStream) { ContentStream.Seek(0, SeekOrigin.Begin); } else if (ContentStream != null) { ContentStream.Close(); ContentStream = null; } OnDebugCallback(this); if (CompleteCallback == null) { Verify(); } else { CompleteCallback(this); } } catch (ThreadAbortException) { Log.Write(Log.Levels.Verbose, "Download aborted."); } finally { IsComplete = true; } OnDownloadEnded(this); }