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
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
|
|
|
|
}
|
|
|