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.

176 lines
4.8 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. #if NETFX
  5. using System.Web;
  6. #endif
  7. namespace Apewer.Web
  8. {
  9. /// <summary></summary>
  10. public partial class ApiProgram
  11. {
  12. /// <summary>调用器。</summary>
  13. private static ApiInvoker _invoker = new ApiInvoker() { Logger = new Logger(), Options = new ApiOptions() };
  14. /// <summary>API 选项。</summary>
  15. public static ApiOptions Options { get => _invoker.Options; }
  16. /// <summary>日志记录器。</summary>
  17. public static Logger Logger { get => _invoker.Logger; }
  18. /// <summary>获取或设置 API 入口。</summary>
  19. public static ApiEntries Entries { get => _invoker.Entries; set => _invoker.Entries = value; }
  20. private Action _initializer = null;
  21. /// <summary></summary>
  22. public ApiProgram(Action initializer = null)
  23. {
  24. _initializer = initializer;
  25. }
  26. }
  27. // Listener
  28. public partial class ApiProgram
  29. {
  30. static HttpListener _listener = null;
  31. /// <summary>在后台启动 Listener,返回错误消息。</summary>
  32. /// <param name="ip">监听的本地 IP 地址。</param>
  33. /// <param name="port">监听的端口。</param>
  34. public static string Listener(string ip, int port = 80)
  35. {
  36. if (_listener == null) return "无法重复启动默认 Listener 实例。";
  37. var server = new HttpListener();
  38. server.IP = ip;
  39. server.Port = port;
  40. server.Action = (context) => _invoker.Invoke(new HttpListenerProvider(context));
  41. var exception = server.Start();
  42. if (exception != null) return exception.Message;
  43. return null;
  44. }
  45. /// <summary>在后台启动 Listener,返回错误消息。</summary>
  46. /// <param name="ip">监听的本地 IP 地址。</param>
  47. /// <param name="port">监听的端口。</param>
  48. public static string Listener(int port = 80, string ip = "0.0.0.0")
  49. {
  50. if (_listener == null) return "无法重复启动默认 Listener 实例。";
  51. var server = new HttpListener();
  52. server.IP = ip;
  53. server.Port = port;
  54. server.Action = (context) => _invoker.Invoke(new HttpListenerProvider(context));
  55. var exception = server.Start();
  56. if (exception != null) return exception.Message;
  57. return null;
  58. }
  59. }
  60. #if NETCORE
  61. // Kestrel & HTTP.Sys
  62. public partial class ApiProgram
  63. {
  64. static AspNetCoreServer _aspnetcore = null;
  65. class Startup : AspNetCoreStartup
  66. {
  67. public override void OnContext(Microsoft.AspNetCore.Http.HttpContext context)
  68. {
  69. if (_invoker == null) return;
  70. _invoker.Invoke(new AspNetCoreProvider(context));
  71. }
  72. }
  73. /// <summary>启动 Kestrel 服务器。</summary>
  74. public static void Kestrel(int port = 80)
  75. {
  76. if (_aspnetcore != null) return;
  77. var server = new KestrelServer();
  78. server.Port = port;
  79. server.Run<Startup>();
  80. _aspnetcore = server;
  81. }
  82. /// <summary>启动 HTTP.sys 服务器。</summary>
  83. public static void HttpSys(int port = 80, string ip = null)
  84. {
  85. if (_aspnetcore != null) return;
  86. var server = new HttpSysServer();
  87. server.Port = port;
  88. server.Run<Startup>();
  89. _aspnetcore = server;
  90. }
  91. }
  92. #endif
  93. #if NETFX
  94. // IIS
  95. public partial class ApiProgram : IHttpHandler, IHttpModule
  96. {
  97. #region IHttpHandler
  98. /// <summary></summary>
  99. public bool IsReusable { get { return false; } }
  100. /// <summary></summary>
  101. public void ProcessRequest(HttpContext context)
  102. {
  103. _initializer?.Invoke();
  104. _invoker.Invoke(new WebsiteProvider(context));
  105. }
  106. #endregion
  107. #region IHttpModule
  108. /// <summary></summary>
  109. public void Dispose() { }
  110. /// <summary></summary>
  111. public void Init(HttpApplication application)
  112. {
  113. application.PreSendRequestHeaders += (s, e) =>
  114. {
  115. // 从 Response 头中移除 Server 和 X-Powered-By 属性。
  116. var response = application.Response;
  117. var keys = new List<string>(response.Headers.AllKeys);
  118. if (keys.Contains("Server")) response.Headers.Remove("Server");
  119. if (keys.Contains("X-Powered-By")) response.Headers.Remove("X-Powered-By");
  120. };
  121. }
  122. IAsyncResult BeginEventHandler(object sender, EventArgs e, AsyncCallback cb, object extraData)
  123. {
  124. return null;
  125. }
  126. void EndEventHandler(IAsyncResult ar)
  127. {
  128. }
  129. #endregion
  130. }
  131. #endif
  132. }