You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

187 lines
5.1 KiB

  1. using Apewer.Network;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Text;
  5. #if NETFX
  6. using System.Web;
  7. using System.Windows.Forms;
  8. #endif
  9. #if NETCORE
  10. using Microsoft.AspNetCore.Http;
  11. using System.Windows.Forms;
  12. #endif
  13. namespace Apewer.Web
  14. {
  15. /// <summary></summary>
  16. public partial class ApiProgram
  17. {
  18. #if NETFX || NETCORE
  19. /// <summary>在当前线程运行标准应用程序消息循环。</summary>
  20. protected static void RunMessageLoop() => Application.Run();
  21. #endif
  22. }
  23. // Listener
  24. public partial class ApiProgram
  25. {
  26. /// <summary>在后台启动 Listener,返回错误消息。</summary>
  27. /// <param name="port">监听的端口。</param>
  28. /// <param name="before">启动 API 解析前执行。</param>
  29. /// <param name="after">启动 Listener 后执行。</param>
  30. public static string Listener(string ip, int port = 80, Action before = null, Action after = null)
  31. {
  32. before?.Invoke();
  33. var server = new Listener();
  34. server.IP = ip;
  35. server.Port = port;
  36. server.Action = (context) => ApiInvoker.Listener(context);
  37. var exception = server.Start();
  38. if (exception != null) return exception.Message;
  39. after?.Invoke();
  40. return null;
  41. }
  42. }
  43. #if NETCORE
  44. // Kestrel & HTTP.Sys
  45. public partial class ApiProgram
  46. {
  47. /// <summary>异步启动 Kestrel,返回错误消息。</summary>
  48. /// <param name="port">监听的端口。</param>
  49. /// <param name="before">启动 API 解析前执行。</param>
  50. /// <param name="after">启动 Listener 后执行。</param>
  51. public static string Kestrel(int port = 80, Action before = null, Action after = null)
  52. {
  53. before?.Invoke();
  54. var instance = new AspNetCore();
  55. instance.Context = (context) => ApiInvoker.AspNetCore(context);
  56. instance.Port = port;
  57. var error = instance.RunKestrel(true);
  58. if (!string.IsNullOrEmpty(error)) return error;
  59. after?.Invoke();
  60. return null;
  61. }
  62. /// <summary>异步启动基于 HTTP.sys 的服务器,返回错误消息。</summary>
  63. /// <param name="port">监听的端口。</param>
  64. /// <param name="before">启动 API 解析前执行。</param>
  65. /// <param name="after">启动 Listener 后执行。</param>
  66. public static string HttpSys(string ip, int port = 80, Action before = null, Action after = null)
  67. {
  68. before?.Invoke();
  69. var instance = new AspNetCore();
  70. instance.Context = (context) => ApiInvoker.AspNetCore(context);
  71. instance.Port = port;
  72. var error = instance.RunHttpSys(ip, true);
  73. if (!string.IsNullOrEmpty(error)) return error;
  74. after?.Invoke();
  75. return null;
  76. }
  77. }
  78. #endif
  79. #if NETFX
  80. // IIS
  81. public partial class ApiProgram : IHttpHandler, IHttpModule
  82. {
  83. private Action _before = null;
  84. /// <summary>仅运行在 IIS 中时会对此类型创建实例。</summary>
  85. /// <param name="before">执行 API 解析前执行。</param>
  86. public ApiProgram(Action before = null)
  87. {
  88. _before = before;
  89. }
  90. #region Initialize
  91. private static object InitLocker = new object();
  92. private bool _initialized = false;
  93. private void Initialize(Action action)
  94. {
  95. if (_initialized) return;
  96. lock (InitLocker)
  97. {
  98. if (_initialized) return;
  99. action?.Invoke();
  100. _initialized = true;
  101. }
  102. }
  103. #endregion
  104. #region IHttpHandler
  105. /// <summary></summary>
  106. public bool IsReusable { get { return false; } }
  107. /// <summary></summary>
  108. public void ProcessRequest(HttpContext context)
  109. {
  110. //// 忽略跨域选项请求。
  111. //if (context.Request.HttpMethod.ToLower() == "options") return;
  112. //// 阻止浏览器请求网站图标。
  113. //if (context.Request.Url.AbsolutePath.ToLower().StartsWith("/favicon.ico")) return;
  114. //// 阻止搜索引擎收录。
  115. //if (context.Request.Url.AbsolutePath.ToLower().StartsWith("/robot.txt"))
  116. //{
  117. // context.Response.ContentType = "text/plain";
  118. // context.Response.Write("User-agent: *\nDisallow: / \n");
  119. // return;
  120. //}
  121. Initialize(_before);
  122. ApiInvoker.IIS(context);
  123. }
  124. #endregion
  125. #region IHttpModule
  126. /// <summary></summary>
  127. public void Dispose() { }
  128. /// <summary></summary>
  129. public void Init(HttpApplication context)
  130. {
  131. context.PreSendRequestHeaders += (s, e) =>
  132. {
  133. var context = HttpContext.Current;
  134. if (context == null) return;
  135. if (ApiOptions.RemoveResponseServer) WebUtility.RemoveServer(context.Response);
  136. };
  137. }
  138. #endregion
  139. }
  140. #endif
  141. }