using System; using System.Collections.Generic; using System.Collections.Specialized; using System.IO; using System.Linq; using System.Net; using System.Reflection; using System.Text; using Getf.Service.Transfer.Client.WinService.Entities; using Getf.Service.Transfer.Client.WinService.Helpers; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace Getf.Service.Transfer.Client.WinService.HttpHandler.HttpByte { public class HttpByteHandler : IDataHandler { LogHelper _LogHelper; public TransInfo HandlerData(TransInfo srcData) { var r = new TransInfo(); var action = srcData.Body.Action; if (String.IsNullOrWhiteSpace(action)) { r.TransResultInfo = GetResult(-320, "Action(url|method)参数不能为空"); return r; } var url = action; var jsonStr = String.IsNullOrWhiteSpace(srcData.Body.Param) ? "{}" : srcData.Body.Param; var jObject = JsonConvert.DeserializeObject(jsonStr); var rData = DoRequest(url, jObject, srcData.Data, out string msg, out int htttpStatusCode); if (rData == null) { r.TransResultInfo = new TransResult() { Code = htttpStatusCode, Message = msg }; return r; } r.TransResultInfo = new TransResult() { Code = htttpStatusCode, Message = msg }; r.Data = rData; return r; } private TransResult GetResult(int code, string message) { return new TransResult() { Code = code, Message = message }; } public byte[] DoRequest(string url, JObject jObject, byte[] data, out string msg, out int httpStatusCode) { try { Encoding encoding = new UTF8Encoding(false); if (jObject["Encoding"] != null) { encoding = Encoding.GetEncoding(jObject["Encoding"].Value()); } var method = "POST"; if (jObject["Method"] != null) { method = jObject["Method"].Value(); } HttpWebRequest httpWebRequest = WebRequest.Create(url) as HttpWebRequest; var bodyIndex = GetBodyIndex(data); var headStr = encoding.GetString(data.Take(bodyIndex).ToArray()); var bodyData = data.Skip(bodyIndex)/*.Select(m => (char)m)*/.ToArray(); SetHead(httpWebRequest, method, headStr); byte[] r; if (!"GET".Equals(method, StringComparison.OrdinalIgnoreCase)) { var requestStream = httpWebRequest.GetRequestStream(); requestStream.Write(bodyData, 0, bodyData.Length); r = GetResponse(httpWebRequest, encoding); requestStream.Close(); requestStream.Dispose(); } else { r = GetResponse(httpWebRequest, encoding); } msg = String.Empty; httpStatusCode = 200; return r; } catch (WebException e) { using (var stream = e?.Response?.GetResponseStream()) { httpStatusCode = (int?)((System.Net.HttpWebResponse)(e?.Response))?.StatusCode ?? 500; if (stream != null) { using (StreamReader streamReader = new StreamReader(stream)) { msg = streamReader.ReadToEnd(); } } else { msg = e.Message; } } } catch (Exception e) { httpStatusCode = 500; msg = e.Message; } return null; } private int GetBodyIndex(byte[] data) { var index = -1; for (int i = 0, c = data.Length; i < c; i++) { var elem = data[i]; if (elem == '\r' && i + 3 < data.Length && data[i + 1] == '\n' && data[i + 2] == '\r' && data[i + 3] == '\n') { index = i + 4; break; } } return index; } private static PropertyInfo InnerCollectionProperty = typeof(WebHeaderCollection).GetProperty("InnerCollection", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); public static void SetHeaderValue(WebHeaderCollection header, string name, string value) { var collection = InnerCollectionProperty.GetValue(header, null) as NameValueCollection; collection[name] = value; } private void SetHead(HttpWebRequest httpWebRequest, string method, string headStr) { httpWebRequest.Method = method; var headStrSplitResult = headStr.Split(new String[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); foreach (var elem in headStrSplitResult) { var keyValue = elem.Split(':'); var name = keyValue[0]; var value = keyValue[1]; if ("Accept-Encoding".Equals(name, StringComparison.OrdinalIgnoreCase)) { httpWebRequest.AutomaticDecompression = DecompressionMethods.GZip; } SetHeaderValue(httpWebRequest.Headers, name, value); } /*if ("post".Equals(method, StringComparison.OrdinalIgnoreCase)) { if (String.IsNullOrWhiteSpace(httpWebRequest.ContentType)) { httpWebRequest.ContentType = "application/x-www-form-urlencoded"; } }*/ } private byte[] GetResponse(HttpWebRequest httpWebRequest, Encoding encoding) { var response = httpWebRequest.GetResponse(); response.Headers.ToByteArray(); using (var stream = response.GetResponseStream()) { using (MemoryStream ms = new MemoryStream()) { stream.CopyTo(ms); var r = new List(); r.AddRange(response.Headers.ToByteArray()); //r.AddRange(encoding.GetBytes("\r\n")); r.AddRange(ms.ToArray()); return r.ToArray(); } } } } }