using DaJiaoYan.Utils;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web;
namespace DaJiaoYan.Services
{
public class HttpHandler
{
public readonly AsyncHttpServer HttpServer;
public readonly string path;
private ResponseData DefaultResponse = new ResponseData { Code = 405 };
public HttpHandler(AsyncHttpServer httpServer, string path = null)
{
HttpServer = httpServer;
this.path = path;
}
public virtual void Get(HttpListenerRequest request, HttpListenerResponse response)
{
//StaticFile(request, ref response, (HttpListenerRequest req, HttpListenerResponse rep) =>
//{
// Json(ref rep, ref DefaultResponse);
//});
Json(ref response, ref DefaultResponse);
}
public virtual void Post(HttpListenerRequest request, HttpListenerResponse response)
{
Json(ref response, ref DefaultResponse);
}
public virtual void Patch(HttpListenerRequest request, HttpListenerResponse response)
{
Json(ref response, ref DefaultResponse);
}
public virtual void Put(HttpListenerRequest request, HttpListenerResponse response)
{
Json(ref response, ref DefaultResponse);
}
public virtual void Delete(HttpListenerRequest request, HttpListenerResponse response)
{
Json(ref response, ref DefaultResponse);
}
///
/// 输出数据
///
///
///
public virtual void Response(ref HttpListenerResponse response, ref byte[] bytes)
{
if (bytes != null)
{
using (var stream = response.OutputStream)
{
///获取数据,要返回给接口的
try
{
stream.Write(bytes, 0, bytes.Length);
}
catch { }
}
}
response.Close();
}
///
/// 响应Json格式数据
///
///
///
public virtual void Json(ref HttpListenerResponse response, ref ResponseData result)
{
response.AddHeader("Content-type", "application/json");//添加响应头信息
response.AddHeader("Cache-Control", "no-cache, no-store, must-revalidate");
response.AddHeader("Pragma", "no-cache");
response.AddHeader("Expires", "0");
response.StatusCode = result.Code;
//response.ContentType = "text/plain;charset=UTF-8";//告诉客户端返回的ContentType类型为纯文本格式,编码为UTF-8
response.ContentEncoding = Encoding.UTF8;
//string d = YxqService.Utils.Json.Encode(result);
var data = Encoding.UTF8.GetBytes(Utils.Json.Encode(result));
Response(ref response, ref data);
}
}
///
/// 响应数据格式
///
public struct ResponseData
{
[JsonProperty(PropertyName = "code")]
public int Code { get; set; }
[JsonProperty(PropertyName = "msg")]
public object Msg { get; set; }
[JsonProperty(PropertyName = "errors")]
public object Errors { get; set; }
[JsonProperty(PropertyName = "data")]
public object Data { get; set; }
}
public class AsyncHttpServer
{
private readonly HttpListener _listener;
private bool _isRunning;
///
/// 中间件方法
///
///
///
///
///
public delegate bool Middleware(HttpListenerRequest request, HttpListenerResponse response);
///
/// 接口方法
///
///
///
public delegate void HttpHandle(HttpListenerRequest request, HttpListenerResponse response);
///
/// 中间件数组
///
private readonly List MiddleWares = new List();
///
/// 路由字典
///
private readonly Dictionary Prefixes = new Dictionary();
///
/// 默认接口
///
private readonly HttpHandler DefaultHandler;
public readonly string Root;
public readonly int Port;
public readonly string Host;
public readonly string Scheme;
///
/// 监听地址
///
public readonly string Listener;
public AsyncHttpServer(string root, string host = "127.0.0.1", int port = 7000, string scheme = "http")
{
this.Root = root;
DefaultHandler = new HttpHandler(this, root);
this.Port = port;
this.Host = host;
this.Scheme = scheme;
Listener = $"{scheme}://{host}:{port}/";
_listener = new HttpListener();
_listener.Prefixes.Add(Listener);
Prefixes.Add("", DefaultHandler);
}
///
/// 注册中间件
///
///
public void RegisterMiddleware(Middleware func)
{
MiddleWares.Add(func);
}
public void RegisterPrefix(string prefix, HttpHandler handler)
{
Prefixes.Add(prefix, handler);
}
public async Task StartAsync()
{
_isRunning = true;
_listener.Start();
Console.WriteLine($"Server started on {string.Join(", ", _listener.Prefixes)}");
try
{
while (_isRunning)
{
var context = await _listener.GetContextAsync();
_ = Task.Factory.StartNew(() => ProcessRequest(context));
}
}
catch (Exception ex)
{
Console.WriteLine($"Server error: {ex.Message}");
}
}
public void Stop()
{
_isRunning = false;
_listener.Stop();
_listener.Close();
Console.WriteLine("Server stopped");
}
private bool ProcessMiddlewares(HttpListenerContext context)
{
bool res = true;
// 中间件处理
foreach (var mw in MiddleWares)
{
if (!mw(context.Request, context.Response))
{
context.Response.Close();
res = false;
break;
}
}
return res;
}
private void ProcessRequest(HttpListenerContext context)
{
if (!ProcessMiddlewares(context))
{
return;
}
var request = context.Request;
var response = context.Response;
try
{
Prefixes.TryGetValue(request.Url.AbsolutePath, out var r);
if (r == null)
{
Prefixes.TryGetValue("", out r);
}
HttpHandle act;
if (r == null)
{
response.StatusCode = 404;
response.Close();
act = DefaultHandler.Get;
}
else
{
switch (request.HttpMethod.ToUpper())
{
case "POST":
act = r.Post;
break;
case "PUT":
act = r.Put;
break;
case "DELETE":
act = r.Delete;
break;
case "PATCH":
act = r.Patch;
break;
default:
act = r.Get;
break;
}
}
act?.Invoke(request, response);
}
catch (Exception e)
{
Log.WriteLine(e.ToString());
response.StatusCode = 404;
}
finally
{
//response.Close();
}
}
public Dictionary ParseForm(ref HttpListenerRequest request)
{
Dictionary res = new Dictionary();
string content;
using (Stream stream = request.InputStream)
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
{
content = reader.ReadToEnd();
}
if (!string.IsNullOrEmpty(content))
{
foreach (var arg in content.Split('&'))
{
var n = arg.IndexOf('=');
if (n > 0)
{
res[arg.Substring(0, n)] = HttpUtility.UrlDecode(arg.Substring(n + 1));
}
}
}
return res;
}
}
}