使用
Dictionary<string, string> routes = new Dictionary<string, string> {
{"/index","IndexController"},
};
MyHttpServer httpServer;
httpServer = new MyHttpServer(routes);
httpServer.respNotice += dataHandle;
httpServer.Start(12333);
public void dataHandle(Dictionary<string, string> data, HttpListenerResponse resp, string route = "", string request_type = "get")
{
string controller = routes.ContainsKey(route) ? routes[route] : "";
Dictionary<string, string> resp_data = new Dictionary<string, string>();
resp_data.Add("code", "1");
resp_data.Add("data", "");
resp_data.Add("time", "12345");
resp_data.Add("msg", "ok ");
switch (controller)
{
case "IndexController":
resp_json = JsonConvert.SerializeObject(resp_data);
httpServer.responData(resp_json, resp);
break;
default:
httpServer.responData("404", resp);
break;
}
}
MyHttpServer.cs
using HttpListenerPost;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace PaddleOcrService.request.myhttp
{
public class MyHttpServer
{
public delegate void respNoticeDelegate(Dictionary<string, string> data, HttpListenerResponse resp,string route,string request_type = "get");
public event respNoticeDelegate respNotice;
private HttpListener listener = new HttpListener();
private Dictionary<string, string> actionDict = new Dictionary<string, string>();
private ReturnDataBase respObj;
public string curr_path = "";
public Dictionary<string, string> data_rec = new Dictionary<string, string>();
public MyHttpServer(Dictionary<string,string> routes = null)
{
if(routes != null)
{
foreach (KeyValuePair<string, string> kvp in routes)
{
AddPrefixes(kvp.Key, kvp.Value);
}
}
}
public void AddPrefixes(string url, string action)
{
actionDict.Add(url, action);
}
public void close()
{
listener.Stop();
}
public void Start(int port)
{
if (!HttpListener.IsSupported)
{
Console.WriteLine("无法在当前系统上运行服务(Windows XP SP2 or Server 2003)。" + DateTime.Now.ToString());
return;
}
if (actionDict.Count <= 0)
{
System.Console.WriteLine("没有监听端口");
}
foreach (var item in actionDict)
{
var url = string.Format("http://127.0.0.1:{0}{1}", port, item.Key + "/");
System.Console.WriteLine(url);
listener.Prefixes.Add(url);
}
listener.Start();
listener.BeginGetContext(Result, null);
respObj = new ReturnDataBase();
System.Console.WriteLine("开始监听");
System.Console.Read();
}
private void Result(IAsyncResult asy)
{
if (!listener.IsListening) return;
listener.BeginGetContext(Result, null);
var context = listener.EndGetContext(asy);
var req = context.Request;
var rsp = context.Response;
string route=HandlerReq(req.RawUrl);
Dictionary<string, string> data = new Dictionary<string, string>();
data= HandleHttpMethod(context,rsp,route);
dataNoticeEvent(data,rsp, route, context.Request.HttpMethod);
}
public string responData(string content,HttpListenerResponse rsp)
{
try
{
using (var stream = rsp.OutputStream)
{
rsp.StatusCode = 200;
rsp.ContentType = "text/html;charset=UTF-8";
rsp.AddHeader("Content-type", "application/json");
rsp.ContentEncoding = Encoding.UTF8;
rsp.AppendHeader("Access-Control-Allow-Origin", "*");
rsp.AppendHeader("Access-Control-Allow-Credentials", "true");
rsp.AppendHeader("Access-Control-Allow-Headers", "Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,X-Requested-With");
rsp.AppendHeader("Access-Control-Max-Age", "86400");
byte[] dataByte = Encoding.UTF8.GetBytes(content);
stream.Write(dataByte, 0, dataByte.Length);
stream.Close();
}
}
catch (Exception e)
{
rsp.Close();
return e.Message;
}
rsp.Close();
return "";
}
private string HandlerReq(string url)
{
try
{
System.Console.WriteLine("url : " + url);
string[] arr_str= url.Split('?');
if(arr_str.Length > 0)
{
return curr_path = arr_str[0];
}
return "";
}
catch (Exception e)
{
return "";
}
}
private Dictionary<string,string> HandleHttpMethod(HttpListenerContext context, HttpListenerResponse resp,string route)
{
Dictionary<string, string> return_data = new Dictionary<string, string>();
data_rec.Clear();
string contentType = context.Request.ContentType == null ? "" : context.Request.ContentType;
if (contentType.Contains("multipart/form-data") )
{
HttpListenerPostParaHelper parse = new HttpListenerPostParaHelper(context);
List<HttpListenerPostValue> list = parse.GetHttpListenerPostValue();
;
foreach (HttpListenerPostValue item in list)
{
string k = item.name;
string value = "";
if (item.type == 0)
{
value = Encoding.UTF8.GetString(item.datas).Replace("\r\n", "");
}
else
{
File.WriteAllBytes(@"D:\test.png", item.datas);
value = @"D:\test.png";
}
dataRecAdd(k,value);
}
return_data = data_rec;
return return_data;
}
if (contentType.Contains("application/json"))
{
try
{
Stream stream = context.Request.InputStream;
StreamReader reader = new StreamReader(stream, Encoding.UTF8);
string json = reader.ReadToEnd();
Dictionary<string, string> DicContent = new Dictionary<string, string>();
if (string.IsNullOrEmpty(json)) return return_data ;
if (json == "[]" || json == "") return return_data;
data_rec = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
return_data = data_rec;
}
catch (Exception ex)
{
return return_data;
}
return return_data;
}
switch (context.Request.HttpMethod)
{
case "GET":
var data = context.Request.QueryString;
string url = context.Request.Url.ToString();
string[] pars = url.Split('?');
string content = "";
if (pars.Length == 0)
{
return return_data;
}
if (pars.Length <= 1) return return_data;
string canshus = pars[1];
if (canshus.Length > 0)
{
string[] canshu = canshus.Split('&');
foreach (string i in canshu)
{
string[] messages = i.Split('=');
dataRecAdd(messages[0], messages[1]);
}
return_data = data_rec;
}
return return_data;
break;
}
return return_data;
}
public void dataNoticeEvent(Dictionary<string, string> data,HttpListenerResponse rsp,string route, string method = "unkonwn")
{
respNotice?.Invoke(data, rsp, route, method);
}
public void dataRecAdd(string k ,string v)
{
if (data_rec.ContainsKey(k))
{
data_rec[k] = v;
}
else
{
data_rec.Add(k, v);
}
}
}
class ReturnDataBase
{
public string GetDataMain(string class_method, Dictionary<string, string> rec_data)
{
string[] class_arr = class_method.Split('.');
string class_name,method;
if (class_arr.Length == 1) class_name = class_arr[0];
if (class_arr.Length == 2) method = class_arr[1];
if (class_arr.Length == 0) return "";
return "cesh";
}
}
}
HttpListenerPostValue.cs
这个类主要用于解析content-type为multipart/form-data时解析数据
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace HttpListenerPost
{
public class HttpListenerPostValue
{
public int type = 0;
public string name;
public byte[] datas;
}
public class HttpListenerPostParaHelper
{
private HttpListenerContext request;
public HttpListenerPostParaHelper(HttpListenerContext request)
{
this.request = request;
}
private bool CompareBytes(byte[] source, byte[] comparison)
{
try
{
int count = source.Length;
if (source.Length != comparison.Length)
return false;
for (int i = 0; i < count; i++)
if (source[i] != comparison[i])
return false;
return true;
}
catch
{
return false;
}
}
private byte[] ReadLineAsBytes(Stream SourceStream)
{
var resultStream = new MemoryStream();
while (true)
{
int data = SourceStream.ReadByte();
resultStream.WriteByte((byte)data);
if (data == 10)
break;
}
resultStream.Position = 0;
byte[] dataBytes = new byte[resultStream.Length];
resultStream.Read(dataBytes, 0, dataBytes.Length);
return dataBytes;
}
public List<HttpListenerPostValue> GetHttpListenerPostValue()
{
try
{
List<HttpListenerPostValue> HttpListenerPostValueList = new List<HttpListenerPostValue>();
if (request.Request.ContentType.Length > 20 && string.Compare(request.Request.ContentType.Substring(0, 20), "multipart/form-data;", true) == 0)
{
string[] HttpListenerPostValue = request.Request.ContentType.Split(';').Skip(1).ToArray();
string boundary = string.Join(";", HttpListenerPostValue).Replace("boundary=", "").Trim();
byte[] ChunkBoundary = Encoding.UTF8.GetBytes("--" + boundary + "\r\n");
byte[] EndBoundary = Encoding.UTF8.GetBytes("--" + boundary + "--\r\n");
Stream SourceStream = request.Request.InputStream;
var resultStream = new MemoryStream();
bool CanMoveNext = true;
HttpListenerPostValue data = null;
while (CanMoveNext)
{
byte[] currentChunk = ReadLineAsBytes(SourceStream);
if (!Encoding.UTF8.GetString(currentChunk).Equals("\r\n"))
resultStream.Write(currentChunk, 0, currentChunk.Length);
if (CompareBytes(ChunkBoundary, currentChunk))
{
byte[] result = new byte[resultStream.Length - ChunkBoundary.Length];
resultStream.Position = 0;
resultStream.Read(result, 0, result.Length);
CanMoveNext = true;
if (result.Length > 0)
data.datas = result;
data = new HttpListenerPostValue();
HttpListenerPostValueList.Add(data);
resultStream.Dispose();
resultStream = new MemoryStream();
}
else if (Encoding.UTF8.GetString(currentChunk).Contains("Content-Disposition"))
{
byte[] result = new byte[resultStream.Length - 2];
resultStream.Position = 0;
resultStream.Read(result, 0, result.Length);
CanMoveNext = true;
data.name = Encoding.UTF8.GetString(result).Replace("Content-Disposition: form-data; name=\"", "").Replace("\"", "").Split(';')[0];
resultStream.Dispose();
resultStream = new MemoryStream();
}
else if (Encoding.UTF8.GetString(currentChunk).Contains("Content-Type"))
{
CanMoveNext = true;
data.type = 1;
resultStream.Dispose();
resultStream = new MemoryStream();
}
else if (CompareBytes(EndBoundary, currentChunk))
{
byte[] result = new byte[resultStream.Length - EndBoundary.Length - 2];
resultStream.Position = 0;
resultStream.Read(result, 0, result.Length);
data.datas = result;
resultStream.Dispose();
CanMoveNext = false;
}
}
}
return HttpListenerPostValueList;
}
catch (Exception ex)
{
return null;
}
}
}
}
|