internal static CurlCode EasyGetInfo(this CurlHandle handle, CurlInfo info, out string value) { CurlCode result = EasyGetInfo(handle, info, out IntPtr text); value = MarshalString.NativeToString(text); return(result); }
internal static void ThrowIfNotOk(this Curl instance, CurlCode code) { if (code != CurlCode.Ok) { throw new CurlException(code, instance); } }
// Private members private static string GetExceptionMessage(CurlCode resultCode) { StringBuilder sb = new StringBuilder(); sb.Append($"({(int)resultCode}) "); if ((int)resultCode == -1) { sb.Append("The process exited prematurely."); } else { switch (resultCode) { case CurlCode.OK: sb.Append("The operation completed successfully."); break; case CurlCode.CouldntResolveHost: sb.Append(Properties.ExceptionMessages.CurlCouldntResolveHost); break; case CurlCode.PeerFailedVerification: sb.Append(Properties.ExceptionMessages.CurlPeerFailedVerification); break; default: sb.Append($"The operation returned with error code {(int)resultCode}"); break; } } return(sb.ToString()); }
/// <summary> /// Starts a thread to watch download progress. Invoked by DownloadCUrl. Not for /// public consumption. /// </summary> private void CurlWatchThread(int index, CurlEasy easy, FileStream stream) { log.Debug("Curlsharp download thread started"); // This should run until completion or failture. CurlCode result = easy.Perform(); log.Debug("Curlsharp download complete"); // Dispose of all our disposables. // We have to do this *BEFORE* we call FileDownloadComplete, as it // ensure we've written everything out to disk. stream.Dispose(); easy.Dispose(); if (result == CurlCode.Ok) { FileDownloadComplete(index, null); } else { // The CurlCode result expands to a human-friendly string, so we can just // throw a kraken containing it and nothing else. The FileDownloadComplete // code collects these into a larger DownloadErrorsKraken aggregate. FileDownloadComplete( index, new Kraken(result.ToString()) ); } }
public Curl(int bufferSize) { if (_initialized != CurlCode.Ok) { if (_initialized == CurlCode.NotInitialized) { throw new CurlNotInitializedException(); } throw new CurlException(_initialized, this); } _buffer = new byte[bufferSize]; _errorBuffer = Marshal.AllocHGlobal(ErrorBufferSize); _curl = CurlNative.EasyInit(); if (_curl == IntPtr.Zero) { throw new CurlEasyInitializeException("Curl Easy failed to initialize!"); } CurlCode result = CurlNative.EasySetOpt(_curl, CurlOption.Errorbuffer, _errorBuffer); if (result != CurlCode.Ok) { throw new CurlException(result, this); } }
public static void Deinitialize() { if (_initialized != CurlCode.NotInitialized) { CurlNative.GlobalCleanup(); _initialized = CurlCode.NotInitialized; } }
public static bool Initialize() { if (_initialized != CurlCode.Ok) { _initialized = CurlNative.GlobalInit(CurlGlobal.Default); } return(_initialized == CurlCode.Ok); }
/// <summary> /// Process-wide initialization -- call only once per process. /// </summary> /// <param name="flags"> /// An or'd combination of /// <see cref="CurlInitFlag" /> members. /// </param> /// <returns> /// A <see cref="CurlCode" />, hopefully /// <c>CurlCode.Ok</c>. /// </returns> public static CurlCode GlobalInit(CurlInitFlag flags) { _initCode = NativeMethods.curl_global_init((int)flags); #if USE_LIBCURLSHIM if (_initCode == CurlCode.Ok) NativeMethods.curl_shim_initialize(); #endif return _initCode; }
/// <summary> /// Process-wide cleanup -- call just before exiting process. /// </summary> /// <remarks> /// While it's not necessary that your program call this method /// before exiting, doing so will prevent leaks of native cURL resources. /// </remarks> public static void GlobalCleanup() { if (_initCode == CurlCode.Ok) { #if USE_LIBCURLSHIM NativeMethods.curl_shim_cleanup(); #endif NativeMethods.curl_global_cleanup(); _initCode = CurlCode.FailedInit; } }
internal string GetError(CurlCode code) { if (code == CurlCode.NotInitialized) { return("Curl Global not initialized"); } string error = MarshalString.Utf8ToString(_errorBuffer); return(string.IsNullOrEmpty(error) ? MarshalString.Utf8ToString(CurlNative.EasyStrError(code)) : error); }
/// <summary> /// Process-wide initialization -- call only once per process. /// </summary> /// <param name="flags"> /// An or'd combination of /// <see cref="CurlInitFlag" /> members. /// </param> /// <returns> /// A <see cref="CurlCode" />, hopefully /// <c>CurlCode.Ok</c>. /// </returns> public static CurlCode GlobalInit(CurlInitFlag flags) { _initCode = NativeMethods.curl_global_init((int)flags); #if USE_LIBCURLSHIM if (_initCode == CurlCode.Ok) { NativeMethods.curl_shim_initialize(); } #endif return(_initCode); }
public void Reset() { _offset = 0; CurlNative.EasyReset(_curl); CurlCode result = CurlNative.EasySetOpt(_curl, CurlOption.Errorbuffer, _errorBuffer); if (result != CurlCode.Ok) { throw new CurlException(result, this); } }
public ArraySegment <byte> GetBytes(string url) { IntPtr urlpointer = IntPtr.Zero; IntPtr useragentpointer = IntPtr.Zero; try { urlpointer = MarshalString.StringToUtf8(url); CurlCode result = CurlNative.EasySetOpt(_curl, CurlOption.Url, urlpointer); if (result != CurlCode.Ok) { throw new CurlException(result, this); } useragentpointer = MarshalString.StringToUtf8(UserAgent); CurlCode result1 = CurlNative.EasySetOpt(_curl, CurlOption.Useragent, useragentpointer); if (result1 != CurlCode.Ok) { throw new CurlException(result1, this); } CurlCode result2 = CurlNative.EasySetOpt(_curl, CurlOption.WriteData, this); if (result2 != CurlCode.Ok) { throw new CurlException(result2, this); } CurlCode result3 = CurlNative.EasySetOpt(_curl, CurlOption.WriteFunction, WriteCallback); if (result3 != CurlCode.Ok) { throw new CurlException(result3, this); } CurlCode result4 = CurlNative.EasyPerform(_curl); if (result4 != CurlCode.Ok) { throw new CurlException(result4, this); } return(new ArraySegment <byte>(_buffer, 0, _offset)); } finally { if (urlpointer != IntPtr.Zero) { Marshal.FreeHGlobal(urlpointer); } if (useragentpointer != IntPtr.Zero) { Marshal.FreeHGlobal(useragentpointer); } } }
public static bool IsConnectionFailure(CurlCode code) { // ReSharper disable once SwitchStatementMissingSomeCases switch (code) { case CurlCode.CURLE_COULDNT_RESOLVE_PROXY: case CurlCode.CURLE_COULDNT_RESOLVE_HOST: case CurlCode.CURLE_COULDNT_CONNECT: case CurlCode.CURLE_SSL_CIPHER: case CurlCode.CURLE_SSL_CERTPROBLEM: case CurlCode.CURLE_SSL_CONNECT_ERROR: case CurlCode.CURLE_SSL_ENGINE_NOTFOUND: return(true); } return(false); }
/// <summary> /// Takes a URL, and returns the content found there as a string. /// </summary> /// <returns>The string.</returns> /// <param name="url">URL.</param> public string DownloadString(string url) { log.DebugFormat("About to download {0}", url); var content = string.Empty; easy.Url = url; easy.WriteData = null; easy.WriteFunction = delegate(byte[] buf, int size, int nmemb, object extraData) { content += Encoding.UTF8.GetString(buf); return(size * nmemb); }; CurlCode result = easy.Perform(); if (result != CurlCode.Ok) { throw new Exception("Curl download failed with error " + result); } log.DebugFormat("Download from {0}:\n\n{1}", url, content); return(content); }
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); }
/// <summary> /// Class constructor - initialize global status. /// </summary> static Curl() { _initCode = CurlCode.FailedInit; }
public static bool IsCurlException(Exception error, out CurlCode code) { code = (CurlCode)(error?.HResult ?? 0); return(error != null && error.GetType() == CurlExceptionType); }
private void TheCurlCodeShouldBe(CurlCode curlCode) { _httpContext.HttpResponse.CurlCode.ShouldBe(curlCode, $"The cURL Code should be {curlCode} but was {_httpContext.HttpResponse.CurlCode}"); }
internal static extern IntPtr curl_easy_strerror(CurlCode err);
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); }
public CurlException(CurlCode resultCode, string message) : base(message) { this.ResultCode = resultCode; }
public CurlException(int exitCode, string message) : base(message) { this.ResultCode = (CurlCode)exitCode; }
public CurlException(string message) : base(message) { this.ResultCode = (CurlCode)(-1); }
internal CurlMultiInfo(CurlMessage msg, CurlEasy curlEasy, CurlCode result) { _msg = msg; _mCurlEasy = curlEasy; _result = result; }
public CurlException(string message, Exception innerException) : base(message, innerException) { this.ResultCode = (CurlCode)(-1); }
public static extern IntPtr curl_easy_strerror(CurlCode err);
public string Post(string url, string data, Encoding encoding) { IntPtr urlpointer = IntPtr.Zero; IntPtr useragentpointer = IntPtr.Zero; IntPtr datapointer = IntPtr.Zero; try { urlpointer = MarshalString.StringToUtf8(url); CurlCode result = CurlNative.EasySetOpt(_curl, CurlOption.Url, urlpointer); if (result != CurlCode.Ok) { throw new CurlException(result, this); } useragentpointer = MarshalString.StringToUtf8(UserAgent); CurlCode result1 = CurlNative.EasySetOpt(_curl, CurlOption.Useragent, useragentpointer); if (result1 != CurlCode.Ok) { throw new CurlException(result1, this); } datapointer = MarshalString.StringToUtf8(data); CurlCode result2 = CurlNative.EasySetOpt(_curl, CurlOption.Postfields, datapointer); if (result2 != CurlCode.Ok) { throw new CurlException(result2, this); } CurlCode result3 = CurlNative.EasySetOpt(_curl, CurlOption.WriteData, this); if (result3 != CurlCode.Ok) { throw new CurlException(result3, this); } CurlCode result4 = CurlNative.EasySetOpt(_curl, CurlOption.WriteFunction, WriteCallback); if (result4 != CurlCode.Ok) { throw new CurlException(result4, this); } CurlCode result5 = CurlNative.EasyPerform(_curl); if (result5 != CurlCode.Ok) { throw new CurlException(result5, this); } return(encoding.GetString(_buffer, 0, _offset)); } finally { if (urlpointer != IntPtr.Zero) { Marshal.FreeHGlobal(urlpointer); } if (useragentpointer != IntPtr.Zero) { Marshal.FreeHGlobal(useragentpointer); } if (datapointer != IntPtr.Zero) { Marshal.FreeHGlobal(datapointer); } } }
internal CurlException(CurlCode code, Curl instance) : base(instance.GetError(code)) { Code = code; Instance = instance; }
public CurlException(CurlCode resultCode) : base(GetExceptionMessage(resultCode)) { this.ResultCode = resultCode; }
// private members internal CurlMultiInfo(CurlMessage msg, CurlEasy curlEasy, CurlCode result) { Msg = msg; CurlEasyHandle = curlEasy; Result = result; }