HttpServer.cs 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. using System;
  2. using System.IO;
  3. using System.Net;
  4. using System.Net.Security;
  5. using System.Net.Sockets;
  6. using System.Security.Authentication;
  7. using System.Security.Cryptography.X509Certificates;
  8. using System.Threading;
  9. using System.Runtime.InteropServices;
  10. namespace ServerLib
  11. {
  12. public class HttpServer : IServer
  13. {
  14. /// <summary>
  15. /// 服务器IP
  16. /// </summary>
  17. public string ServerIP { get; private set; }
  18. /// <summary>
  19. /// 服务器端口
  20. /// </summary>
  21. public int ServerPort { get; private set; }
  22. /// <summary>
  23. /// 服务器目录
  24. /// </summary>
  25. public string ServerRoot { get; private set; }
  26. /// <summary>
  27. /// 是否运行
  28. /// </summary>
  29. public bool IsRunning { get; private set; }
  30. /// <summary>
  31. /// 服务器协议
  32. /// </summary>
  33. public Protocols Protocol { get; private set; }
  34. /// <summary>
  35. /// 服务端Socet
  36. /// </summary>
  37. private TcpListener serverListener;
  38. /// <summary>
  39. /// 日志接口
  40. /// </summary>
  41. public ILogger Logger { get; set; }
  42. /// <summary>
  43. /// SSL证书
  44. /// </summary>
  45. private X509Certificate serverCertificate = null;
  46. /// <summary>
  47. /// 构造函数
  48. /// </summary>
  49. /// <param name="ipAddress">IP地址</param>
  50. /// <param name="port">端口号</param>
  51. /// <param name="root">根目录</param>
  52. private HttpServer(IPAddress ipAddress, int port, string root)
  53. {
  54. this.ServerIP = ipAddress.ToString();
  55. this.ServerPort = port;
  56. //如果指定目录不存在则采用默认目录
  57. if (!Directory.Exists(root))
  58. this.ServerRoot = AppDomain.CurrentDomain.BaseDirectory;
  59. this.ServerRoot = root;
  60. }
  61. /// <summary>
  62. /// 构造函数
  63. /// </summary>
  64. /// <param name="ipAddress">IP地址</param>
  65. /// <param name="port">端口号</param>
  66. /// <param name="root">根目录</param>
  67. public HttpServer(string ipAddress, int port, string root) :
  68. this(IPAddress.Parse(ipAddress), port, root)
  69. {
  70. }
  71. /// <summary>
  72. /// 构造函数
  73. /// </summary>
  74. /// <param name="ipAddress">IP地址</param>
  75. /// <param name="port">端口号</param>
  76. public HttpServer(string ipAddress, int port) :
  77. this(IPAddress.Parse(ipAddress), port, AppDomain.CurrentDomain.BaseDirectory)
  78. {
  79. }
  80. /// <summary>
  81. /// 构造函数
  82. /// </summary>
  83. /// <param name="port">端口号</param>
  84. /// <param name="root">根目录</param>
  85. public HttpServer(int port, string root) :
  86. this(IPAddress.Loopback, port, root)
  87. {
  88. }
  89. /// <summary>
  90. /// 构造函数
  91. /// </summary>
  92. /// <param name="port">端口号</param>
  93. public HttpServer(int port) :
  94. this(IPAddress.Loopback, port, AppDomain.CurrentDomain.BaseDirectory)
  95. {
  96. }
  97. /// <summary>
  98. /// 构造函数
  99. /// </summary>
  100. /// <param name="ip"></param>
  101. public HttpServer(string ip) :
  102. this(IPAddress.Parse(ip), 80, AppDomain.CurrentDomain.BaseDirectory)
  103. {
  104. }
  105. #region 公开方法
  106. /// <summary>
  107. /// 开启服务器
  108. /// </summary>
  109. public void Start()
  110. {
  111. if (IsRunning) return;
  112. //创建服务端Socket
  113. this.serverListener = new TcpListener(IPAddress.Parse(ServerIP), ServerPort);
  114. this.Protocol = serverCertificate == null ? Protocols.Http : Protocols.Https;
  115. this.IsRunning = true;
  116. this.serverListener.Start();
  117. this.Log(string.Format("Sever is running at {0}://{1}:{2}", Protocol.ToString().ToLower(), ServerIP,
  118. ServerPort));
  119. try
  120. {
  121. while (IsRunning)
  122. {
  123. TcpClient client = serverListener.AcceptTcpClient();
  124. Thread requestThread = new Thread(() => { ProcessRequest(client); });
  125. requestThread.Start();
  126. }
  127. }
  128. catch (Exception e)
  129. {
  130. Log(e.Message);
  131. }
  132. }
  133. public HttpServer SetSSL(string certificate)
  134. {
  135. return SetSSL(X509Certificate.CreateFromCertFile(certificate));
  136. }
  137. public HttpServer SetSSL(X509Certificate certifiate)
  138. {
  139. this.serverCertificate = certifiate;
  140. return this;
  141. }
  142. public void Stop()
  143. {
  144. if (!IsRunning) return;
  145. IsRunning = false;
  146. serverListener.Stop();
  147. }
  148. /// <summary>
  149. /// 设置服务器目录
  150. /// </summary>
  151. /// <param name="root"></param>
  152. public HttpServer SetRoot(string root)
  153. {
  154. if (!Directory.Exists(root))
  155. this.ServerRoot = AppDomain.CurrentDomain.BaseDirectory;
  156. this.ServerRoot = root;
  157. return this;
  158. }
  159. /// <summary>
  160. /// 获取服务器目录
  161. /// </summary>
  162. public string GetRoot()
  163. {
  164. return this.ServerRoot;
  165. }
  166. /// <summary>
  167. /// 设置端口
  168. /// </summary>
  169. /// <param name="port">端口号</param>
  170. /// <returns></returns>
  171. public HttpServer SetPort(int port)
  172. {
  173. this.ServerPort = port;
  174. return this;
  175. }
  176. #endregion
  177. #region 内部方法
  178. /// <summary>
  179. /// 处理客户端请求
  180. /// </summary>
  181. /// <param name="handler">客户端Socket</param>
  182. private void ProcessRequest(TcpClient handler)
  183. {
  184. //处理请求
  185. Stream clientStream = handler.GetStream();
  186. //处理SSL
  187. if (serverCertificate != null) clientStream = ProcessSSL(clientStream);
  188. if (clientStream == null) return;
  189. //构造HTTP请求
  190. HttpRequest request = new HttpRequest(clientStream);
  191. request.Logger = Logger;
  192. //构造HTTP响应
  193. HttpResponse response = new HttpResponse(clientStream);
  194. response.Logger = Logger;
  195. //处理请求类型
  196. switch (request.Method)
  197. {
  198. case "GET":
  199. OnGet(request, response);
  200. break;
  201. case "POST":
  202. OnPost(request, response);
  203. break;
  204. default:
  205. OnDefault(request, response);
  206. break;
  207. }
  208. }
  209. /// <summary>
  210. /// 处理ssl加密请求
  211. /// </summary>
  212. /// <param name="clientStream"></param>
  213. /// <returns></returns>
  214. private Stream ProcessSSL(Stream clientStream)
  215. {
  216. try
  217. {
  218. SslStream sslStream = new SslStream(clientStream);
  219. sslStream.AuthenticateAsServer(serverCertificate, false, SslProtocols.Tls, true);
  220. sslStream.ReadTimeout = 10000;
  221. sslStream.WriteTimeout = 10000;
  222. return sslStream;
  223. }
  224. catch (Exception e)
  225. {
  226. Log(e.Message);
  227. clientStream.Close();
  228. }
  229. return null;
  230. }
  231. /// <summary>
  232. /// 记录日志
  233. /// </summary>
  234. /// <param name="message">日志消息</param>
  235. protected void Log(object message)
  236. {
  237. if (Logger != null) Logger.Log(message);
  238. }
  239. #endregion
  240. #region 虚方法
  241. /// <summary>
  242. /// 响应Get请求
  243. /// </summary>
  244. /// <param name="request">请求报文</param>
  245. public virtual void OnGet(HttpRequest request, HttpResponse response)
  246. {
  247. }
  248. /// <summary>
  249. /// 响应Post请求
  250. /// </summary>
  251. /// <param name="request"></param>
  252. public virtual void OnPost(HttpRequest request, HttpResponse response)
  253. {
  254. }
  255. /// <summary>
  256. /// 响应默认请求
  257. /// </summary>
  258. public virtual void OnDefault(HttpRequest request, HttpResponse response)
  259. {
  260. }
  261. #endregion
  262. }
  263. }