This class wraps a linked list of strings used in cURL. Use it to build string lists where they're required, such as when calling CurlEasy.SetOpt with CurlOption.Quote as the option.
Inheritance: IDisposable
Example #1
0
        private static void Main(string[] args)
        {
            try
            {
                Curl.GlobalInit(CurlInitFlag.All);

                using (var curl = new CurlEasy())
                {
                    /* This is the URL for your mailserver */
                    curl.Url = "smtp://*****:*****@example.org>");

                    /* Add two recipients, in this particular case they correspond to
                     * the To: and Cc: addressees in the header, but they could be any
                     * kind of recipient. */
                    using (var recipients = new CurlSlist())
                    {
                        recipients.Append("<*****@*****.**>");
                        recipients.Append("<*****@*****.**>");
                        curl.SetOpt(CurlOption.MailRcpt, recipients);

                        /* We're using a callback function to specify the payload (the
                         * headers and body of the message). You could just use the
                         * ReadData option to  specify a FILE pointer to read from. */
                        curl.ReadFunction = PayloadSource;
                        curl.ReadData = new UploadContext();
                        curl.Upload = true;

                        var res = curl.Perform();
                        if (res != CurlCode.Ok)
                        {
                            Console.WriteLine("CurlEasy.Perform() failed: " + res);
                        }
                    }

                    /* curl won't send the QUIT command until you call cleanup, so you should be
                     * able to re-use this connection for additional messages (setting
                     * CURLOPT_MAIL_FROM and CURLOPT_MAIL_RCPT as required, and calling
                     * Perform() again. It may not be a good idea to keep the
                     * connection open for a very long time though (more than a few minutes may
                     * result in the server timing out the connection), and you do want to clean
                     * up in the end.
                     */
                }

                Curl.GlobalCleanup();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
            Console.ReadLine();
        }
        private CurlSlist SerializeHeaders(HttpRequest request)
        {
            if (!request.Headers.ContainsKey("Accept-Encoding"))
            {
                request.Headers.Add("Accept-Encoding", "gzip");
            }

            if (request.Headers.ContentType == null)
            {
                request.Headers.ContentType = string.Empty;
            }

            var curlHeaders = new CurlSlist();
            foreach (var header in request.Headers)
            {
                curlHeaders.Append(header.Key + ": " + header.Value.ToString());
            }

            return curlHeaders;
        }
