public static string Download(string url, out string etag, string filename = null, IUser user = null) { TxFileManager FileTransaction = new TxFileManager(); user = user ?? new NullUser(); user.RaiseMessage("Downloading {0}", url); // Generate a temporary file if none is provided. if (filename == null) { filename = FileTransaction.GetTempFileName(); } log.DebugFormat("Downloading {0} to {1}", url, filename); try { var agent = MakeDefaultHttpClient(); agent.DownloadFile(url, filename); etag = agent.ResponseHeaders.Get("ETag")?.Replace("\"", ""); } // Explicit redirect handling. This is needed when redirecting from HTTPS to HTTP on .NET Core. catch (WebException ex) { if (ex.Status != WebExceptionStatus.ProtocolError) { throw; } HttpWebResponse response = ex.Response as HttpWebResponse; if (response?.StatusCode != HttpStatusCode.Redirect) { throw; } return(Download(response.GetResponseHeader("Location"), out etag, filename, user)); } catch (Exception e) { log.InfoFormat("Native download failed, trying with CurlSharp..."); etag = null; try { Curl.Init(); using (FileStream stream = File.OpenWrite(filename)) { string header = string.Empty; var client = Curl.CreateEasy(url, stream, delegate(byte[] buf, int size, int nmemb, object extraData) { header += Encoding.UTF8.GetString(buf); return(size * nmemb); }); using (client) { var result = client.Perform(); var returnCode = client.ResponseCode; if (result != CurlCode.Ok || returnCode >= 300) { // Always log if it's an error. log.ErrorFormat("Response from {0}:\r\n\r\n{1}\r\n{2}", url, header, "Content not logged because it is likely a file."); WebException curlException = new WebException($"Curl download failed with status {returnCode}."); throw new NativeAndCurlDownloadFailedKraken( new List <Exception> { e, curlException }, url.ToString(), header, null, returnCode ); } else { // Only log if debug flag is set. log.DebugFormat("Response from {0}:\r\n\r\n{1}\r\n{2}", url, header, "Content not logged because it is likely a file."); } } } Curl.CleanUp(); return(filename); } catch { // D'oh, failed again. Fall through to clean-up handling. } // Clean up our file, it's unlikely to be complete. // We do this even though we're using transactional files, as we may not be in a transaction. // It's okay if this fails. try { log.DebugFormat("Removing {0} after web error failure", filename); FileTransaction.Delete(filename); } catch { // Apparently we need a catch, even if we do nothing. } // Look for an exception regarding the authentication. if (Regex.IsMatch(e.ToString(), "The authentication or decryption has failed.")) { throw new MissingCertificateKraken("Failed downloading " + url, e); } // Not the exception we were looking for! Throw it further upwards! throw; } return(filename); }
public static string Download(string url, string filename = null, IUser user = null) { user = user ?? new NullUser(); user.RaiseMessage("Downloading {0}", url); // Generate a temporary file if none is provided. if (filename == null) { filename = FileTransaction.GetTempFileName(); } Log.DebugFormat("Downloading {0} to {1}", url, filename); var agent = MakeDefaultHttpClient(); try { agent.DownloadFile(url, filename); } catch (Exception ex) { Log.InfoFormat("Download failed, trying with curlsharp..."); try { Curl.Init(); using (FileStream stream = File.OpenWrite(filename)) using (var curl = Curl.CreateEasy(url, stream)) { CurlCode result = curl.Perform(); if (result != CurlCode.Ok) { throw new Kraken("curl download of " + url + " failed with CurlCode " + result); } else { Log.Debug("curlsharp download successful"); } } Curl.CleanUp(); return(filename); } catch { // D'oh, failed again. Fall through to clean-up handling. } // Clean up our file, it's unlikely to be complete. // We do this even though we're using transactional files, as we may not be in a transaction. // It's okay if this fails. try { Log.DebugFormat("Removing {0} after web error failure", filename); FileTransaction.Delete(filename); } catch { // Apparently we need a catch, even if we do nothing. } // Look for an exception regarding the authentication. if (Regex.IsMatch(ex.ToString(), "The authentication or decryption has failed.")) { throw new MissingCertificateKraken("Failed downloading " + url, ex); } // Not the exception we were looking for! Throw it further upwards! throw; } return(filename); }
public static string Download(string url, out string etag, string filename = null, IUser user = null) { TxFileManager FileTransaction = new TxFileManager(); user = user ?? new NullUser(); user.RaiseMessage("Downloading {0}", url); // Generate a temporary file if none is provided. if (filename == null) { filename = FileTransaction.GetTempFileName(); } log.DebugFormat("Downloading {0} to {1}", url, filename); try { var agent = MakeDefaultHttpClient(); agent.DownloadFile(url, filename); etag = agent.ResponseHeaders.Get("ETag")?.Replace("\"", ""); } // Explicit redirect handling. This is needed when redirecting from HTTPS to HTTP on .NET Core. catch (WebException ex) { if (ex.Status != WebExceptionStatus.ProtocolError) { throw; } HttpWebResponse response = ex.Response as HttpWebResponse; if (response.StatusCode != HttpStatusCode.Redirect) { throw; } return(Net.Download(response.GetResponseHeader("Location"), out etag, filename, user)); } catch (Exception ex) { log.InfoFormat("Download failed, trying with curlsharp..."); etag = null; try { Curl.Init(); using (FileStream stream = File.OpenWrite(filename)) using (var curl = Curl.CreateEasy(url, stream)) { CurlCode result = curl.Perform(); if (result != CurlCode.Ok) { throw new Kraken("curl download of " + url + " failed with CurlCode " + result); } else { log.Debug("curlsharp download successful"); } } Curl.CleanUp(); return(filename); } catch { // D'oh, failed again. Fall through to clean-up handling. } // Clean up our file, it's unlikely to be complete. // We do this even though we're using transactional files, as we may not be in a transaction. // It's okay if this fails. try { log.DebugFormat("Removing {0} after web error failure", filename); FileTransaction.Delete(filename); } catch { // Apparently we need a catch, even if we do nothing. } // Look for an exception regarding the authentication. if (Regex.IsMatch(ex.ToString(), "The authentication or decryption has failed.")) { throw new MissingCertificateKraken("Failed downloading " + url, ex); } // Not the exception we were looking for! Throw it further upwards! throw; } return(filename); }