diff --git a/OSS.Http.ConsoleTest/App.config b/OSS.Http.ConsoleTest/App.config
deleted file mode 100644
index 8e15646..0000000
--- a/OSS.Http.ConsoleTest/App.config
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/OSS.Http.ConsoleTest/Program.cs b/OSS.Http.ConsoleTest/Program.cs
deleted file mode 100644
index bc0d3e5..0000000
--- a/OSS.Http.ConsoleTest/Program.cs
+++ /dev/null
@@ -1,118 +0,0 @@
-using System;
-using System.IO;
-using System.Threading;
-using OSS.Http.Models;
-
-namespace OSS.Http.ConsoleTest
-{
- class Program
- {
- static void Main(string[] args)
- {
- Console.WriteLine("请输入请求地址(quit 直接退出):");
- string url = string.Empty;
- while ((url=Console.ReadLine())!="quit")
- {
- if (!string.IsNullOrEmpty(url))
- {
- Console.WriteLine("输入 async 执行异步请求,输入 sync 执行同步请求:");
- string cmd = Console.ReadLine();
- if (cmd == "async")
- {
- AsyncHttp(url);
- }
- else if (cmd == "sync")
- {
- SyncHttp(url);
- }
- }
- Console.WriteLine("请输入请求地址:");
- }
- }
-
- private static void SyncHttp(string url)
- {
- if (!string.IsNullOrEmpty(url))
- {
- OsHttpRequest request = new OsHttpRequest();
- request.AddressUrl = url;
- request.HttpMothed = HttpMothed.POST;
- request.Parameters.Add(new Parameter("name", "test", ParameterType.Form));
- FileStream file_stream = null;
- try
- {
-
- file_stream = new FileStream("E:\\test.txt", FileMode.Open, FileAccess.Read);
-
- //byte[] bites = new byte[file_stream.Length];
-
- //using (file_stream)
- //{
- // file_stream.Read(bites, 0, bites.Length);
- //}
-
- FileParameter file = new FileParameter("test", file_stream, "test_file", contentType: "text/plain");
- request.FileParameterList.Add(file);
-
- var response = HttpUtil.ExecuteSync(request);
-
- Console.WriteLine(response.Content);
-
- Console.WriteLine("请求结束!!!");
- }
- catch (Exception)
- {
- }
- finally
- {
- if (file_stream != null)
- file_stream.Close();
- }
-
- }
- }
-
-
- private static void AsyncHttp(string url)
- {
- if (!string.IsNullOrEmpty(url))
- {
- OsHttpRequest request = new OsHttpRequest();
- request.AddressUrl = url;
- request.HttpMothed = HttpMothed.POST;
- request.Parameters.Add(new Parameter("name", "test", ParameterType.Form));
- FileStream file_stream = null;
- try
- {
- file_stream = new FileStream("E:\\test.txt", FileMode.Open, FileAccess.Read);
-
- FileParameter file = new FileParameter("test", file_stream, "test_file", contentType: "text/plain");
- request.FileParameterList.Add(file);
- Console.WriteLine(string.Format("当前主线程ID:{0}", Thread.CurrentThread.ManagedThreadId));
- HttpUtil.ExecuteAsync(request, res =>
- {
- Console.WriteLine("进入异步响应 :");
- Console.WriteLine(res.Content);
- Console.WriteLine(" ");
- Console.WriteLine(string.Format("当前子线程ID:{0}", Thread.CurrentThread.ManagedThreadId));
- Console.WriteLine("异步结束 ");
- });
- Console.WriteLine(string.Format("当前主线程ID:{0}", Thread.CurrentThread.ManagedThreadId));
- }
- catch (Exception)
- {
-
- }
- finally
- {
- if (file_stream != null)
- file_stream.Close();
- }
-
- }
- }
-
-
-
- }
-}
diff --git a/OSS.Http.ConsoleTest/Properties/AssemblyInfo.cs b/OSS.Http.ConsoleTest/Properties/AssemblyInfo.cs
deleted file mode 100644
index 3c8456a..0000000
--- a/OSS.Http.ConsoleTest/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("OSS.Http.ConsoleTest")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Microsoft")]
-[assembly: AssemblyProduct("OSS.Http.ConsoleTest")]
-[assembly: AssemblyCopyright("Copyright © Microsoft 2013")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("1f56fe4b-8d19-4842-8019-0cab316444c9")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/OSS.Http.NET45.sln b/OSS.Http.NET45.sln
new file mode 100644
index 0000000..ec7db6a
--- /dev/null
+++ b/OSS.Http.NET45.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OSS.Http.NET45", "OSS.Http\OSS.Http.NET45.csproj", "{5A831C5B-8D82-4A6A-A555-3E04847455D1}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {5A831C5B-8D82-4A6A-A555-3E04847455D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5A831C5B-8D82-4A6A-A555-3E04847455D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5A831C5B-8D82-4A6A-A555-3E04847455D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5A831C5B-8D82-4A6A-A555-3E04847455D1}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/OSS.Http.sln b/OSS.Http.sln
index 2eda144..09dc39f 100644
--- a/OSS.Http.sln
+++ b/OSS.Http.sln
@@ -3,9 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OSS.Http", "OSS.Http\OSS.Http.csproj", "{5A831C5B-8D82-4A6A-A555-3E04847455D1}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OSS.Http.ConsoleTest", "OSS.Http.ConsoleTest\OSS.Http.ConsoleTest.csproj", "{0504F610-BD59-45B5-988C-BFFE15AAAC82}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OSS.Http", "OSS.Http\OSS.Http.csproj", "{7AE49C75-D715-4688-8E11-A8334C461608}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -13,14 +11,10 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {5A831C5B-8D82-4A6A-A555-3E04847455D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {5A831C5B-8D82-4A6A-A555-3E04847455D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {5A831C5B-8D82-4A6A-A555-3E04847455D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {5A831C5B-8D82-4A6A-A555-3E04847455D1}.Release|Any CPU.Build.0 = Release|Any CPU
- {0504F610-BD59-45B5-988C-BFFE15AAAC82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {0504F610-BD59-45B5-988C-BFFE15AAAC82}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {0504F610-BD59-45B5-988C-BFFE15AAAC82}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {0504F610-BD59-45B5-988C-BFFE15AAAC82}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7AE49C75-D715-4688-8E11-A8334C461608}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7AE49C75-D715-4688-8E11-A8334C461608}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7AE49C75-D715-4688-8E11-A8334C461608}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7AE49C75-D715-4688-8E11-A8334C461608}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/OSS.Http/Connect/HttpBase.cs b/OSS.Http/Connect/HttpBase.cs
deleted file mode 100644
index 7d6aa6d..0000000
--- a/OSS.Http/Connect/HttpBase.cs
+++ /dev/null
@@ -1,510 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Net;
-using System.Text;
-using System.Web;
-using OSS.Http.Models;
-
-namespace OSS.Http.Connect
-{
- ///
- /// 请求基类
- ///
- public abstract class HttpBase
- {
- private const string _lineBreak = "\r\n";
- private static readonly Encoding _defaultEncoding = Encoding.UTF8;
- protected IDictionary> _notCanAddHeaderDictionary = null;
- public HttpBase()
- {
- _notCanAddHeaderDictionary = new Dictionary>(StringComparer.InvariantCultureIgnoreCase);
- }
-
-
- ///
- /// 配置请求
- ///
- ///
- protected virtual HttpWebRequest ConfigureWebRequest(OsHttpRequest request)
- {
- Uri uri = BuildUri(request); // 创建url请求
- var webRequest = (HttpWebRequest)WebRequest.Create(uri);
-
- ServicePointManager.Expect100Continue = false;
- if (request.IsDecompres)
- {
- webRequest.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip | DecompressionMethods.None;
- }
-
- webRequest.Method = request.HttpMothed.ToString();
-
- if (request.TimeOutMilSeconds>0)
- {
- webRequest.Timeout = request.TimeOutMilSeconds;
- webRequest.ReadWriteTimeout = request.TimeOutMilSeconds;
- }
-
- if (!request.HasFile)
- {
- webRequest.ContentLength = 0;
- }
-
- webRequest.ContentType = "application/x-www-form-urlencoded"; //添加一个默认类型,具体自定义可以在后边重写
-
- PrepareHeaders(webRequest, request); // 添加头部信息
- PrepareCookies(webRequest, request); // 添加cookie信息
-
- request.CustomPropertySetting?.Invoke(webRequest);
-
- return webRequest;
- }
-
-
-
- ///
- /// 创建请求的 Url 对象
- ///
- /// 请求的对象实体
- /// 返回的 System.Uri 对象
- protected virtual Uri BuildUri(OsHttpRequest request)
- {
- string urlAddress = request.AddressUrl;
- if (string.IsNullOrEmpty(urlAddress))
- {
- throw new ArgumentNullException("无效的请求,请求对象中的 UrlAddress 不能为空");
- }
- return new Uri(urlAddress);
- }
-
-
- #region 准备模块
-
- ///
- /// 准备请求的 头部 数据
- ///
- ///
- ///
- protected virtual void PrepareHeaders(HttpWebRequest webRequest, OsHttpRequest request)
- {
- foreach (var header in request.HeaderParameters)
- {
- if (_notCanAddHeaderDictionary.ContainsKey(header.Name))
- {
- _notCanAddHeaderDictionary[header.Name].Invoke(webRequest, header.Value.ToString());
- }
- else
- {
- webRequest.Headers.Add(header.Name, header.Value.ToString());
- }
-
- }
- }
-
- ///
- /// 准备请求的 cookie 数据
- ///
- ///
- ///
- protected virtual void PrepareCookies(HttpWebRequest webRequest, OsHttpRequest request)
- {
- webRequest.CookieContainer = new CookieContainer();
-
- foreach (var httpCookie in request.CookieParameters)
- {
- var cookie = new Cookie
- {
- Name = httpCookie.Name,
- Value = httpCookie.Value.ToString(),
- Domain =string.IsNullOrEmpty(httpCookie.Domain)? webRequest.RequestUri.Host:httpCookie.Domain
- };
- webRequest.CookieContainer.Add(cookie);
- }
- }
- #endregion
-
-
- ///
- /// 准备请求的 内容 数据 === 同步
- ///
- /// HttpWebRequest请求
- protected virtual void SendBodyDataSync(HttpWebRequest webRequest, OsHttpRequest request)
- {
- string boundary = GetBoundary();
- if (request.HasFile)
- {
- webRequest.ContentType = GetMultipartFormContentType(boundary);
- using (var webRequestStream = webRequest.GetRequestStream())
- {
- WriteMultipartFormData(webRequestStream, request, boundary);
- }
- }
- else
- {
- string data = EncodeFormParameters(request);
- if (!string.IsNullOrEmpty(data))
- {
- var bytes = _defaultEncoding.GetBytes(data);
- webRequest.ContentLength = bytes.Length;
- using (var webRequestStream = webRequest.GetRequestStream())
- {
- webRequestStream.Write(bytes, 0, bytes.Length);
- }
- }
- }
- }
-
- ///
- /// 准备请求的 内容 数据 === 异步
- ///
- /// HttpWebRequest请求
- ///
- ///
- protected virtual void SendBodyDataAsyncAndCallBack(HttpWebRequest webRequest, OsHttpRequest request,
- Action action)
- {
- if (request.HttpMothed == HttpMothed.POST && request.FormParameters.Count > 0 || request.HasFile)
- {
- if (!request.HasFile)
- {
- webRequest.ContentLength = _defaultEncoding.GetByteCount(EncodeFormParameters(request));
- }
- webRequest.BeginGetRequestStream(ar => RquestStreamCallBack(ar, request, action), webRequest);
- }
- else
- {
- webRequest.BeginGetResponse(ar => ResponseCallBackAsync(ar, action), webRequest);
- }
- }
-
- ///
- /// 异步请求处理
- ///
- ///
- ///
- ///
- private void RquestStreamCallBack(IAsyncResult result, OsHttpRequest request,
- Action action)
- {
-
-
- HttpWebRequest webRequest = result.AsyncState as HttpWebRequest;
-
- if (request.HasFile)
- {
- string boundary = GetBoundary();
-
- webRequest.ContentType = GetMultipartFormContentType(boundary);
-
- using (var webRequestStream = webRequest.EndGetRequestStream(result))
- {
- WriteMultipartFormData(webRequestStream, request, boundary);
- }
- }
- else
- {
- var bytes = _defaultEncoding.GetBytes(EncodeFormParameters(request));
-
- using (var webRequestStream = webRequest.EndGetRequestStream(result))
- {
- webRequestStream.Write(bytes, 0, bytes.Length);
- }
- }
-
- webRequest.BeginGetResponse(ar => ResponseCallBackAsync(ar, action), webRequest);
- }
-
- ///
- /// 异步响应处理
- ///
- ///
- ///
- private void ResponseCallBackAsync(IAsyncResult result, Action action)
- {
- var response = new OsHttpResponse();
-
- HttpWebResponse web_response = null;
- try
- {
- var webRequest = (HttpWebRequest)result.AsyncState;
- web_response = webRequest.EndGetResponse(result) as HttpWebResponse;
- }
- catch (WebException ex)
- {
- if (ex.Status == WebExceptionStatus.RequestCanceled)
- {
- throw ex;
- }
- if (ex.Response is HttpWebResponse)
- {
- response.ResponseStatus = ResponseStatus.ErrorButResponse;
- web_response = ex.Response as HttpWebResponse;
- }
- else
- {
- throw ex;
- }
- }
-
- ExtractResponseData(response, web_response);
-
- if (action != null)
- {
- action(response);
- }
-
- if (web_response != null)
- web_response.Close();
- }
-
- #region 请求数据的 内容 处理
-
- #region 处理带文件上传的数据处理
- ///
- /// 创建 请求 分割界限
- ///
- ///
- protected static string GetBoundary()
- {
- string pattern = "abcdefghijklmnopqrstuvwxyz0123456789";
- StringBuilder boundaryBuilder = new StringBuilder();
- Random rnd = new Random();
- for (int i = 0; i < 10; i++)
- {
- var index = rnd.Next(pattern.Length);
- boundaryBuilder.Append(pattern[index]);
- }
- return string.Format("-----------------------------{0}", boundaryBuilder.ToString());
- }
-
- ///
- /// 返回含文件请求的ContentType
- ///
- ///
- /// 返回 WebRequest 的 ContenType 信息
- protected static string GetMultipartFormContentType(string boundary)
- {
- return string.Format("multipart/form-data; boundary={0}", boundary);
- }
-
- ///
- /// 写入 Form 的内容值 【 非文件参数 + 文件头 + 文件参数(内部完成) + 请求结束符 】
- ///
- ///
- ///
- protected void WriteMultipartFormData(Stream webRequestStream, OsHttpRequest request, string boundary)
- {
- var formparas = request.FormParameters;
- foreach (var param in formparas)
- {
- //写入form表单中的非文件数据
- WriteStringTo(webRequestStream, GetMultipartFormData(param, boundary));
- }
- foreach (var file in request.FileParameterList)
- {
- //文件头
- WriteStringTo(webRequestStream, GetMultipartFileHeader(file, boundary));
- //文件内容
- file.Writer(webRequestStream);
- //文件结尾
- WriteStringTo(webRequestStream, _lineBreak);
- }
- //写入整个请求的底部信息
- WriteStringTo(webRequestStream, GetMultipartFooter(boundary));
- }
-
- ///
- /// 写入 Form 的内容值(非文件参数)
- ///
- ///
- ///
- ///
- protected static string GetMultipartFormData(Parameter param, string boundary)
- {
- return string.Format("--{0}{3}Content-Disposition: form-data; name=\"{1}\"{3}{3}{2}{3}",
- boundary, param.Name, param.Value, _lineBreak);
- }
-
- ///
- /// 写入 Form 的内容值(文件头)
- ///
- ///
- ///
- ///
- protected static string GetMultipartFileHeader(FileParameter file, string boundary)
- {
- return string.Format("--{0}{4}Content-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"{4}Content-Type: {3}{4}{4}",
- boundary, file.Name, file.FileName, file.ContentType ?? "application/octet-stream", _lineBreak);
- }
-
- ///
- /// 写入 Form 的内容值 (请求结束符)
- ///
- ///
- ///
- protected static string GetMultipartFooter(string boundary)
- {
- return string.Format("--{0}--{1}", boundary, _lineBreak);
- }
- #endregion
-
- #region 不包含文件的数据处理(正常 get/post 请求)
- ///
- /// 写入请求的内容信息 (非文件上传请求)
- ///
- ///
- ///
- protected static string EncodeFormParameters(OsHttpRequest request)
- {
- var formstring = new StringBuilder();
- foreach (var p in request.FormParameters)
- {
- if (formstring.Length > 1)
- formstring.Append("&");
- formstring.AppendFormat("{0}={1}", p.Name, p.Value);
- }
- if (!string.IsNullOrEmpty(request.CustomBody))
- {
- if (formstring.Length > 1)
- formstring.Append("&");
- formstring.Append(request.CustomBody);
- }
- return formstring.ToString();
- }
- #endregion
-
- #endregion
-
- #region 请求返回 -- 返回数据的处理
-
- ///
- /// 返回自定义
- ///
- /// 传入 webrequest 对象
- /// 需要返回的自定义 response 对象
- ///
- protected virtual void GetResponse(HttpWebRequest request, ref OsHttpResponse response)
- {
- response.ResponseStatus = ResponseStatus.None;
-
- bool isErrorButResponse;
- var webResponse = GetHttpResponse(request, out isErrorButResponse);
-
- ExtractResponseData(response, webResponse);
-
- if (isErrorButResponse)
- response.ResponseStatus = ResponseStatus.ErrorButResponse;
-
- }
-
- ///
- /// 获取远程请求响应
- ///
- /// 请求对象
- /// 请求返回是否正常
- ///
- private static HttpWebResponse GetHttpResponse(HttpWebRequest request, out bool isErrorButResponse)
- {
- HttpWebResponse webResponse = null;
- isErrorButResponse = false;
- try
- {
- webResponse = (HttpWebResponse)request.GetResponse();
- }
- catch (WebException ex)
- {
- if (ex.Response is HttpWebResponse)
- {
- isErrorButResponse = true;
- webResponse = ex.Response as HttpWebResponse;
- }
- else
- throw;
- }
- return webResponse;
- }
-
-
- ///
- /// 填充自定义 response 值
- ///
- ///
- ///
- private static void ExtractResponseData(OsHttpResponse response, HttpWebResponse webResponse)
- {
- using (webResponse)
- {
- response.ContentEncoding = webResponse.ContentEncoding;
- response.Server = webResponse.Server;
- response.ContentType = webResponse.ContentType;
- response.ContentLength = webResponse.ContentLength;
-
- response.StatusCode = webResponse.StatusCode;
- response.StatusDescription = webResponse.StatusDescription;
- response.ResponseUri = webResponse.ResponseUri;
- response.ResponseStatus = ResponseStatus.Completed;
-
- response.RawBytes = ReadAsBytes(webResponse.GetResponseStream());
-
- if (webResponse.Cookies != null)
- {
- foreach (Cookie cookie in webResponse.Cookies)
- {
- HttpCookie recookie = new HttpCookie(cookie.Name);
- recookie.Domain = cookie.Domain;
- recookie.Expires = cookie.Expires;
- recookie.HttpOnly = cookie.HttpOnly;
- recookie.Path = cookie.Path;
- recookie.Secure = cookie.Secure;
- recookie.Value = cookie.Value;
- response.Cookies.Add(recookie);
- }
- }
-
- foreach (var headerName in webResponse.Headers.AllKeys)
- {
- var headerValue = webResponse.Headers[headerName];
- response.Headers.Add(new Parameter { Name = headerName, Value = headerValue });
- }
- webResponse.Close();
- }
- }
-
- ///
- /// 流转化成字节
- ///
- /// 要转化的流
- /// byte[]
- protected static byte[] ReadAsBytes(Stream input)
- {
- byte[] buffer = new byte[16 * 1024];
- using (MemoryStream ms = new MemoryStream())
- {
- int read;
- while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
- {
- ms.Write(buffer, 0, read);
- }
- return ms.ToArray();
- }
- }
- #endregion
-
- #region 请求辅助方法
- ///
- /// 写入数据方法(将数据写入 webrequest)
- ///
- ///
- ///
- protected static void WriteStringTo(Stream stream, string toWrite)
- {
- var bytes = _defaultEncoding.GetBytes(toWrite);
- stream.Write(bytes, 0, bytes.Length);
- }
-
- protected virtual void AddStaticHeaderDictionary()
- {
- }
- #endregion
- }
-}
diff --git a/OSS.Http/Connect/OsRest.cs b/OSS.Http/Connect/OsRest.cs
new file mode 100644
index 0000000..ee9ee10
--- /dev/null
+++ b/OSS.Http/Connect/OsRest.cs
@@ -0,0 +1,262 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net.Http;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using OSS.Http.Models;
+
+namespace OSS.Http.Connect
+{
+ ///
+ /// 请求基类
+ ///
+ public class OsRest:HttpClient
+ {
+ private const string _lineBreak = "\r\n";
+ private static readonly Encoding _defaultEncoding = Encoding.UTF8;
+
+ public OsRest():this(new HttpClientHandler(),true)
+ {
+ }
+ public OsRest(HttpMessageHandler handler)
+ : this(handler,true)
+ {
+ }
+ public OsRest(HttpMessageHandler handler,bool disposeHandler) : base(handler, disposeHandler)
+ {
+ }
+
+ ///
+ /// 执行请求方法
+ ///
+ ///
+ ///
+ ///
+ ///
+ public Task RestSend(OsHttpRequest request,
+ HttpCompletionOption completionOption = HttpCompletionOption.ResponseContentRead,
+ CancellationToken cancellationToken = new CancellationToken())
+ {
+ var reqMsg = ConfigureReqMsg(request);
+
+ if (request.TimeOutMilSeconds > 0)
+ this.Timeout = TimeSpan.FromMilliseconds(request.TimeOutMilSeconds);
+
+ return SendAsync(reqMsg, completionOption, cancellationToken);
+ }
+
+
+ #region 配置 ReqMsg信息
+
+ ///
+ /// 配置请求
+ ///
+ ///
+ public HttpRequestMessage ConfigureReqMsg(OsHttpRequest request)
+ {
+ var reqMsg = new HttpRequestMessage();
+
+ reqMsg.RequestUri = ConfigReqUriMsg(request);
+ reqMsg.Method = new HttpMethod(request.HttpMothed.ToString());
+ reqMsg.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); // 默认补充,如果头参数中已设置,后边会覆盖
+
+ //ConfigReqHeadersMsg(reqMsg.Headers, request); // 添加头部信息
+ request.HeaderSetting?.Invoke(reqMsg.Headers);
+ ConfigReqContent(reqMsg,request); // 配置内容
+
+ return reqMsg;
+ }
+
+ ///
+ /// 创建请求的 Url 对象
+ ///
+ /// 请求的对象实体
+ /// 返回的 System.Uri 对象
+ private Uri ConfigReqUriMsg(OsHttpRequest request)
+ {
+ if (string.IsNullOrEmpty(request.AddressUrl))
+ {
+ throw new ArgumentNullException(nameof(request), "无效的请求,请求对象中的 UrlAddress 不能为空");
+ }
+ string urlAddress = request.AddressUrl;
+
+ var queryPara = GetReqParameters(request, ParameterType.Query);
+ urlAddress = queryPara.Aggregate(urlAddress, (current, p) => string.Concat(current, current.IndexOf("?", StringComparison.CurrentCultureIgnoreCase) < 0 ? "?" : "&", p.ToString()));
+
+
+ return new Uri(urlAddress);
+ }
+
+ ///
+ /// 配置使用的cotent
+ ///
+ ///
+ ///
+ ///
+ private void ConfigReqContent(HttpRequestMessage reqMsg, OsHttpRequest req)
+ {
+ //var reqContent=new StreamContent();
+ var contentStream = new MemoryStream();
+
+ if (req.HasFile)
+ {
+ string boundary = GetBoundary();
+ WriteMultipartFormData(contentStream, req, boundary);
+ }
+ else
+ {
+ string data = GetNormalFormData(req);
+ if (!string.IsNullOrEmpty(data))
+ {
+ var bytes = _defaultEncoding.GetBytes(data);
+ contentStream.Write(bytes, 0, bytes.Length);
+ }
+ }
+ reqMsg.Content = new StreamContent(contentStream);
+ }
+ #endregion
+
+
+ #region 请求数据的 内容 处理
+
+ #region 处理带文件上传的数据处理
+ ///
+ /// 创建 请求 分割界限
+ ///
+ ///
+ private static string GetBoundary()
+ {
+ string pattern = "abcdefghijklmnopqrstuvwxyz0123456789";
+ StringBuilder boundaryBuilder = new StringBuilder();
+ Random rnd = new Random();
+ for (int i = 0; i < 10; i++)
+ {
+ var index = rnd.Next(pattern.Length);
+ boundaryBuilder.Append(pattern[index]);
+ }
+ return string.Format("-----------------------------{0}", boundaryBuilder.ToString());
+ }
+
+ /////
+ ///// 返回含文件请求的ContentType
+ /////
+ /////
+ ///// 返回 WebRequest 的 ContenType 信息
+ //private static string GetMultipartFormContentType(string boundary)
+ //{
+ // return string.Format("multipart/form-data; boundary={0}", boundary);
+ //}
+
+ ///
+ /// 写入 Form 的内容值 【 非文件参数 + 文件头 + 文件参数(内部完成) + 请求结束符 】
+ ///
+ ///
+ ///
+ private void WriteMultipartFormData(Stream webRequestStream, OsHttpRequest request, string boundary)
+ {
+ var formparas =GetReqParameters(request,ParameterType.Form);
+ foreach (var param in formparas)
+ {
+ //写入form表单中的非文件数据
+ WriteStringTo(webRequestStream, GetMultipartFormData(param, boundary));
+ }
+ foreach (var file in request.FileParameterList)
+ {
+ //文件头
+ WriteStringTo(webRequestStream, GetMultipartFileHeader(file, boundary));
+ //文件内容
+ file.Writer(webRequestStream);
+ //文件结尾
+ WriteStringTo(webRequestStream, _lineBreak);
+ }
+ //写入整个请求的底部信息
+ WriteStringTo(webRequestStream, GetMultipartFooter(boundary));
+ }
+
+ ///
+ /// 写入 Form 的内容值(非文件参数)
+ ///
+ ///
+ ///
+ ///
+ private static string GetMultipartFormData(Parameter param, string boundary)
+ {
+ return string.Format("--{0}{3}Content-Disposition: form-data; name=\"{1}\"{3}{3}{2}{3}",
+ boundary, param.Name, param.Value, _lineBreak);
+ }
+
+ ///
+ /// 写入 Form 的内容值(文件头)
+ ///
+ ///
+ ///
+ ///
+ private static string GetMultipartFileHeader(FileParameter file, string boundary)
+ {
+ return string.Format("--{0}{4}Content-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"{4}Content-Type: {3}{4}{4}",
+ boundary, file.Name, file.FileName, file.ContentType ?? "application/octet-stream", _lineBreak);
+ }
+
+ ///
+ /// 写入 Form 的内容值 (请求结束符)
+ ///
+ ///
+ ///
+ private static string GetMultipartFooter(string boundary)
+ {
+ return string.Format("--{0}--{1}", boundary, _lineBreak);
+ }
+ #endregion
+
+ #region 不包含文件的数据处理(正常 get/post 请求)
+ ///
+ /// 写入请求的内容信息 (非文件上传请求)
+ ///
+ ///
+ ///
+ private static string GetNormalFormData(OsHttpRequest request)
+ {
+ var formParas = GetReqParameters(request, ParameterType.Form);
+ var formstring = new StringBuilder();
+ foreach (var p in formParas)
+ {
+ if (formstring.Length > 1)
+ formstring.Append("&");
+ formstring.AppendFormat("{0}={1}", p.Name, p.Value);
+ }
+ if (!string.IsNullOrEmpty(request.CustomBody))
+ {
+ if (formstring.Length > 1)
+ formstring.Append("&");
+ formstring.Append(request.CustomBody);
+ }
+ return formstring.ToString();
+ }
+ #endregion
+
+ #endregion
+
+
+ #region 请求辅助方法
+ ///
+ /// 写入数据方法(将数据写入 webrequest)
+ ///
+ ///
+ ///
+ private static void WriteStringTo(Stream stream, string toWrite)
+ {
+ var bytes = _defaultEncoding.GetBytes(toWrite);
+ stream.Write(bytes, 0, bytes.Length);
+ }
+
+
+ private static List GetReqParameters(OsHttpRequest request,ParameterType type)
+ {
+ return request.Parameters.Where(p => p.Type == type).ToList() ?? new List();
+ }
+ #endregion
+ }
+}
diff --git a/OSS.Http/Connect/RestHttp.Async.cs b/OSS.Http/Connect/RestHttp.Async.cs
deleted file mode 100644
index 0dac62b..0000000
--- a/OSS.Http/Connect/RestHttp.Async.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using OSS.Http.Interface;
-using OSS.Http.Models;
-using System;
-using System.Net;
-
-namespace OSS.Http.Connect
-{
- internal partial class RestHttp
- {
- public void ExecuteAsync(OsHttpRequest request, Action action)
- {
- OsHttpResponse response = new OsHttpResponse();
-
- if (string.IsNullOrEmpty(request.AddressUrl)
- || request.HttpMothed == HttpMothed.None)
- {
- throw new ArgumentException("对不起,请求出错,请检查参数等设置(地址,请求方式等)!", "request");
-
- }
-
- HttpWebRequest webrequest = ConfigureWebRequest(request);
-
- SendBodyDataAsyncAndCallBack(webrequest, request, action);
-
- }
- }
-}
diff --git a/OSS.Http/Connect/RestHttp.Sync.cs b/OSS.Http/Connect/RestHttp.Sync.cs
deleted file mode 100644
index f9a8783..0000000
--- a/OSS.Http/Connect/RestHttp.Sync.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-using OSS.Http.Interface;
-using OSS.Http.Models;
-using System;
-using System.Net;
-
-namespace OSS.Http.Connect
-{
- internal partial class RestHttp : HttpBase, IHttp
- {
- public RestHttp()
- {
- AddStaticHeaderDictionary();
- }
-
- ///
- /// 同步的请求方式
- ///
- /// 请求的参数
- /// 自定义的Response结果
- public OsHttpResponse ExecuteSync(OsHttpRequest request)
- {
- OsHttpResponse response = new OsHttpResponse();
-
- if (string.IsNullOrEmpty(request.AddressUrl)
- || request.HttpMothed == HttpMothed.None)
- {
- throw new ArgumentException("对不起,请求出错,请检查参数等设置(地址,请求方式等)!", "request");
- }
- HttpWebRequest webrequest = ConfigureWebRequest(request);
-
- SendBodyDataSync(webrequest, request);
-
- GetResponse(webrequest, ref response);
-
- return response;
- }
-
- protected override void AddStaticHeaderDictionary()
- {
- _notCanAddHeaderDictionary.Add("Accept", (r, v) => r.Accept = v);
- _notCanAddHeaderDictionary.Add("Content-Type", (r, v) => r.ContentType = v);
-
- _notCanAddHeaderDictionary.Add("Date", (r, v) =>
- {
- DateTime parsed;
- if (DateTime.TryParse(v, out parsed))
- {
- r.Date = parsed;
- }
- });
- _notCanAddHeaderDictionary.Add("Host", (r, v) => r.Host = v);
- _notCanAddHeaderDictionary.Add("Connection", (r, v) => r.Connection = v);
- _notCanAddHeaderDictionary.Add("Content-Length", (r, v) => r.ContentLength = Convert.ToInt64(v));
- _notCanAddHeaderDictionary.Add("Expect", (r, v) => r.Expect = v);
- _notCanAddHeaderDictionary.Add("If-Modified-Since", (r, v) => r.IfModifiedSince = Convert.ToDateTime(v));
- _notCanAddHeaderDictionary.Add("Referer", (r, v) => r.Referer = v);
- _notCanAddHeaderDictionary.Add("Transfer-Encoding", (r, v) => { r.TransferEncoding = v; r.SendChunked = true; });
- _notCanAddHeaderDictionary.Add("User-Agent", (r, v) => r.UserAgent = v);
- }
-
-
-
- }
-}
diff --git a/OSS.Http/Enum.cs b/OSS.Http/Enum.cs
index a75729d..d21782a 100644
--- a/OSS.Http/Enum.cs
+++ b/OSS.Http/Enum.cs
@@ -14,22 +14,26 @@ namespace OSS.Http
///
/// Get
///
- GET = 2,
+ GET = 10,
///
/// post
///
- POST = 4,
+ POST = 20,
///
/// PUT
///
- PUT=8,
+ PUT = 30,
///
/// DELETE
///
- DELETE=16
+ DELETE = 40,
+ HEAD=50,
+ OPTIONS=60,
+ TRACE=70
+
}
///
@@ -54,7 +58,7 @@ namespace OSS.Http
///
ErrorButResponse,
///
- /// 超市
+ /// 超时
///
TimedOut,
///
@@ -81,10 +85,10 @@ namespace OSS.Http
/// 地址中的值
///
UrlSegment,
- ///
- /// 头部参数
- ///
- Header,
+ /////
+ ///// 头部参数
+ /////
+ //Header,
///
/// cookie
///
diff --git a/OSS.Http/HttpUtil.cs b/OSS.Http/HttpUtil.cs
index 6bb30d9..629a7c1 100644
--- a/OSS.Http/HttpUtil.cs
+++ b/OSS.Http/HttpUtil.cs
@@ -1,37 +1,48 @@
using System;
+using System.Net.Http;
+using System.Threading.Tasks;
using OSS.Http.Connect;
-using OSS.Http.Interface;
using OSS.Http.Models;
namespace OSS.Http
{
///
- ///
+ /// http请求辅助类
///
public static class HttpUtil
{
- private static IHttp httpsync = new RestHttp();
+ private static HttpClientHandler m_Handler;
+ private static OsRest m_Client ;
+
+ public static Action SetHandler { get; set; }
+
///
/// 同步的请求方式
///
/// 请求的参数
/// 自定义的Response结果
- public static OsHttpResponse ExecuteSync(this OsHttpRequest request)
+ public static Task ExecuteSync(this OsHttpRequest request,HttpCompletionOption completionOption=HttpCompletionOption.ResponseContentRead)
{
- return httpsync.ExecuteSync(request);
+ if (m_Client==null)
+ {
+ m_Handler=new HttpClientHandler();
+ ConfigClientHandler(m_Handler);
+ m_Client=new OsRest(m_Handler);
+ }
+ return m_Client.RestSend(request, completionOption);
}
-
///
- /// 异步的请求方式
+ /// 配置请求处理类
///
- /// 请求的参数
- ///
- /// 自定义的Response结果
- public static void ExecuteAsync(this OsHttpRequest request, Action callback)
+ ///
+ public static void ConfigClientHandler(HttpClientHandler reqHandler)
{
- httpsync.ExecuteAsync(request, callback);
+ reqHandler.AllowAutoRedirect = true;
+ reqHandler.MaxAutomaticRedirections = 5;
+ reqHandler.UseCookies = true;
+ SetHandler?.Invoke(reqHandler);
}
diff --git a/OSS.Http/Interface/IHttp.cs b/OSS.Http/Interface/IHttp.cs
deleted file mode 100644
index 5e214b6..0000000
--- a/OSS.Http/Interface/IHttp.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System;
-using OSS.Http.Models;
-
-namespace OSS.Http.Interface
-{
- public interface IHttp
- {
- #region
- ///
- /// 同步执行
- ///
- /// 请求的参数
- /// 自定义的Response结果
- OsHttpResponse ExecuteSync(OsHttpRequest request);
-
- ///
- /// 异步请求
- ///
- /// 请求的参数
- /// 自定义的Response结果
- void ExecuteAsync(OsHttpRequest request,Action action);
- #endregion
- }
-}
diff --git a/OSS.Http/Models/FileParameter.cs b/OSS.Http/Models/FileParameter.cs
index c6237dc..29cb51a 100644
--- a/OSS.Http/Models/FileParameter.cs
+++ b/OSS.Http/Models/FileParameter.cs
@@ -1,6 +1,5 @@
using System;
using System.IO;
-using System.Linq;
namespace OSS.Http.Models
{
@@ -29,7 +28,6 @@ namespace OSS.Http.Models
};
this.FileName = filename;
this.ContentType = contentType;
-
this.Name = name;
}
///
diff --git a/OSS.Http/Models/HttpRequest.cs b/OSS.Http/Models/HttpRequest.cs
index 7d0e03b..587500d 100644
--- a/OSS.Http/Models/HttpRequest.cs
+++ b/OSS.Http/Models/HttpRequest.cs
@@ -2,7 +2,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Net;
+using System.Net.Http;
+using System.Net.Http.Headers;
namespace OSS.Http.Models
{
@@ -17,81 +18,73 @@ namespace OSS.Http.Models
FileParameterList = new List();
}
-
- ///
- /// 自定义属性设置
- ///
- public Action CustomPropertySetting { get; set; }
-
- ///
- /// form 参数列表
- ///
- internal IList FormParameters { get { return GetParameters(ParameterType.Form);} }
- ///
- /// header 参数列表
- ///
- internal IList HeaderParameters { get { return GetParameters(ParameterType.Header); } }
- ///
- /// Query 参数列表
- ///
- internal IList QueryParameters { get { return GetParameters(ParameterType.Query); } }
- ///
- /// Cookie 参数列表
- ///
- internal IList CookieParameters { get { return GetParameters(ParameterType.Cookie); } }
-
-
-
- ///
- /// 文件参数列表
- ///
- public IList FileParameterList { get; set; }
///
/// 请求地址信息
///
public string AddressUrl { get; set; }
+
///
/// 请求方式
///
public HttpMothed HttpMothed { get; set; }
+ /////
+ ///// 是否允许自动重定向
+ ///// 默认为true 最大可重定向次数为 5
+ /////
+ //public bool AllowAutoRedirect { get; set; } = true;
+
+ /////
+ ///// 是否使用压缩
+ /////
+ //public bool AutoDecompres { get; set; }
+
+ /////
+ ///// 是否使用cookie
+ /////
+ //public bool UseCookies { get; set; }
///
- /// 超时时间(毫秒)
+ /// 头部属性自定义设置
///
- public int TimeOutMilSeconds { get; set; }
+ public Action HeaderSetting { get; set; }
+
+ ///
+ /// HttpClientHandler 自定义属性设置
+ ///
+ public Action HandlerSetting { get; set; }
+
+ #region 请求的内容参数
+
+ ///
+ /// 文件参数列表
+ ///
+ public List FileParameterList { get; set; }
///
/// 是否存在文件
///
public bool HasFile
{
- get
- {
- return FileParameterList.Any();
- }
+ get { return FileParameterList.Any(); }
}
+
///
- /// 参数列表
+ /// 非文件参数列表
///
- public IList Parameters { get; set; }
- private IList GetParameters(ParameterType type)
- {
- return this.Parameters.Where(p => p.Type == type).ToList() ?? new List();
- }
+ public List Parameters { get; set; }
+ #endregion
///
- /// 自定义内容实体,键值对 key=value&key1=value1 或者自定义内容格式
+ /// 自定义内容实体
/// eg:当上传文件时,无法自定义内容
///
public string CustomBody { get; set; }
-
///
- /// 是否使用压缩
+ /// 超时时间(毫秒)
///
- public bool IsDecompres { get; set; }
-
+ public int TimeOutMilSeconds { get; set; }
}
}
diff --git a/OSS.Http/Models/HttpResponse.cs b/OSS.Http/Models/HttpResponse.cs
deleted file mode 100644
index 7f24cb1..0000000
--- a/OSS.Http/Models/HttpResponse.cs
+++ /dev/null
@@ -1,116 +0,0 @@
-using OSS.Http.Interface;
-using System;
-using System.Collections.Generic;
-using System.Net;
-using System.Text;
-using System.Web;
-
-namespace OSS.Http.Models
-{
- ///
- /// 响应信息
- ///
- public class OsHttpResponse
- {
- ///
- /// 构造函数
- ///
- public OsHttpResponse()
- {
- Headers = new List();
- Cookies = new List();
- }
- ///
- /// 返回类型
- ///
- public string ContentType { get; set; }
-
- ///
- /// 返回内容的长度
- ///
- public long ContentLength { get; set; }
-
- ///
- /// 返回内容的编码
- ///
- public string ContentEncoding { get; set; }
-
- private string _content;
- ///
- /// 返回的内容
- ///
- public string Content
- {
- get
- {
- if (_content == null && RawBytes != null && RawBytes.Length > 0)
- {
- Encoding encoding = Encoding.UTF8;
-
- _content = encoding.GetString(RawBytes);
- }
- return _content ?? string.Empty;
- }
- }
-
- ///
- /// 内容的字节流
- ///
- public byte[] RawBytes { get; set; }
-
- ///
- /// 返回响应的实际地址
- /// 如果请求过程中出现重定向,此地址
- ///
- public Uri ResponseUri { get; set; }
-
- ///
- /// 字符串,包含发送响应的服务器的名称
- ///
- public string Server { get; set; }
-
- ///
- /// 返回的Cookie列表
- ///
- public IList Cookies { get; private set; }
-
- private ResponseStatus _responseStatus = ResponseStatus.None;
-
- ///
- /// 返回的状态(请求传输等出现错误等状态) 默认是 None 成功为 Completed
- ///
- public ResponseStatus ResponseStatus
- {
- get
- {
- return _responseStatus;
- }
- set
- {
- _responseStatus = value;
- }
- }
-
-
- ///
- /// 返回的 Http状态码
- /// 如: 200, 301等
- ///
- public HttpStatusCode StatusCode { get; set; }
- ///
- /// 返回的状态描述 http状态码的枚举字符串
- /// 如: OK,Moved 等
- ///
- public string StatusDescription { get; set; }
-
- /////
- ///// 错误实体
- /////
- //public Exception ErrorException { get; set; }
-
- ///
- /// 头部列表
- ///
- public IList Headers { get; set; }
- }
-}
diff --git a/OSS.Http/Models/Parameter.cs b/OSS.Http/Models/Parameter.cs
index 2b422c7..ea0a5c7 100644
--- a/OSS.Http/Models/Parameter.cs
+++ b/OSS.Http/Models/Parameter.cs
@@ -63,9 +63,6 @@ namespace OSS.Http.Models
{
return string.Format("{0}={1}", Name.UrlEncode(), Value.UrlEncode());
}
-
-
-
}
internal static class UrlExtension
diff --git a/OSS.Http.ConsoleTest/OSS.Http.ConsoleTest.csproj b/OSS.Http/OSS.Http.NET45.csproj
similarity index 63%
rename from OSS.Http.ConsoleTest/OSS.Http.ConsoleTest.csproj
rename to OSS.Http/OSS.Http.NET45.csproj
index 7704774..9d9e635 100644
--- a/OSS.Http.ConsoleTest/OSS.Http.ConsoleTest.csproj
+++ b/OSS.Http/OSS.Http.NET45.csproj
@@ -4,36 +4,45 @@
Debug
AnyCPU
- {0504F610-BD59-45B5-988C-BFFE15AAAC82}
- Exe
+ {5A831C5B-8D82-4A6A-A555-3E04847455D1}
+ Library
Properties
- OSS.Http.ConsoleTest
- OSS.Http.ConsoleTest
+ OSS.Http
+ OSS.Http
v4.5
512
+
- AnyCPU
true
full
false
bin\Debug\
- DEBUG;TRACE
+ TRACE;DEBUG;NET45
prompt
4
+ false
- AnyCPU
pdbonly
true
bin\Release\
- TRACE
+ TRACE;NET45
prompt
4
+ false
+ bin\Release\OSS.Http.xml
+ GlobalizationRules.ruleset
+
+
+
+ C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Net.Http.dll
+
+
@@ -41,17 +50,16 @@
-
+
+
+
+
+
+
-
-
-
-
- {5a831c5b-8d82-4a6a-a555-3e04847455d1}
- OSS.Http
-
+
+
-
-
-
+
-
-
-
+