using System; using System.Collections.Generic; using System.Text; #if NETFX using System.Web; #endif namespace Apewer.Web { /// <summary></summary> public partial class ApiProgram { private static ApiInvoker _invoker = new ApiInvoker() { Logger = new Logger(), Options = new ApiOptions() }; /// <summary>调用器。</summary> public static ApiInvoker Invoker { get => _invoker; } /// <summary>API 选项。</summary> public static ApiOptions Options { get => _invoker.Options; } /// <summary>日志记录器。</summary> public static Logger Logger { get => _invoker.Logger; } /// <summary>获取或设置 API 入口。</summary> public static ApiEntries Entries { get => _invoker.Entries; set => _invoker.Entries = value; } private Action _initializer = null; /// <summary></summary> public ApiProgram(Action initializer = null) { _initializer = initializer; } } // Listener public partial class ApiProgram { static HttpListener _listener = null; /// <summary>在后台启动 Listener,返回错误消息。</summary> public static string Listener(string prefix) { if (_listener != null) return "无法重复启动默认 Listener 实例。"; _listener = new HttpListener(); _listener.Prefix = prefix; _listener.Action = (context) => _invoker.Invoke(new HttpListenerProvider(context)); var exception = _listener.Start(); if (exception != null) return exception.Message(); return null; } } // Mini public partial class ApiProgram { static MiniServer _mini = null; /// <summary>启动 Mini 服务器,返回错误消息。</summary> public static string Mini(int port = 80, bool await = true) { if (_mini != null) return "无法重复启动实例。"; _mini = new MiniServer(); _mini.Handler = context => _invoker.Invoke(new MiniProvider(context)); _mini.Run(port, await); return null; } } #if NETCORE // Kestrel & HTTP.Sys public partial class ApiProgram { static AspNetCoreServer _aspnetcore = null; class Startup : AspNetCoreStartup { public override void OnContext(Microsoft.AspNetCore.Http.HttpContext context) { if (_invoker == null) return; _invoker.Invoke(new AspNetCoreProvider(context)); } public override bool UseCompression => Options == null ? false : Options.AllowCompression; } /// <summary>启动 Kestrel 服务器。</summary> public static void Kestrel(int port = 80) { if (_aspnetcore != null) return; var server = new KestrelServer(); server.Port = port; server.Run<Startup>(); _aspnetcore = server; } /// <summary>启动 HTTP.sys 服务器。</summary> public static void HttpSys(int port = 80, string ip = null) { if (_aspnetcore != null) return; var server = new HttpSysServer(); server.Port = port; server.Run<Startup>(); _aspnetcore = server; } } #endif #if NETFX // IIS public partial class ApiProgram : IHttpHandler, IHttpModule { #region IHttpHandler static bool _initialized = false; /// <summary></summary> public bool IsReusable { get { return false; } } /// <summary></summary> public void ProcessRequest(HttpContext context) { if (!_initialized) { _initialized = true; _initializer?.Invoke(); } _invoker.Invoke(new WebsiteProvider(context)); } #endregion #region IHttpModule /// <summary></summary> public void Dispose() { } /// <summary></summary> public void Init(HttpApplication application) { application.PreSendRequestHeaders += (s, e) => { // 从 Response 头中移除 Server 和 X-Powered-By 属性。 var response = application.Response; var keys = new List<string>(response.Headers.AllKeys); if (keys.Contains("Server")) response.Headers.Remove("Server"); if (keys.Contains("X-Powered-By")) response.Headers.Remove("X-Powered-By"); }; } IAsyncResult BeginEventHandler(object sender, EventArgs e, AsyncCallback cb, object extraData) { return null; } void EndEventHandler(IAsyncResult ar) { } #endregion } #endif }