492 lines
18 KiB
C#
492 lines
18 KiB
C#
using Api.Framework.Events;
|
|
using CsharpHttpHelper;
|
|
using Microsoft.Owin;
|
|
using Microsoft.Owin.Builder;
|
|
using Microsoft.Owin.Cors;
|
|
using Microsoft.Owin.Hosting;
|
|
using Owin;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Specialized;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Net.NetworkInformation;
|
|
using System.Net.Sockets;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading.Tasks;
|
|
using System.Web.Http;
|
|
|
|
[assembly: OwinStartup(typeof(Api.Framework.WebClient))]
|
|
namespace Api.Framework
|
|
{
|
|
/// <summary>
|
|
/// web管理
|
|
/// </summary>
|
|
public class WebClient
|
|
{
|
|
/// <summary>
|
|
/// 响应结果
|
|
/// </summary>
|
|
public class Result
|
|
{
|
|
public int Code { get; set; }
|
|
|
|
public int code { get => Code; }
|
|
|
|
public object Message { get; set; }
|
|
|
|
public object data { get => Message; }
|
|
}
|
|
|
|
public class Util
|
|
{
|
|
/// <summary>
|
|
/// 将查询字符串解析转换为名值集合.
|
|
/// </summary>
|
|
/// <param name="queryString"></param>
|
|
/// <param name="encoding"></param>
|
|
/// <param name="isEncoded"></param>
|
|
/// <returns></returns>
|
|
public static NameValueCollection GetQueryString(string queryString, Encoding encoding)
|
|
{
|
|
queryString = queryString.Replace("?", "");
|
|
NameValueCollection result = new NameValueCollection(StringComparer.OrdinalIgnoreCase);
|
|
if (!string.IsNullOrEmpty(queryString))
|
|
{
|
|
int count = queryString.Length;
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
int startIndex = i;
|
|
int index = -1;
|
|
while (i < count)
|
|
{
|
|
char item = queryString[i];
|
|
if (item == '=')
|
|
{
|
|
if (index < 0)
|
|
{
|
|
index = i;
|
|
}
|
|
}
|
|
else if (item == '&')
|
|
{
|
|
break;
|
|
}
|
|
i++;
|
|
}
|
|
string key = null;
|
|
string value = null;
|
|
if (index >= 0)
|
|
{
|
|
key = queryString.Substring(startIndex, index - startIndex);
|
|
value = queryString.Substring(index + 1, (i - index) - 1);
|
|
}
|
|
else
|
|
{
|
|
key = queryString.Substring(startIndex, i - startIndex);
|
|
}
|
|
result[key] = value;
|
|
if ((i == (count - 1)) && (queryString[i] == '&'))
|
|
{
|
|
result[key] = string.Empty;
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
}
|
|
|
|
private static IDisposable server = null;
|
|
public static bool IsStart
|
|
{
|
|
get
|
|
{
|
|
if (server == null) return false;
|
|
else return true;
|
|
}
|
|
}
|
|
|
|
public static List<IPAddress> GetNetwork()
|
|
{
|
|
List<IPAddress> list = new List<IPAddress>();
|
|
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
|
|
foreach (NetworkInterface adapter in nics)
|
|
{
|
|
//判断是否为以太网卡
|
|
//Wireless80211 无线网卡 Ppp 宽带连接
|
|
//Ethernet 以太网卡
|
|
//这里篇幅有限贴几个常用的,其他的返回值大家就自己百度吧!
|
|
if (adapter.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
|
|
{
|
|
//获取以太网卡网络接口信息
|
|
IPInterfaceProperties ip = adapter.GetIPProperties();
|
|
//获取单播地址集
|
|
UnicastIPAddressInformationCollection ipCollection = ip.UnicastAddresses;
|
|
foreach (UnicastIPAddressInformation _ip in ipCollection)
|
|
{
|
|
//InterNetwork IPV4地址 InterNetworkV6 IPV6地址
|
|
//Max MAX 位址
|
|
list.Add(_ip.Address);
|
|
}
|
|
}
|
|
}
|
|
|
|
return list;
|
|
}
|
|
public static void Start(string ip, int port, bool throwExcption = true)
|
|
{
|
|
try
|
|
{
|
|
if (server != null) Close();
|
|
|
|
server = WebApp.Start<WebClient>($"http://{ip}:{port}/");
|
|
ApiClient.Setting.ServerConfig.Host = ip;
|
|
ApiClient.Setting.ServerConfig.Port = port;
|
|
Api.Framework.Tools.Util.Save(ApiClient.Setting.ServerConfig);
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
//Console.WriteLine("WebClient Start Error:" + ex.Message);
|
|
if (!throwExcption) return;
|
|
if (ex.InnerException != null)
|
|
{
|
|
var msg = ex.InnerException.Message;
|
|
if (msg.Contains("拒绝访问")) throw new Exception("权限不足,请关闭防火墙,并以管理员方式启动程序!");
|
|
else if (msg.Contains("另一个程序正在使用此文件,进程无法访问。")) throw new Exception("端口号被其他应用占用,请更换端口号!");
|
|
}
|
|
throw new Exception(ex.InnerException.Message);
|
|
}
|
|
}
|
|
|
|
public static void Close()
|
|
{
|
|
if (server != null)
|
|
{
|
|
server.Dispose();
|
|
server = null;
|
|
}
|
|
}
|
|
|
|
//public void Configuration(IAppBuilder app)
|
|
//{
|
|
// // ConfigureAuth(app);
|
|
// try
|
|
// {
|
|
// app.UseCors(CorsOptions.AllowAll);
|
|
|
|
// app.Use(async (context, next) =>
|
|
// {
|
|
// var respose = new Result();
|
|
// //是否已经处理
|
|
// try
|
|
// {
|
|
// bool is_handle = false;
|
|
// Dictionary<string, string> Param = new Dictionary<string, string>();
|
|
// var contentType = context.Request.ContentType;
|
|
// if (context.Request.Method.ToLower() == "post")
|
|
// {
|
|
// if (contentType.StartsWith("application/x-www-form-urlencoded", StringComparison.OrdinalIgnoreCase))
|
|
// {
|
|
// string body = new StreamReader(context.Request.Body, Encoding.UTF8).ReadToEnd();
|
|
// var postdata = Util.GetQueryString(body, Encoding.UTF8);
|
|
// if (postdata != null)
|
|
// {
|
|
// foreach (var item in postdata.AllKeys)
|
|
// {
|
|
// Param[item] = postdata[item];
|
|
// }
|
|
//}
|
|
// }
|
|
// }
|
|
// if (context.Request.Query != null && context.Request.Query.Count() > 0)
|
|
// {
|
|
// foreach (var item in context.Request.Query)
|
|
// {
|
|
// if (item.Value != null && item.Value.Length > 0) Param[item.Key] = item.Value[0];
|
|
// }
|
|
// }
|
|
|
|
// if (EventClient.StopParsing) return;
|
|
// var plugins = PluginClient.Plugins.ToArray();
|
|
//var events = new WebRequestEvents(context, Param, respose);
|
|
// //正常事件解析
|
|
// foreach (var plugin in plugins)
|
|
// {
|
|
// if (!plugin.IsRun) continue;//未运行
|
|
// if (events.Cancel) break;//已取消传递
|
|
// plugin.SDK.OnEvent(context, events);
|
|
// }
|
|
// }
|
|
// catch (Exception ex)
|
|
// {
|
|
// respose.Code = -1;
|
|
// respose.Message = ex.Message;
|
|
// }
|
|
// finally
|
|
// {
|
|
// if (respose.Message == null)
|
|
// {
|
|
// respose.Code = -1;
|
|
// respose.Message = $"请求成功,但未响应结果!{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}";
|
|
// }
|
|
// var msg = HttpHelper.ObjectToJson(respose);
|
|
//context.Response.StatusCode = (int) HttpStatusCode.OK;
|
|
//context.Response.Write(msg);
|
|
// }
|
|
|
|
// await next();
|
|
// });
|
|
|
|
|
|
// //app.Map("/api", map =>
|
|
// //{
|
|
// // map.Use(async (context, next) =>
|
|
// // {
|
|
|
|
// // System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
|
|
// // sw.Start();
|
|
// // context.Response.StatusCode = 200;
|
|
// // Uri uri = context.Request.Uri;
|
|
// // string ip = "未知IP";
|
|
// // try
|
|
// // {
|
|
|
|
// // switch (uri.AbsolutePath.ToLower())
|
|
// // {
|
|
// // case "/api":
|
|
// // {
|
|
|
|
// // break;
|
|
// // }
|
|
// // break;
|
|
// // default:
|
|
// // {
|
|
|
|
// // context.Response.StatusCode = 404;
|
|
// // }
|
|
// // break;
|
|
// // }
|
|
// // ip = context.Request.RemoteIpAddress;
|
|
// // }
|
|
// // catch (Exception e)
|
|
// // {
|
|
// // context.Response.StatusCode = 500;
|
|
// // context.Response.Write("<h1>" + e.Message + "</h1>" + e.StackTrace);
|
|
// // EventClient.OnEvent(this,"【WebAPI处理请求出错】" + e.Message);
|
|
// // }
|
|
// // finally
|
|
// // {
|
|
|
|
// // }
|
|
// // sw.Stop();
|
|
// // TimeSpan ts = sw.Elapsed;
|
|
// // // Library.LogHelper.Log("【" + ts.TotalMilliseconds + "】【"+ip+"】" + uri.PathAndQuery, 90);
|
|
// // await next();
|
|
// // });
|
|
|
|
// //});
|
|
|
|
// }
|
|
// catch (Exception ex)
|
|
// {
|
|
|
|
// throw;
|
|
// }
|
|
//}
|
|
|
|
#region 路由器初始化
|
|
|
|
/// <summary>
|
|
/// 默认
|
|
/// </summary>
|
|
private static string _siteDir = Directory.GetCurrentDirectory() + "\\wwwroot";
|
|
|
|
/// <summary>
|
|
/// 配置管理器
|
|
/// </summary>
|
|
/// <param name="app"></param>
|
|
public void Configuration(IAppBuilder app)
|
|
{
|
|
app.UseCors(CorsOptions.AllowAll);
|
|
app.Use((context, fun) =>
|
|
{
|
|
return RequestHandler(context, fun);
|
|
});
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// 挂载静态数据
|
|
/// </summary>
|
|
/// <param name="context"></param>
|
|
/// <param name="next"></param>
|
|
/// <returns></returns>
|
|
public async Task RequestHandler(IOwinContext context, Func<Task> next)
|
|
{
|
|
try
|
|
{
|
|
var path = GetFilePath(context.Request.Path.Value);
|
|
|
|
if (File.Exists(path))
|
|
{
|
|
//Console.WriteLine(path);
|
|
await SetResponse(context, path);
|
|
}
|
|
else
|
|
{
|
|
await TodoApi(context, next);
|
|
}
|
|
}
|
|
catch (Exception)
|
|
{
|
|
}
|
|
await next();
|
|
}
|
|
|
|
private Task TodoApi(IOwinContext context, Func<Task> next)
|
|
{
|
|
var respose = new Result();
|
|
try
|
|
{
|
|
bool is_handle = false;
|
|
Dictionary<string, string> Param = new Dictionary<string, string>();
|
|
var contentType = context.Request.ContentType;
|
|
if (context.Request.Method.ToLower() == "post")
|
|
{
|
|
//Console.WriteLine(contentType);
|
|
if (contentType.StartsWith("application/x-www-form-urlencoded", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
string body = new StreamReader(context.Request.Body, Encoding.UTF8).ReadToEnd();
|
|
var postdata = Util.GetQueryString(body, Encoding.UTF8);
|
|
if (postdata != null)
|
|
{
|
|
foreach (var item in postdata.AllKeys)
|
|
{
|
|
Param[item] = HttpHelper.URLDecode(postdata[item]);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if (context.Request.Query != null && context.Request.Query.Count() > 0)
|
|
{
|
|
foreach (var item in context.Request.Query)
|
|
{
|
|
if (item.Value != null && item.Value.Length > 0) Param[item.Key] = HttpHelper.URLDecode(item.Value[0]);
|
|
}
|
|
}
|
|
|
|
if (EventClient.StopParsing) return next();
|
|
var plugins = PluginClient.Plugins.ToArray();
|
|
var events = new WebRequestEvents(context, Param, respose);
|
|
//正常事件解析
|
|
foreach (var plugin in plugins)
|
|
{
|
|
if (!plugin.IsRun) continue;//未运行
|
|
if (events.Cancel) break;//已取消传递
|
|
plugin.SDK.OnEvent(context, events);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
respose.Code = -1;
|
|
respose.Message = ex.Message;
|
|
}
|
|
|
|
if (respose.Message == null)
|
|
{
|
|
respose.Code = -1;
|
|
respose.Message = $"请求成功,但未响应结果!{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}";
|
|
}
|
|
var msg = HttpHelper.ObjectToJson(respose);
|
|
context.Response.StatusCode = (int)HttpStatusCode.OK;
|
|
return context.Response.WriteAsync(msg);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 查找本地数据,无数据 返回index
|
|
/// </summary>
|
|
/// <param name="relPath"></param>
|
|
/// <returns></returns>
|
|
public static string GetFilePath(string relPath)
|
|
{
|
|
if (string.IsNullOrEmpty(relPath) || relPath == "/")
|
|
{
|
|
relPath = "index.html";
|
|
}
|
|
|
|
return Path.Combine(
|
|
AppDomain.CurrentDomain.BaseDirectory
|
|
, _siteDir
|
|
, relPath.TrimStart('/').Replace('/', '\\'));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置返回contenttype 并返回数据
|
|
/// </summary>
|
|
/// <param name="context"></param>
|
|
/// <param name="path"></param>
|
|
/// <returns></returns>
|
|
public Task SetResponse(IOwinContext context, string path)
|
|
{
|
|
var perfix = Path.GetExtension(path);
|
|
if (perfix == ".html")
|
|
{
|
|
context.Response.ContentType = "text/html; charset=utf-8";
|
|
return context.Response.WriteAsync(File.ReadAllText(path));
|
|
}
|
|
else if (perfix == ".js")
|
|
{
|
|
context.Response.ContentType = "application/x-javascript";
|
|
return context.Response.WriteAsync(File.ReadAllText(path));
|
|
}
|
|
else if (perfix == ".css")
|
|
{
|
|
context.Response.ContentType = "text/css";
|
|
return context.Response.WriteAsync(File.ReadAllText(path));
|
|
}
|
|
else if (perfix == ".jpg" || perfix == ".jpeg")
|
|
{
|
|
context.Response.ContentType = "image/jpeg";
|
|
return context.Response.WriteAsync(File.ReadAllBytes(path));
|
|
}
|
|
else if (perfix == ".png")
|
|
{
|
|
context.Response.ContentType = "application/x-png";
|
|
return context.Response.WriteAsync(File.ReadAllBytes(path));
|
|
}
|
|
else if (perfix == ".mp4")
|
|
{
|
|
context.Response.ContentType = "video/mpeg4";
|
|
return context.Response.WriteAsync(File.ReadAllBytes(path));
|
|
}
|
|
else if (perfix == ".webp")
|
|
{
|
|
context.Response.ContentType = "image/webp";
|
|
return context.Response.WriteAsync(File.ReadAllBytes(path));
|
|
}
|
|
else if (perfix == ".gif")
|
|
{
|
|
context.Response.ContentType = "image/gif";
|
|
return context.Response.WriteAsync(File.ReadAllBytes(path));
|
|
}
|
|
else if (perfix == ".woff2")
|
|
{
|
|
context.Response.ContentType = "application/x-font-woff";
|
|
return context.Response.WriteAsync(File.ReadAllBytes(path));
|
|
}
|
|
|
|
|
|
return context.Response.WriteAsync(File.ReadAllText(path));
|
|
}
|
|
#endregion
|
|
|
|
}
|
|
}
|