using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Configuration; using System.IO; using System.Net; using System.Net.Security; using System.Text; using XImaging.Automation.Library.HxDriverLib; namespace XImaging.Automation.Service { public class PostServerConfig : ConfigurationElement { [ConfigurationProperty("name", IsRequired = true)] public string Name { get { return (string)this["name"]; } } [ConfigurationProperty("method", IsRequired = true)] public string Method { get { return (string)this["method"]; } } [ConfigurationProperty("uri", IsRequired = true)] public string URI { get { return (string)this["uri"]; } } } public class PostServerSection : ConfigurationSection { [ConfigurationProperty("server", IsRequired = true)] public PostServerConfig Server { get { return this["server"] as PostServerConfig; } } } public class MessageConfig : ConfigurationElement { [ConfigurationProperty("enabled", IsRequired = true)] public bool Enabled { get { return (bool)this["enabled"]; } } [ConfigurationProperty("timeout", IsRequired = true)] public int Timeout { get { return (int)this["timeout"]; } } } public class MessageSection : ConfigurationSection { [ConfigurationProperty("heartbeat", IsRequired = true)] public MessageConfig Heartbeat { get { return this["heartbeat"] as MessageConfig; } } } public class HttpRequestClient { /// /// 获取或设置数据字符编码, 默认使用 /// public Encoding Encoding { get; set; } = Encoding.UTF8; /// /// 获取或设置 UserAgent /// public string UserAgent { get; set; } = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36"; /// /// 获取或设置 Accept /// public string Accept { get; set; } = "*/*"; /// /// 获取或设置 Referer /// public string Referer { get; set; } /// /// 获取或设置 Cookie 容器 /// public CookieContainer CookieContainer { get; set; } = new CookieContainer(); public virtual string Post(string url) { return null; } /// /// 初始化一个用于以 POST 方式向目标地址提交不包含文件表单数据实例 /// public HttpRequestClient() { } } internal sealed class BiosenHttpRequestClient : HttpRequestClient { public static string Uri { set; get; } private JObject _postDatas; private static string SO_DELIMITER = "#!HxSEP!#"; private string m_strName; private string m_strPayload; public static void Init() { PostServerSection section = ConfigurationManager.GetSection("dataServer") as PostServerSection; BiosenHttpRequestClient.Uri = section.Server.URI; } public BiosenHttpRequestClient() : base() { this._postDatas = JObject.FromObject(new { }); } /// /// 以POST方式向目标地址提交表单数据 /// /// 目标地址, http(s)://sample.com /// 目标地址的响应 public override string Post(string url) { if (string.IsNullOrWhiteSpace(url)) throw new ArgumentNullException(nameof(url)); HttpWebRequest request = null; if (url.ToLowerInvariant().StartsWith("https")) { request = WebRequest.Create(url) as HttpWebRequest; ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback((s, c, ch, ss) => { return true; }); request.ProtocolVersion = HttpVersion.Version11; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls; request.KeepAlive = true; ServicePointManager.CheckCertificateRevocationList = true; ServicePointManager.DefaultConnectionLimit = 100; ServicePointManager.Expect100Continue = false; } else { request = WebRequest.Create(url) as HttpWebRequest; } request.Timeout = 3000; request.Method = "POST"; request.ContentType = "application/json"; request.UserAgent = this.UserAgent; request.Accept = this.Accept; request.Referer = this.Referer; request.CookieContainer = this.CookieContainer; string postData = this._postDatas.ToString(); try { using (var streamWriter = new StreamWriter(request.GetRequestStream())) { streamWriter.Write(postData); } } catch(Exception ex) { LogConstant.logger.Print(string.Format("[Post][Exception]{0}", ex.ToString())); } LogConstant.logger.Print(string.Format("[Post][Data]准备向[{0}]发送消息: {1}", url, postData)); string resContent = ""; try { HttpWebResponse response = request.GetResponse() as HttpWebResponse; using (Stream resStream = response.GetResponseStream()) { using (StreamReader streamReader = new StreamReader(resStream, Encoding.UTF8)) { resContent = streamReader.ReadToEnd().ToString(); } } LogConstant.logger.Print(string.Format("[Post][Data]消息发送成功,从[{0}]收到返回消息: {1}", url, resContent)); return resContent; } catch (Exception ex) { LogConstant.logger.Print("[Post][Data]消息发送失败,未收到返回消息:" + ex.Message); throw ex; } } public static void Send(string data) { BiosenHttpRequestClient client = new BiosenHttpRequestClient(); client.Payload = data; string t_response = client.Post(BiosenHttpRequestClient.Uri + "?name=" + client.m_strName); return; } public string Payload { set { this.m_strPayload = value; this.m_strName = XImaging.Automation.Library.HxDriverLib.Encrypt.md5(this.m_strPayload + SO_DELIMITER); this._postDatas = JObject.Parse(this.m_strPayload); } get { return m_strPayload; } } } internal sealed class BiosenErrorRequestClient : HttpRequestClient { public static string Uri { set; get; } private JObject _postDatas; private static string SO_DELIMITER = "#!HxSEP!#"; private string m_strName; private string m_strPayload; public static void Init() { PostServerSection section = ConfigurationManager.GetSection("errorServer") as PostServerSection; BiosenErrorRequestClient.Uri = section.Server.URI; } public BiosenErrorRequestClient() : base() { this._postDatas = JObject.FromObject(new { }); } /// /// 以POST方式向目标地址提交表单数据 /// /// 目标地址, http(s)://sample.com /// 目标地址的响应 public override string Post(string url) { if (string.IsNullOrWhiteSpace(url)) throw new ArgumentNullException(nameof(url)); HttpWebRequest request = null; if (url.ToLowerInvariant().StartsWith("https")) { request = WebRequest.Create(url) as HttpWebRequest; ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback((s, c, ch, ss) => { return true; }); request.ProtocolVersion = HttpVersion.Version11; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls; request.KeepAlive = true; ServicePointManager.CheckCertificateRevocationList = true; ServicePointManager.DefaultConnectionLimit = 100; ServicePointManager.Expect100Continue = false; } else { request = WebRequest.Create(url) as HttpWebRequest; } request.Timeout = 3000; request.Method = "POST"; request.ContentType = "application/json"; request.UserAgent = this.UserAgent; request.Accept = this.Accept; request.Referer = this.Referer; request.CookieContainer = this.CookieContainer; string postData = this._postDatas.ToString(); try { using (var streamWriter = new StreamWriter(request.GetRequestStream())) { streamWriter.Write(postData); } } catch (Exception ex) { LogConstant.logger.Print("[Post][Exception]" + ex.ToString()); } LogConstant.logger.Print(string.Format("[Post][Error]准备向[{0}]发送错误消息: {1}", url, postData)); string resContent = ""; try { HttpWebResponse response = request.GetResponse() as HttpWebResponse; using (Stream resStream = response.GetResponseStream()) { using (StreamReader streamReader = new StreamReader(resStream, Encoding.UTF8)) { resContent = streamReader.ReadToEnd().ToString(); } } LogConstant.logger.Print(string.Format("[Post][Error]错误消息发送成功,从[{0}]收到返回消息: {1}", url, resContent)); return resContent; } catch(Exception ex) { LogConstant.logger.Print("[Post][Error]错误消息发送失败,未收到返回消息:" + ex.Message); throw ex; } } public static void Send(string data) { BiosenErrorRequestClient client = new BiosenErrorRequestClient(); client.Payload = data; string t_response = client.Post(BiosenErrorRequestClient.Uri + "?name=" + client.m_strName); return; } public string Payload { set { this.m_strPayload = value; this.m_strName = XImaging.Automation.Library.HxDriverLib.Encrypt.md5(this.m_strPayload + SO_DELIMITER); this._postDatas = JObject.Parse(this.m_strPayload); } get { return m_strPayload; } } } public class UploadParameterType { public UploadParameterType() { Encoding = Encoding.UTF8; PostParameters = new Dictionary(); } /// /// 上传地址 /// public string Url { get; set; } /// /// 文件名称key /// public string FileName { get; set; } /// /// 编码格式 /// public Encoding Encoding { get; set; } /// /// 上传文件的流 /// public Stream UploadStream { get; set; } /// /// 上传文件 携带的参数集合 /// public IDictionary PostParameters { get; set; } } public class BiosenFileRequestClient : HttpRequestClient { public static string Uri { set; get; } private UploadParameterType parameters; public static void Init() { PostServerSection section = ConfigurationManager.GetSection("fileServer") as PostServerSection; BiosenFileRequestClient.Uri = section.Server.URI; } public override string Post(string url) { if (string.IsNullOrWhiteSpace(url)) throw new ArgumentNullException(nameof(url)); string boundary = DateTime.Now.Ticks.ToString("x"); // 边界符 byte[] beginBoundaryBytes = Encoding.UTF8.GetBytes("--" + boundary + "\r\n"); byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n"); byte[] newLineBytes = Encoding.UTF8.GetBytes("\r\n"); MemoryStream memoryStream = new MemoryStream(); if (this.parameters.PostParameters != null && parameters.PostParameters.Count > 0) { foreach (KeyValuePair keyValuePair in parameters.PostParameters) { string parameterHeaderTemplate = string.Format("Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}\r\n", keyValuePair.Key, keyValuePair.Value); byte[] parameterHeaderBytes = parameters.Encoding.GetBytes(parameterHeaderTemplate); memoryStream.Write(beginBoundaryBytes, 0, beginBoundaryBytes.Length); memoryStream.Write(parameterHeaderBytes, 0, parameterHeaderBytes.Length); } } const string filePartHeaderTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" + "Content-Type: application/octet-stream\r\n\r\n"; int i = 0; if (this.parameters.FileName != null) { FileInfo fileInfo = new FileInfo(this.parameters.FileName); string fileName = fileInfo.Name; string fileHeaderItem = string.Format(filePartHeaderTemplate, "files", fileName); byte[] fileHeaderItemBytes = Encoding.UTF8.GetBytes(fileHeaderItem); if (i > 0) { memoryStream.Write(newLineBytes, 0, newLineBytes.Length); } memoryStream.Write(beginBoundaryBytes, 0, beginBoundaryBytes.Length); memoryStream.Write(fileHeaderItemBytes, 0, fileHeaderItemBytes.Length); int bytesRead; byte[] buffer = new byte[1024]; FileStream fileStream = new FileStream(this.parameters.FileName, FileMode.Open, FileAccess.Read); while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) { memoryStream.Write(buffer, 0, bytesRead); // 2.3 将文件流写入FormData项中 } i++; } memoryStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length); HttpWebRequest request = null; if (url.ToLowerInvariant().StartsWith("https")) { request = WebRequest.Create(url) as HttpWebRequest; ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback((s, c, ch, ss) => { return true; }); request.ProtocolVersion = HttpVersion.Version11; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls; request.KeepAlive = true; ServicePointManager.CheckCertificateRevocationList = true; ServicePointManager.DefaultConnectionLimit = 100; ServicePointManager.Expect100Continue = false; } else { request = WebRequest.Create(url) as HttpWebRequest; } request.Timeout = 10000; request.Method = "POST"; request.ContentType = string.Format("multipart/form-data; boundary={0}", boundary); request.UserAgent = this.UserAgent; request.Accept = this.Accept; request.Referer = this.Referer; request.ContentLength = memoryStream.Length; request.CookieContainer = this.CookieContainer; memoryStream.Position = 0; byte[] tempBuffer = new byte[memoryStream.Length]; memoryStream.Read(tempBuffer, 0, tempBuffer.Length); memoryStream.Close(); using (var streamWriter = request.GetRequestStream()) { streamWriter.Write(tempBuffer, 0, tempBuffer.Length); } string resContent = ""; HttpWebResponse response = request.GetResponse() as HttpWebResponse; using (Stream resStream = response.GetResponseStream()) { using (StreamReader streamReader = new StreamReader(resStream, Encoding.UTF8)) { resContent = streamReader.ReadToEnd().ToString(); } } return resContent; } public static string Send(UploadParameterType parameters) { BiosenFileRequestClient client = new BiosenFileRequestClient(); client.parameters = parameters; LogConstant.logger.Print(string.Format("[Post][File]准备上传文件[{0}]到数据服务器", parameters.FileName)); string t_response = client.Post(BiosenFileRequestClient.Uri); JObject res = JObject.Parse(t_response); if (res["status"].ToString().Equals("0")) { string url = res["data"].ToString(); LogConstant.logger.Print(string.Format("[Post][File]文件上传到数据服务器的保存地址:[{0}]", t_response)); return url; } else { LogConstant.logger.Print(string.Format("[Post][File]文件上传数据服务器失败:{0}", res["message"].ToString())); throw new Exception(res["message"].ToString()); } } } internal sealed class BiosenBatchFilesRequestClient : HttpRequestClient { public static string Uri { set; get; } private UploadParameterType parameters; public static void Init() { PostServerSection section = ConfigurationManager.GetSection("fileServer") as PostServerSection; BiosenBatchFilesRequestClient.Uri = section.Server.URI; } public override string Post(string url) { if (string.IsNullOrWhiteSpace(url)) throw new ArgumentNullException(nameof(url)); string boundary = DateTime.Now.Ticks.ToString("x"); // 边界符 byte[] beginBoundaryBytes = Encoding.UTF8.GetBytes("--" + boundary + "\r\n"); byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n"); byte[] newLineBytes = Encoding.UTF8.GetBytes("\r\n"); MemoryStream memoryStream = new MemoryStream(); if (this.parameters.PostParameters != null && parameters.PostParameters.Count > 0) { foreach (KeyValuePair keyValuePair in parameters.PostParameters) { string parameterHeaderTemplate = string.Format("Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}\r\n", keyValuePair.Key, keyValuePair.Value); byte[] parameterHeaderBytes = parameters.Encoding.GetBytes(parameterHeaderTemplate); memoryStream.Write(beginBoundaryBytes, 0, beginBoundaryBytes.Length); memoryStream.Write(parameterHeaderBytes, 0, parameterHeaderBytes.Length); } } const string filePartHeaderTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" + "Content-Type: application/octet-stream\r\n\r\n"; int i = 0; if (this.parameters.FileName != null) { FileInfo fileInfo = new FileInfo(this.parameters.FileName); string fileName = fileInfo.Name; string fileHeaderItem = string.Format(filePartHeaderTemplate, "files", fileName); byte[] fileHeaderItemBytes = Encoding.UTF8.GetBytes(fileHeaderItem); if (i > 0) { memoryStream.Write(newLineBytes, 0, newLineBytes.Length); } memoryStream.Write(beginBoundaryBytes, 0, beginBoundaryBytes.Length); memoryStream.Write(fileHeaderItemBytes, 0, fileHeaderItemBytes.Length); int bytesRead; byte[] buffer = new byte[1024]; FileStream fileStream = new FileStream(this.parameters.FileName, FileMode.Open, FileAccess.Read); while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) { memoryStream.Write(buffer, 0, bytesRead); // 2.3 将文件流写入FormData项中 } i++; } memoryStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length); HttpWebRequest request = null; if (url.ToLowerInvariant().StartsWith("https")) { request = WebRequest.Create(url) as HttpWebRequest; ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback((s, c, ch, ss) => { return true; }); request.ProtocolVersion = HttpVersion.Version11; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls; request.KeepAlive = true; ServicePointManager.CheckCertificateRevocationList = true; ServicePointManager.DefaultConnectionLimit = 100; ServicePointManager.Expect100Continue = false; } else { request = WebRequest.Create(url) as HttpWebRequest; } request.Method = "POST"; request.ContentType = string.Format("multipart/form-data; boundary={0}", boundary); request.UserAgent = this.UserAgent; request.Accept = this.Accept; request.Referer = this.Referer; request.ContentLength = memoryStream.Length; request.CookieContainer = this.CookieContainer; memoryStream.Position = 0; byte[] tempBuffer = new byte[memoryStream.Length]; memoryStream.Read(tempBuffer, 0, tempBuffer.Length); memoryStream.Close(); using (var streamWriter = request.GetRequestStream()) { streamWriter.Write(tempBuffer, 0, tempBuffer.Length); } string resContent = ""; HttpWebResponse response = request.GetResponse() as HttpWebResponse; using (Stream resStream = response.GetResponseStream()) { using (StreamReader streamReader = new StreamReader(resStream, Encoding.UTF8)) { resContent = streamReader.ReadToEnd().ToString(); } } return resContent; } public static string Send(UploadParameterType parameters) { BiosenBatchFilesRequestClient client = new BiosenBatchFilesRequestClient(); client.parameters = parameters; LogConstant.logger.Print(string.Format("[Post][File]准备上传文件[{0}]到数据服务器", parameters.FileName)); string t_response = client.Post(BiosenFileRequestClient.Uri); JObject res = JObject.Parse(t_response); if (res["status"].ToString().Equals("0")) { string url = res["data"].ToString(); LogConstant.logger.Print(string.Format("[Post][File]文件上传到数据服务器的保存地址:[{0}]", t_response)); return url; } else { LogConstant.logger.Print(string.Format("[Post][File]文件上传数据服务器失败:{0}", res["message"].ToString())); throw new Exception(res["message"].ToString()); } } } }