当前位置 博文首页 > 文章内容

    HttpClient类

    作者: 栏目:未分类 时间:2020-09-09 10:04:04

    本站于2023年9月4日。收到“大连君*****咨询有限公司”通知
    说我们IIS7站长博客,有一篇博文用了他们的图片。
    要求我们给他们一张图片6000元。要不然法院告我们

    为避免不必要的麻烦,IIS7站长博客,全站内容图片下架、并积极应诉
    博文内容全部不再显示,请需要相关资讯的站长朋友到必应搜索。谢谢!

    另祝:版权碰瓷诈骗团伙,早日弃暗投明。

    相关新闻:借版权之名、行诈骗之实,周某因犯诈骗罪被判处有期徒刑十一年六个月

    叹!百花齐放的时代,渐行渐远!



     /// <summary>
        /// http 同步请求类
        /// 如果类库中没有提供设置HttpWebRequest参数的方法,可以实现OnCreatedRequest回调,自己再去设置
        /// 有任何错误可以判断Exception类型,获取相应错误信息
        /// </summary>
        public class HttpClient
        {
            private Encoding respEncoding = Encoding.UTF8;
    
    #if DEBUG
            private int timeout = Int32.MaxValue;
    #else
            private int timeout = 30000;
    #endif
            
            /// <summary>
            /// 字符编码
            /// </summary>
            public Encoding DefaultEncoding { get; set; } = Encoding.UTF8;
    
            /// <summary>
            /// 当HttpWebRequest创建完成回调
            /// </summary>
            public Action<HttpWebRequest> OnCreatedRequest { get; set; }
            
            /// <summary>
            /// 设置超时时间,默认30秒,单位毫秒
            /// </summary>
            /// <param name="timeout"></param>
            public void SetTimeout(int timeout)
            {
                this.timeout = timeout;
            }
            
            /// <summary>
            /// 请求报文头
            /// </summary>
            public Dictionary<string, string> Headers { get; set; } = new Dictionary<string, string>();
    
            /// <summary>
            /// 异常信息
            /// </summary>
            public Exception Exception { get; set; }
    
            /// <summary>
            /// HttpStatusCode
            /// </summary>
            public HttpStatusCode HttpStatusCode { get; set; }
    
    
    
            /// <summary>
            /// 同步Get
            /// </summary>
            /// <param name="url">路径</param>
            /// <returns>返回</returns>
            public string Get(string url)
            {
                var httpWebRequest = CreateHttpWebRequest(url);
                httpWebRequest.Method = "GET";
    
                //返回数据s
                var bytes = GetRespBytes(httpWebRequest);
                return bytes != null ? respEncoding.GetString(bytes) : null;
            }
            
            /// <summary>
            /// 同步post
            /// </summary>
            /// <param name="url">地址</param>
            /// <param name="postStr">数据</param>
            /// <param name="isjson">是否是json数据,默认false</param>
            /// <returns>返回</returns>
            public string Post(string url, string postStr = null, bool isjson = false)
            {
                return Post(url, string.IsNullOrEmpty(postStr) ? null : DefaultEncoding.GetBytes(postStr), isjson);
            }
            
            /// <summary>
            /// 同步post
            /// </summary>
            /// <param name="url">地址</param>
            /// <param name="contentBytes">内容的byte字节</param>
            /// <param name="isjson">是否是json数据,默认false</param>
            /// <returns>返回</returns>
            public string Post(string url, byte[] contentBytes = null, bool isjson = false)
            {
                HttpWebRequest httpWebRequest = CreateHttpWebRequest(url, isjson);
                httpWebRequest.Method = "POST";
    
                //写数据
                if (contentBytes != null && contentBytes.Length > 0)
                {
                    httpWebRequest.ContentLength = contentBytes.Length;
                    try
                    {
                        using (var myStream = httpWebRequest.GetRequestStream())
                        {
                            myStream.Write(contentBytes, 0, contentBytes.Length);
                        }
                    }
                    catch (Exception ex)
                    {
                        Exception = ex;
                        return null;
                    }
                }
                //返回数据
                var bytes = GetRespBytes(httpWebRequest);
                return bytes != null ? respEncoding.GetString(bytes) : null;
            }
    
            /// <summary>
            /// 获取返回数据
            /// </summary>
            /// <param name="httpWebRequest"></param>
            /// <returns>返回</returns>
            private byte[] GetRespBytes(HttpWebRequest httpWebRequest)
            {
                //接收数据
                using (HttpWebResponse httpResp = GetHttpWebResponse(httpWebRequest))
                {
                    Stream respStream = httpResp?.GetResponseStream();
                    if (respStream == null) return null;
                    using (Stream stream = httpResp.ContentEncoding.ToLower().Contains("gzip")
                        ? new GZipStream(respStream, CompressionMode.Decompress)
                        : respStream)
                    {
                        List<byte> lst = new List<byte>();
                        int nRead;
                        while ((nRead = stream.ReadByte()) != -1) lst.Add((byte)nRead);
    
                        var bytes = lst.ToArray();
                        //获取编码
                        respEncoding = GetHtmlEncoding(httpResp, bytes);
                        return bytes;
                    }
                }
            }
    
    
            /// <summary>
            /// 创建HttpWebRequest
            /// </summary>
            /// <param name="url">url地址</param>
            /// <param name="isjson">是否是json数据,默认false</param>
            /// <returns>返回</returns>
            private HttpWebRequest CreateHttpWebRequest(string url, bool isjson = false)
            {
                var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
                HttpStatusCode = HttpStatusCode.Created;
                httpWebRequest.Accept = "text/html, application/xhtml+xml, */*";
                httpWebRequest.ContentType = "application/x-www-form-urlencoded;charset=" + DefaultEncoding.WebName;
                if (isjson)
                    httpWebRequest.ContentType = "application/json;charset=" + DefaultEncoding.WebName;
                httpWebRequest.UserAgent = "Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/7.0;)";
                //httpWebRequest.UserAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 10_2 like Mac OS X) AppleWebKit/602.3.12 (KHTML, like Gecko) Mobile/14C92 Safari/601.1 wechatdevtools/0.18.182200 MicroMessenger/6.5.7 Language/zh_CN webview/0)";
                httpWebRequest.ProtocolVersion = HttpVersion.Version11;
                httpWebRequest.Headers.Add("Accept-Language", "zh-cn");
                httpWebRequest.Headers.Add("Accept-Encoding", "gzip, deflate");
                httpWebRequest.Headers.Add("Pragma", "no-cache");
                httpWebRequest.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
                httpWebRequest.KeepAlive = true;
                //httpWebRequest.AllowAutoRedirect = true;
                httpWebRequest.ServicePoint.Expect100Continue = false;
                httpWebRequest.Timeout = timeout;
    
                //添加header
                if (Headers.Count > 0)
                {
                    foreach (var header in Headers)
                        httpWebRequest.Headers.Add(header.Key, header.Value);
                }
    
                if (url.Contains("https://"))
                    SetCertificatePolicy();
    
                OnCreatedRequest?.Invoke(httpWebRequest);
                return httpWebRequest;
            }
    
            /// <summary>
            /// 获取HttpWebResponse
            /// </summary>
            /// <param name="httpWebRequest"></param>
            /// <returns>返回</returns>
            private HttpWebResponse GetHttpWebResponse(HttpWebRequest httpWebRequest)
            {
                HttpWebResponse httpResp = null;
                try
                {
                    httpResp = (HttpWebResponse)httpWebRequest.GetResponse();
                    HttpStatusCode = httpResp.StatusCode;
                }
                catch (WebException ex)
                {
                    Exception = ex;
                    if (ex.Response != null)
                    {
                        httpResp = (HttpWebResponse) ex.Response;
                        HttpStatusCode = httpResp.StatusCode;
                    }
                }
                catch (Exception ex)
                {
                    Exception = ex;
                }
    
                return httpResp;
            }
    
            /// <summary>
            /// 从html内容获取编码
            /// </summary>
            /// <param name="response"></param>
            /// <param name="bytes"></param>
            /// <returns>返回</returns>
            private Encoding GetHtmlEncoding(HttpWebResponse response, byte[] bytes)
            {
                Encoding encoding = DefaultEncoding;
                //检测响应头是否返回了编码类型,若返回了编码类型则使用返回的编码
                //注:有时响应头没有编码类型,CharacterSet经常设置为ISO-8859-1
                if (!string.IsNullOrEmpty(response.CharacterSet) && response.CharacterSet.ToUpper() != "ISO-8859-1")
                {
                    encoding = Encoding.GetEncoding(response.CharacterSet == "utf8" ? "utf-8" : response.CharacterSet);
                }
                else
                {
                    //若没有在响应头找到编码,则去html找meta头的charset
                    var result = Encoding.Default.GetString(bytes);
                    //在返回的html里使用正则匹配页面编码
                    Match match = Regex.Match(result, @"<meta.*charset=""?([\w-]+)""?.*>", RegexOptions.IgnoreCase);
                    if (match.Success)
                    {
                        encoding = Encoding.GetEncoding(match.Groups[1].Value);
                    }
                }
                return encoding;
            }
            
            /// <summary>
            /// 注册证书
            /// </summary>
            private void SetCertificatePolicy()
            {
                ServicePointManager.ServerCertificateValidationCallback
                           += RemoteCertificateValidate;
            }
    
            /// <summary>  
            /// 远程证书验证,固定返回true 
            /// </summary>  
            private bool RemoteCertificateValidate(object sender, X509Certificate cert,
                X509Chain chain, SslPolicyErrors error)
            {
                return true;
            }
        }