Example #3
0
        public static CurlResponse PerformCurl(CurlRequest curlRequest)
        {
            lock (instance)
            {
                var headerBuffers = new List<byte[]>();
                var contentBuffers = new List<byte[]>();

                using (var easy = new CurlEasy())
                {
                    
                    easy.Url = curlRequest.Url;
                    easy.BufferSize = 64 * 1024;
                    easy.UserAgent = BrowserUtil.ChromeUserAgent;
                    easy.FollowLocation = false;
                    easy.ConnectTimeout = 20;
                    if(curlRequest.Headers != null)
                    {
                        CurlSlist curlHeaders = new CurlSlist();
                        foreach (var header in curlRequest.Headers)
                        {
                            curlHeaders.Append(header.Key + ": " + header.Value);
                        }
                        easy.SetOpt(CurlOption.HttpHeader, curlHeaders);
                    }

                    easy.WriteFunction = (byte[] buf, int size, int nmemb, object data) =>
                    {
                        contentBuffers.Add(buf);
                        return size * nmemb;
                    };

                    easy.HeaderFunction = (byte[] buf, int size, int nmemb, object extraData) =>
                    {
                        headerBuffers.Add(buf);
                        return size * nmemb;
                    };

                    if (!string.IsNullOrEmpty(curlRequest.Cookies))
                        easy.Cookie = curlRequest.Cookies;

                    if (!string.IsNullOrEmpty(curlRequest.Referer))
                        easy.Referer = curlRequest.Referer;

                    if (curlRequest.Method == HttpMethod.Post)
                    {
                        if (!string.IsNullOrEmpty(curlRequest.RawPOSTDdata))
                        {
                            easy.Post = true;
                            easy.PostFields = curlRequest.RawPOSTDdata;
                            easy.PostFieldSize = Encoding.UTF8.GetByteCount(curlRequest.RawPOSTDdata);
                        }
                        else
                        {
                            easy.Post = true;
                            var postString = StringUtil.PostDataFromDict(curlRequest.PostData);
                            easy.PostFields = postString;
                            easy.PostFieldSize = Encoding.UTF8.GetByteCount(postString);
                        }
                    }

                    if (Startup.DoSSLFix == true)
                    {
                        // http://stackoverflow.com/questions/31107851/how-to-fix-curl-35-cannot-communicate-securely-with-peer-no-common-encryptio
                        // https://git.fedorahosted.org/cgit/mod_nss.git/plain/docs/mod_nss.html
                        easy.SslCipherList = SSLFix.CipherList;
                        easy.FreshConnect = true;
                        easy.ForbidReuse = true;
                    }

                    if (Startup.IgnoreSslErrors == true)
                    {
                        easy.SetOpt(CurlOption.SslVerifyhost, false);
                        easy.SetOpt(CurlOption.SslVerifyPeer, false);
                    }

                    if (Startup.ProxyConnection != null)
                    {
                        easy.SetOpt(CurlOption.Proxy, Startup.ProxyConnection);
                    }                    

                    easy.Perform();

                    if (easy.LastErrorCode != CurlCode.Ok)
                    {
                        var message = "Error " + easy.LastErrorCode.ToString() + " " + easy.LastErrorDescription + " " + easy.ErrorBuffer;
                        if (null != OnErrorMessage)
                            OnErrorMessage(message);
                        else
                            Console.WriteLine(message);
                    }
                }

                var headerBytes = Combine(headerBuffers.ToArray());
                var headerString = Encoding.UTF8.GetString(headerBytes);
                if (Startup.ProxyConnection != null)
                {
                    var firstcrlf = headerString.IndexOf("\r\n\r\n");
                    var secondcrlf = headerString.IndexOf("\r\n\r\n", firstcrlf + 1);
                    if (secondcrlf > 0)
                    {
                        headerString = headerString.Substring(firstcrlf + 4, secondcrlf - (firstcrlf));
                    }
                }
                var headerParts = headerString.Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
                var headers = new List<string[]>();
                var headerCount = 0;
                HttpStatusCode status = HttpStatusCode.NotImplemented;
                var cookieBuilder = new StringBuilder();
                var cookies = new List<Tuple<string, string>>();
                foreach (var headerPart in headerParts)
                {
                    if (headerCount == 0)
                    {
                        var split = headerPart.Split(' ');
                        if (split.Length < 2)
                            throw new Exception("HTTP Header missing");
                        var responseCode = int.Parse(headerPart.Split(' ')[1]);
                        status = (HttpStatusCode)responseCode;
                    }
                    else
                    {
                        var keyVal = headerPart.Split(new char[] { ':' }, 2);
                        if (keyVal.Length > 1)
                        {
                            var key = keyVal[0].ToLower().Trim();
                            var value = keyVal[1].Trim();

                            if (key == "set-cookie")
                            {
                                var nameSplit = value.IndexOf('=');
                                if (nameSplit > -1) {
                                    cookies.Add(new Tuple<string, string>(value.Substring(0, nameSplit), value.Substring(0, value.IndexOf(';') + 1)));
                                }
                            }
                            else
                            {
                                headers.Add(new[] { key, value });
                            }
                        }
                    }

                    headerCount++;
                }

                foreach (var cookieGroup in cookies.GroupBy(c => c.Item1))
                {
                    cookieBuilder.AppendFormat("{0} ", cookieGroup.Last().Item2);
                }

                // add some debug output to track down the problem causing people getting InternalServerError results
                if (status == HttpStatusCode.NotImplemented || status == HttpStatusCode.InternalServerError)
                {
                    try
                    {
                        OnErrorMessage("got NotImplemented/InternalServerError");
                        OnErrorMessage("request.Method: " + curlRequest.Method);
                        OnErrorMessage("request.Url: " + curlRequest.Url);
                        OnErrorMessage("request.Cookies: " + curlRequest.Cookies);
                        OnErrorMessage("request.Referer: " + curlRequest.Referer);
                        OnErrorMessage("request.RawPOSTDdata: " + curlRequest.RawPOSTDdata);
                        OnErrorMessage("cookies: "+ cookieBuilder.ToString().Trim());
                        OnErrorMessage("headerString:\n" + headerString);
                    
                        foreach (var headerPart in headerParts)
                        {
                            OnErrorMessage("headerParts: "+headerPart);
                        }
                    }
                    catch (Exception ex)
                    {
                        OnErrorMessage(string.Format("CurlHelper: error while handling NotImplemented/InternalServerError:\n{0}", ex));
                    }
                }
                
                var contentBytes = Combine(contentBuffers.ToArray());
                var curlResponse = new CurlResponse(headers, contentBytes, status, cookieBuilder.ToString().Trim());
                return curlResponse;
            }
        }
Example #4
0
        private CurlSlist SerializeHeaders(HttpWebRequest webRequest)
        {
            if (webRequest.SendChunked)
            {
                throw new NotSupportedException("Chunked transfer is not supported");
            }

            if (webRequest.ContentLength > 0)
            {
                webRequest.Headers.Add("Content-Length", webRequest.ContentLength.ToString());
            }

            if (webRequest.AutomaticDecompression.HasFlag(DecompressionMethods.GZip))
            {
                if (webRequest.AutomaticDecompression.HasFlag(DecompressionMethods.Deflate))
                {
                    webRequest.Headers.Add("Accept-Encoding", "gzip, deflate");
                }
                else
                {
                    webRequest.Headers.Add("Accept-Encoding", "gzip");
                }
            }
            else
            {
                if (webRequest.AutomaticDecompression.HasFlag(DecompressionMethods.Deflate))
                {
                    webRequest.Headers.Add("Accept-Encoding", "deflate");
                }
            }

            var curlHeaders = new CurlSlist();
            for (int i = 0; i < webRequest.Headers.Count; i++)
            {
                curlHeaders.Append(webRequest.Headers.GetKey(i) + ": " + webRequest.Headers.Get(i));
            }

            curlHeaders.Append("Content-Type: " + webRequest.ContentType ?? string.Empty);

            return curlHeaders;
        }