public CURLE Perform() { CURLE result = (CURLE)(-1); if (!running) { running = true; retryCount = maxRetryCount; while (true) { Prepare(); result = Lib.curl_easy_perform(easyPtr); var done = ProcessResponse(result); if (done || --retryCount < 0) { Dump(); break; } else { Thread.Sleep(retryInterval); } } running = false; } else { CurlLog.LogError("Can't preform a running handle again!"); } return(result); }
public void MultiPerform(CurlMulti _multi = null) { if (!running) { running = true; retryCount = maxRetryCount; multi = _multi ?? CurlMultiUpdater.Instance.DefaultMulti; Prepare(); multi.AddEasy(this); } else { CurlLog.LogError("Can't preform a running handle again!"); } }
private void Dump() { if (!dump) { return; } try { var sb = new StringBuilder(); GetInfo(CURLINFO.EFFECTIVE_URL, out string effectiveUrl); GetInfo(CURLINFO.TOTAL_TIME, out double time); GetInfo(CURLINFO.PRIMARY_IP, out string ip); #if UNITY_EDITOR var colorize = true; #else var colorize = false; #endif if (colorize) { sb.AppendLine($"<color={((status >= 200 && status <= 299) ? "green" : "red")}><b>[{method.ToUpper()}]</b></color> {effectiveUrl}({ip}) [{httpVersion} {status} {message}] [{outDataLength}({(outData != null ? outData.Length : 0)}) | {inDataLength}({(inData != null ? inData.Length : 0)}) | {time * 1000} ms]"); } else { sb.AppendLine($"[{method.ToUpper()}] {effectiveUrl}({ip}) [{httpVersion} {status} {message}] [{outDataLength}({(outData != null ? outData.Length : 0)}) | {inDataLength}({(inData != null ? inData.Length : 0)}) | {time * 1000} ms]"); } if (debug) { if (outHeader != null) { if (colorize) { sb.AppendLine("<b><color=lightblue>Request Headers</color></b>"); } else { sb.AppendLine("-- Request Headers --"); } foreach (var entry in outHeader) { if (colorize) { sb.AppendLine($"<b><color=silver>[{entry.Key}]</color></b> {entry.Value}"); } else { sb.AppendLine($"[{entry.Key}] {entry.Value}"); } } } if (outData != null && outData.Length > 0) { if (colorize) { sb.AppendLine($"<b><color=lightblue>Request Body</color></b> [ {outData.Length} ]"); } else { sb.AppendLine($"-- Request Body -- [ {outData.Length} ]"); } string outDataString = decoder?.DecodeOutData(this) ?? Encoding.UTF8.GetString(outData, 0, Math.Min(outData.Length, 0x400)); sb.AppendLine(outDataString); } if (inHeader != null) { if (colorize) { sb.AppendLine("<b><color=lightblue>Response Headers</color></b>"); } else { sb.AppendLine("-- Response Headers --"); } foreach (var entry in inHeader) { if (colorize) { sb.AppendLine($"<b><color=silver>[{entry.Key}]</color></b> {entry.Value}"); } else { sb.AppendLine($"[{entry.Key}] {entry.Value}"); } } } if (inData != null && inData.Length > 0) { if (colorize) { sb.AppendLine($"<b><color=lightblue>Response Body</color></b> [ {inData.Length} ]"); } else { sb.AppendLine($"-- Response Body -- [ {inData.Length} ]"); } string inDataString = decoder?.DecodeInData(this) ?? Encoding.UTF8.GetString(inData, 0, Math.Min(inData.Length, 0x400)); sb.AppendLine(inDataString); } } CurlLog.Log(sb.ToString()); } catch (Exception e) { CurlLog.LogError("Unexpected exception: " + e); } }
private bool ProcessResponse(CURLE result) { var done = false; try { thisHandle.Free(); if (result == CURLE.OK) { responseHeaderStream.Position = 0; var sr = new StreamReader(responseHeaderStream); // Handle first line { var line = sr.ReadLine(); var index = line.IndexOf(' '); httpVersion = line.Substring(0, index); var nextIndex = line.IndexOf(' ', index + 1); if (int.TryParse(line.Substring(index + 1, nextIndex - index), out var _status)) { status = _status; } message = line.Substring(nextIndex + 1); } inHeader = new HeaderDict(); while (true) { var line = sr.ReadLine(); if (!string.IsNullOrEmpty(line)) { var index = line.IndexOf(':'); var key = line.Substring(0, index).Trim(); var value = line.Substring(index + 1).Trim(); inHeader[key] = value; } else { break; } } var ms = responseBodyStream as MemoryStream; if (ms != null) { inData = ms.ToArray(); } if (status / 100 == 3) { if (followRedirect && GetInfo(CURLINFO.REDIRECT_URL, out string location) == CURLE.OK) { uri = new Uri(location); } else { done = true; } } else { done = true; } } else { CurlLog.LogWarning($"Failed to request: {uri}, reason: {result}"); } CloseStreams(); } catch (Exception e) { CurlLog.LogError("Unexpected exception: " + e); } return(done); }
private void Prepare() { try { status = 0; message = null; thisHandle = GCHandle.Alloc(this); SetOpt(CURLOPT.URL, uri.AbsoluteUri); var upperMethod = method.ToUpper(); switch (upperMethod) { case "GET": SetOpt(CURLOPT.HTTPGET, true); break; case "HEAD": SetOpt(CURLOPT.NOBODY, true); break; case "POST": SetOpt(CURLOPT.POST, true); break; default: SetOpt(CURLOPT.CUSTOMREQUEST, method); break; } if (useHttp2) { SetOpt(CURLOPT.HTTP_VERSION, (long)HTTPVersion.VERSION_2TLS); } else { SetOpt(CURLOPT.HTTP_VERSION, (long)HTTPVersion.VERSION_1_1); } SetOpt(CURLOPT.PIPEWAIT, true); SetOpt(CURLOPT.SSL_VERIFYHOST, !insecure); SetOpt(CURLOPT.SSL_VERIFYPEER, !insecure); // Ca cert path SetOpt(CURLOPT.CAINFO, s_capath); // Fill request header var requestHeader = new CurlSlist(IntPtr.Zero); if (disableExpect) { requestHeader.Append("Expect:"); } requestHeader.Append($"Content-Type:{contentType}"); if (userHeader != null) { foreach (var entry in userHeader) { requestHeader.Append(entry.Key + ":" + entry.Value); } } SetOpt(CURLOPT.HTTPHEADER, (IntPtr)requestHeader); // Fill request body if (outData != null && outData.Length > 0) { SetOpt(CURLOPT.POSTFIELDS, outData); SetOpt(CURLOPT.POSTFIELDSIZE, outData.Length); } // Handle response header responseHeaderStream = new MemoryStream(); SetOpt(CURLOPT.HEADERFUNCTION, (Delegates.HeaderFunction)HeaderFunction); SetOpt(CURLOPT.HEADERDATA, (IntPtr)thisHandle); bool rangeRequest = rangeStart > 0 || rangeEnd > 0; if (rangeRequest) { if (rangeEnd == 0) { SetOpt(CURLOPT.RANGE, $"{rangeStart}-"); } else { SetOpt(CURLOPT.RANGE, $"{rangeStart}-{rangeEnd}"); } } else { SetOpt(CURLOPT.RANGE, IntPtr.Zero); } // Handle response body recievedDataLength = 0; if (string.IsNullOrEmpty(outputPath)) { responseBodyStream = new MemoryStream(); } else { var dir = Path.GetDirectoryName(outputPath); if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir)) { Directory.CreateDirectory(dir); } responseBodyStream = new FileStream(outputPath, rangeRequest ? FileMode.Append : FileMode.OpenOrCreate); } SetOpt(CURLOPT.WRITEFUNCTION, (Delegates.WriteFunction)WriteFunction); SetOpt(CURLOPT.WRITEDATA, (IntPtr)thisHandle); // Debug if (debug) { outHeader = null; SetOpt(CURLOPT.VERBOSE, true); SetOpt(CURLOPT.DEBUGFUNCTION, DebugFunction); SetOpt(CURLOPT.DEBUGDATA, (IntPtr)thisHandle); } else { SetOpt(CURLOPT.VERBOSE, false); SetOpt(CURLOPT.DEBUGFUNCTION, IntPtr.Zero); SetOpt(CURLOPT.DEBUGDATA, IntPtr.Zero); } if (progressCallback != null) { SetOpt(CURLOPT.NOPROGRESS, false); SetOpt(CURLOPT.XFERINFOFUNCTION, ProgressFunction); SetOpt(CURLOPT.XFERINFODATA, (IntPtr)thisHandle); } else { SetOpt(CURLOPT.NOPROGRESS, true); SetOpt(CURLOPT.XFERINFOFUNCTION, IntPtr.Zero); SetOpt(CURLOPT.XFERINFODATA, IntPtr.Zero); } // Timeout SetOpt(CURLOPT.CONNECTTIMEOUT_MS, connectionTimeout); SetOpt(CURLOPT.TIMEOUT_MS, timeout); SetOpt(CURLOPT.LOW_SPEED_LIMIT, lowSpeedLimit); SetOpt(CURLOPT.LOW_SPEED_TIME, lowSpeedTimeout); // Speed limitation SetOpt(CURLOPT.MAX_SEND_SPEED_LARGE, outSpeedLimit); SetOpt(CURLOPT.MAX_RECV_SPEED_LARGE, inSpeedLimit); } catch (Exception e) { CurlLog.LogError("Unexpected exception: " + e); } }
private void Prepare() { try { status = 0; message = null; thisHandle = GCHandle.Alloc(this); SetOpt(CURLOPT.URL, uri.AbsoluteUri); SetOpt(CURLOPT.CUSTOMREQUEST, method); SetOpt(CURLOPT.HTTP_VERSION, (long)HTTPVersion.VERSION_2TLS); SetOpt(CURLOPT.PIPEWAIT, true); if (insecure) { SetOpt(CURLOPT.SSL_VERIFYHOST, false); SetOpt(CURLOPT.SSL_VERIFYPEER, false); } // Ca cert path SetOpt(CURLOPT.CAINFO, s_capath); // Fill request header var requestHeader = new CurlSlist(IntPtr.Zero); requestHeader.Append($"Content-Type:{contentType}"); if (userHeader != null) { foreach (var entry in userHeader) { requestHeader.Append(entry.Key + ":" + entry.Value); } } SetOpt(CURLOPT.HTTPHEADER, (IntPtr)requestHeader); // Fill request body if (outData != null && outData.Length > 0) { SetOpt(CURLOPT.POSTFIELDS, outData); SetOpt(CURLOPT.POSTFIELDSIZE, outData.Length); } // Handle response header responseHeaderStream = new MemoryStream(); SetOpt(CURLOPT.HEADERFUNCTION, (Delegates.HeaderFunction)HeaderFunction); SetOpt(CURLOPT.HEADERDATA, (IntPtr)thisHandle); // Handle response body recievedDataLength = 0; if (string.IsNullOrEmpty(outputPath)) { responseBodyStream = new MemoryStream(); } else { var dir = Path.GetDirectoryName(outputPath); if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir)) { Directory.CreateDirectory(dir); } responseBodyStream = new FileStream(outputPath, FileMode.OpenOrCreate); } SetOpt(CURLOPT.WRITEFUNCTION, (Delegates.WriteFunction)WriteFunction); SetOpt(CURLOPT.WRITEDATA, (IntPtr)thisHandle); // Debug if (debug) { outHeader = null; SetOpt(CURLOPT.VERBOSE, true); SetOpt(CURLOPT.DEBUGFUNCTION, DebugFunction); SetOpt(CURLOPT.DEBUGDATA, (IntPtr)thisHandle); } // Timeout SetOpt(CURLOPT.CONNECTTIMEOUT_MS, connectionTimeout); SetOpt(CURLOPT.TIMEOUT_MS, timeout); SetOpt(CURLOPT.LOW_SPEED_LIMIT, lowSpeedLimit); SetOpt(CURLOPT.LOW_SPEED_TIME, lowSpeedTimeout); // Speed limitation SetOpt(CURLOPT.MAX_SEND_SPEED_LARGE, outSpeedLimit); SetOpt(CURLOPT.MAX_RECV_SPEED_LARGE, inSpeedLimit); } catch (Exception e) { CurlLog.LogError("Unexpected exception: " + e); } }