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

using Apewer.Network;
using System;
using System.Collections.Generic;
using System.Text;
#if NETFX
using System.Web;
using System.Windows.Forms;
#endif
#if NETCORE
using Microsoft.AspNetCore.Http;
using System.Windows.Forms;
#endif
namespace Apewer.Web
{
/// <summary></summary>
public partial class ApiProgram
{
#if NETFX || NETCORE
/// <summary>在当前线程运行标准应用程序消息循环。</summary>
protected static void RunMessageLoop() => Application.Run();
#endif
}
// Listener
public partial class ApiProgram
{
/// <summary>在后台启动 Listener,返回错误消息。</summary>
/// <param name="port">监听的端口。</param>
/// <param name="before">启动 API 解析前执行。</param>
/// <param name="after">启动 Listener 后执行。</param>
public static string Listener(string ip, int port = 80, Action before = null, Action after = null)
{
before?.Invoke();
var server = new Listener();
server.IP = ip;
server.Port = port;
server.Action = (context) => ApiInvoker.Listener(context);
var exception = server.Start();
if (exception != null) return exception.Message;
after?.Invoke();
return null;
}
}
#if NETCORE
// Kestrel & HTTP.Sys
public partial class ApiProgram
{
/// <summary>异步启动 Kestrel,返回错误消息。</summary>
/// <param name="port">监听的端口。</param>
/// <param name="before">启动 API 解析前执行。</param>
/// <param name="after">启动 Listener 后执行。</param>
public static string Kestrel(int port = 80, Action before = null, Action after = null)
{
before?.Invoke();
var instance = new AspNetCore();
instance.Context = (context) => ApiInvoker.AspNetCore(context);
instance.Port = port;
var error = instance.RunKestrel(true);
if (!string.IsNullOrEmpty(error)) return error;
after?.Invoke();
return null;
}
/// <summary>异步启动基于 HTTP.sys 的服务器,返回错误消息。</summary>
/// <param name="port">监听的端口。</param>
/// <param name="before">启动 API 解析前执行。</param>
/// <param name="after">启动 Listener 后执行。</param>
public static string HttpSys(string ip, int port = 80, Action before = null, Action after = null)
{
before?.Invoke();
var instance = new AspNetCore();
instance.Context = (context) => ApiInvoker.AspNetCore(context);
instance.Port = port;
var error = instance.RunHttpSys(ip, true);
if (!string.IsNullOrEmpty(error)) return error;
after?.Invoke();
return null;
}
}
#endif
#if NETFX
// IIS
public partial class ApiProgram : IHttpHandler, IHttpModule
{
private Action _before = null;
/// <summary>仅运行在 IIS 中时会对此类型创建实例。</summary>
/// <param name="before">执行 API 解析前执行。</param>
public ApiProgram(Action before = null)
{
_before = before;
}
#region Initialize
private static object InitLocker = new object();
private bool _initialized = false;
private void Initialize(Action action)
{
if (_initialized) return;
lock (InitLocker)
{
if (_initialized) return;
action?.Invoke();
_initialized = true;
}
}
#endregion
#region IHttpHandler
/// <summary></summary>
public bool IsReusable { get { return false; } }
/// <summary></summary>
public void ProcessRequest(HttpContext context)
{
//// 忽略跨域选项请求。
//if (context.Request.HttpMethod.ToLower() == "options") return;
//// 阻止浏览器请求网站图标。
//if (context.Request.Url.AbsolutePath.ToLower().StartsWith("/favicon.ico")) return;
//// 阻止搜索引擎收录。
//if (context.Request.Url.AbsolutePath.ToLower().StartsWith("/robot.txt"))
//{
// context.Response.ContentType = "text/plain";
// context.Response.Write("User-agent: *\nDisallow: / \n");
// return;
//}
Initialize(_before);
ApiInvoker.IIS(context);
}
#endregion
#region IHttpModule
/// <summary></summary>
public void Dispose() { }
/// <summary></summary>
public void Init(HttpApplication context)
{
context.PreSendRequestHeaders += (s, e) =>
{
var context = HttpContext.Current;
if (context == null) return;
if (ApiOptions.RemoveResponseServer) WebUtility.RemoveServer(context.Response);
};
}
#endregion
}
#endif
}