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.

186 lines
5.0 KiB

4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
3 years ago
4 years ago
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.Net;
  4. using System.Text;
  5. #if NETFX
  6. using System.Web;
  7. #endif
  8. namespace Apewer.Web
  9. {
  10. /// <summary></summary>
  11. public partial class ApiProgram
  12. {
  13. private static ApiInvoker _invoker = new ApiInvoker() { Logger = new Logger(), Options = new ApiOptions() };
  14. /// <summary>调用器。</summary>
  15. public static ApiInvoker Invoker { get => _invoker; }
  16. /// <summary>API 选项。</summary>
  17. public static ApiOptions Options { get => _invoker.Options; }
  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. public static string Listener(string prefix)
  33. {
  34. if (_listener != null) return "无法重复启动默认 Listener 实例。";
  35. _listener = new HttpListener();
  36. _listener.Prefix = prefix;
  37. _listener.Action = (context) => _invoker.Invoke(new HttpListenerProvider(context));
  38. var exception = _listener.Start();
  39. if (exception != null) return exception.Message();
  40. return null;
  41. }
  42. }
  43. // Mini
  44. public partial class ApiProgram
  45. {
  46. static MiniServer _mini = null;
  47. /// <summary>启动 Mini 服务器,返回错误消息。</summary>
  48. public static string Mini(IPEndPoint endpoint, bool await = true)
  49. {
  50. if (endpoint == null) throw new ArgumentNullException(nameof(endpoint));
  51. if (_mini != null) return "无法重复启动实例。";
  52. _mini = new MiniServer();
  53. _mini.Handler = context => _invoker.Invoke(new MiniProvider(context));
  54. _mini.Run(endpoint, await);
  55. return null;
  56. }
  57. /// <summary>启动 Mini 服务器,返回错误消息。</summary>
  58. public static string Mini(int port = 80, bool await = true) => Mini(new IPEndPoint(IPAddress.Any, port));
  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. public override bool UseCompression => Options == null ? false : Options.AllowCompression;
  73. }
  74. /// <summary>启动 Kestrel 服务器。</summary>
  75. public static void Kestrel(int port = 80)
  76. {
  77. if (_aspnetcore != null) return;
  78. var server = new KestrelServer();
  79. server.Port = port;
  80. server.Run<Startup>();
  81. _aspnetcore = server;
  82. }
  83. /// <summary>启动 HTTP.sys 服务器。</summary>
  84. public static void HttpSys(int port = 80, string ip = null)
  85. {
  86. if (_aspnetcore != null) return;
  87. var server = new HttpSysServer();
  88. server.Port = port;
  89. server.Run<Startup>();
  90. _aspnetcore = server;
  91. }
  92. }
  93. #endif
  94. #if NETFX
  95. // IIS
  96. public partial class ApiProgram : IHttpHandler, IHttpModule
  97. {
  98. #region IHttpHandler
  99. static bool _initialized = false;
  100. /// <summary></summary>
  101. public bool IsReusable { get { return false; } }
  102. /// <summary></summary>
  103. public void ProcessRequest(HttpContext context)
  104. {
  105. if (!_initialized)
  106. {
  107. _initialized = true;
  108. _initializer?.Invoke();
  109. }
  110. _invoker.Invoke(new WebsiteProvider(context));
  111. }
  112. #endregion
  113. #region IHttpModule
  114. /// <summary></summary>
  115. public void Dispose() { }
  116. /// <summary></summary>
  117. public void Init(HttpApplication application)
  118. {
  119. application.PreSendRequestHeaders += (s, e) =>
  120. {
  121. // 从 Response 头中移除 Server 和 X-Powered-By 属性。
  122. var response = application.Response;
  123. var keys = new List<string>(response.Headers.AllKeys);
  124. if (keys.Contains("Server")) response.Headers.Remove("Server");
  125. if (keys.Contains("X-Powered-By")) response.Headers.Remove("X-Powered-By");
  126. };
  127. }
  128. IAsyncResult BeginEventHandler(object sender, EventArgs e, AsyncCallback cb, object extraData)
  129. {
  130. return null;
  131. }
  132. void EndEventHandler(IAsyncResult ar)
  133. {
  134. }
  135. #endregion
  136. }
  137. #endif
  138. }