using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace HPSocketCS
{
public class HttpServer : TcpServer
{
///
/// 【可选】开始解析
///
public event HttpServerEvent.OnMessageBeginEventHandler OnMessageBegin;
///
/// 【可选】请求头通知
///
public event HttpServerEvent.OnHeaderEventHandler OnHeader;
///
/// 【可选】Chunked 报文头通知
///
public event HttpServerEvent.OnChunkHeaderEventHandler OnChunkHeader;
///
/// 【可选】Chunked 报文结束通知
///
public event HttpServerEvent.OnChunkCompleteEventHandler OnChunkComplete;
///
/// 【可选】升级协议通知
///
public event HttpServerEvent.OnUpgradeEventHandler OnUpgrade;
///
/// 【可选】请求行解析完成(仅用于 HTTP 服务端)
///
public event HttpServerEvent.OnRequestLineEventHandler OnRequestLine;
///
/// 【必须】请求头完成通知
///
public event HttpServerEvent.OnHeadersCompleteEventHandler OnHeadersComplete;
///
/// 【必须】请求体报文通知
///
public event HttpServerEvent.OnBodyEventHandler OnBody;
///
/// 【必须】请求体报文通知
///
public event HttpServerEvent.OnPointerDataBodyEventHandler OnPointerDataBody;
///
/// 【必须】完成解析通知
///
public event HttpServerEvent.OnMessageCompleteEventHandler OnMessageComplete;
///
/// 【必须】解析错误通知
///
public event HttpServerEvent.OnParseErrorEventHandler OnParseError;
///
/// 创建socket监听&服务组件
///
///
protected override bool CreateListener()
{
if (IsCreate == true || pListener != IntPtr.Zero || pServer != IntPtr.Zero)
{
return false;
}
pListener = HttpSdk.Create_HP_HttpServerListener();
if (pListener == IntPtr.Zero)
{
return false;
}
pServer = HttpSdk.Create_HP_HttpServer(pListener);
if (pServer == IntPtr.Zero)
{
return false;
}
IsCreate = true;
return true;
}
///
/// 终止服务并释放资源
///
public override void Destroy()
{
Stop();
if (pServer != IntPtr.Zero)
{
HttpSdk.Destroy_HP_HttpServer(pServer);
pServer = IntPtr.Zero;
}
if (pListener != IntPtr.Zero)
{
HttpSdk.Destroy_HP_HttpServerListener(pListener);
pListener = IntPtr.Zero;
}
IsCreate = false;
}
HttpSdk.OnMessageBegin _OnMessageBegin;
HttpSdk.OnHeader _OnHeader;
HttpSdk.OnChunkHeader _OnChunkHeader;
HttpSdk.OnChunkComplete _OnChunkComplete;
HttpSdk.OnUpgrade _OnUpgrade;
HttpSdk.OnRequestLine _OnRequestLine;
HttpSdk.OnHeadersComplete _OnHeadersComplete;
HttpSdk.OnBody _OnBody;
HttpSdk.OnMessageComplete _OnMessageComplete;
HttpSdk.OnParseError _OnParseError;
protected override void SetCallback()
{
// 设置tcpserver的callback
_OnPrepareListen = new Sdk.OnPrepareListen(SDK_OnPrepareListen);
_OnAccept = new Sdk.OnAccept(SDK_OnAccept);
_OnSend = new Sdk.OnSend(SDK_OnSend);
_OnReceive = new Sdk.OnReceive(SDK_OnReceive);
_OnClose = new Sdk.OnClose(SDK_OnClose);
_OnShutdown = new Sdk.OnShutdown(SDK_OnShutdown);
_OnHandShake = new Sdk.OnHandShake(SDK_OnHandShake);
HttpSdk.HP_Set_FN_HttpServer_OnPrepareListen(pListener, _OnPrepareListen);
HttpSdk.HP_Set_FN_HttpServer_OnAccept(pListener, _OnAccept);
HttpSdk.HP_Set_FN_HttpServer_OnSend(pListener, _OnSend);
HttpSdk.HP_Set_FN_HttpServer_OnReceive(pListener, _OnReceive);
HttpSdk.HP_Set_FN_HttpServer_OnClose(pListener, _OnClose);
HttpSdk.HP_Set_FN_HttpServer_OnShutdown(pListener, _OnShutdown);
HttpSdk.HP_Set_FN_HttpServer_OnHandShake(pListener, _OnHandShake);
// 设置自身的callback
_OnMessageBegin = new HttpSdk.OnMessageBegin(SDK_OnMessageBegin);
_OnHeader = new HttpSdk.OnHeader(SDK_OnHeader);
_OnChunkHeader = new HttpSdk.OnChunkHeader(SDK_OnChunkHeader);
_OnChunkComplete = new HttpSdk.OnChunkComplete(SDK_OnChunkComplete);
_OnUpgrade = new HttpSdk.OnUpgrade(SDK_OnUpgrade);
_OnRequestLine = new HttpSdk.OnRequestLine(SDK_OnRequestLine);
_OnHeadersComplete = new HttpSdk.OnHeadersComplete(SDK_OnHeadersComplete);
_OnBody = new HttpSdk.OnBody(SDK_OnBody);
_OnMessageComplete = new HttpSdk.OnMessageComplete(SDK_OnMessageComplete);
_OnParseError = new HttpSdk.OnParseError(SDK_OnParseError);
HttpSdk.HP_Set_FN_HttpServer_OnMessageBegin(pListener, _OnMessageBegin);
HttpSdk.HP_Set_FN_HttpServer_OnRequestLine(pListener, _OnRequestLine);
HttpSdk.HP_Set_FN_HttpServer_OnHeader(pListener, _OnHeader);
HttpSdk.HP_Set_FN_HttpServer_OnHeadersComplete(pListener, _OnHeadersComplete);
HttpSdk.HP_Set_FN_HttpServer_OnBody(pListener, _OnBody);
HttpSdk.HP_Set_FN_HttpServer_OnChunkHeader(pListener, _OnChunkHeader);
HttpSdk.HP_Set_FN_HttpServer_OnChunkComplete(pListener, _OnChunkComplete);
HttpSdk.HP_Set_FN_HttpServer_OnMessageComplete(pListener, _OnMessageComplete);
HttpSdk.HP_Set_FN_HttpServer_OnUpgrade(pListener, _OnUpgrade);
HttpSdk.HP_Set_FN_HttpServer_OnParseError(pListener, _OnParseError);
}
protected virtual HttpParseResult SDK_OnParseError(IntPtr pSender, IntPtr connId, int iErrorCode, string lpszErrorDesc)
{
if (OnParseError != null)
{
return OnParseError(connId, iErrorCode, lpszErrorDesc);
}
return HttpParseResult.Ok;
}
protected virtual HttpParseResult SDK_OnMessageComplete(IntPtr pSender, IntPtr connId)
{
if (OnMessageComplete != null)
{
return OnMessageComplete(connId);
}
return HttpParseResult.Ok;
}
protected virtual HttpParseResult SDK_OnBody(IntPtr pSender, IntPtr connId, IntPtr pData, int iLength)
{
if (OnPointerDataBody != null)
{
return OnPointerDataBody(connId, pData, iLength);
}
else if (OnBody != null)
{
byte[] bytes = new byte[iLength];
Marshal.Copy(pData, bytes, 0, iLength);
return OnBody(connId, bytes);
}
return HttpParseResult.Ok;
}
protected virtual HttpParseResultEx SDK_OnHeadersComplete(IntPtr pSender, IntPtr connId)
{
if (OnHeadersComplete != null)
{
return OnHeadersComplete(connId);
}
return HttpParseResultEx.Ok;
}
protected virtual HttpParseResult SDK_OnRequestLine(IntPtr pSender, IntPtr connId, string lpszMethod, string lpszUrl)
{
if (OnRequestLine != null)
{
return OnRequestLine(connId, lpszMethod, lpszUrl);
}
return HttpParseResult.Ok;
}
protected virtual HttpParseResult SDK_OnUpgrade(IntPtr pSender, IntPtr connId, HttpUpgradeType enUpgradeType)
{
if (OnUpgrade != null)
{
return OnUpgrade(connId, enUpgradeType);
}
return HttpParseResult.Ok;
}
protected virtual HttpParseResult SDK_OnChunkComplete(IntPtr pSender, IntPtr connId)
{
if (OnChunkComplete != null)
{
return OnChunkComplete(connId);
}
return HttpParseResult.Ok;
}
protected virtual HttpParseResult SDK_OnChunkHeader(IntPtr pSender, IntPtr connId, int iLength)
{
if (OnChunkHeader != null)
{
return OnChunkHeader(connId, iLength);
}
return HttpParseResult.Ok;
}
protected virtual HttpParseResult SDK_OnHeader(IntPtr pSender, IntPtr connId, string lpszName, string lpszValue)
{
if (OnHeader != null)
{
return OnHeader(connId, lpszName, lpszValue);
}
return HttpParseResult.Ok;
}
protected virtual HttpParseResult SDK_OnMessageBegin(IntPtr pSender, IntPtr connId)
{
if (OnMessageBegin != null)
{
return OnMessageBegin(connId);
}
return HttpParseResult.Ok;
}
/**************************************************************************/
/***************************** Server 操作方法 *****************************/
///
/// 名称:回复请求
/// 描述:向客户端回复 HTTP 请求
///
/// 连接 ID
/// HTTP 状态码
/// HTTP 状态描述
/// 回复请求头
/// 回复请求体
///
public bool SendResponse(IntPtr connId, HttpStatusCode httpStatusCode, string desc, THeader[] headers, byte[] body, int bodyLength)
{
int headersLength = headers == null ? 0 : headers.Length;
return HttpSdk.HP_HttpServer_SendResponse(pServer, connId, (ushort)httpStatusCode, desc, headers, headersLength, body, bodyLength);
}
///
/// 名称:发送本地文件
/// 描述:向指定连接发送 4096 KB 以下的小文件
///
///
///
///
///
///
///
public bool SendLocalFile(IntPtr connId, string fileName, HttpStatusCode httpStatusCode, string desc, THeader[] headers)
{
int headersLength = headers == null ? 0 : headers.Length;
return HttpSdk.HP_HttpServer_SendLocalFile(pServer, connId, fileName, (ushort)httpStatusCode, desc, headers, headersLength);
}
///
/// 名称:释放连接
/// 描述:把连接放入释放队列,等待某个时间(通过 SetReleaseDelay() 设置)关闭连接
///
/// 连接 ID
///
public bool Release(IntPtr connId)
{
return HttpSdk.HP_HttpServer_Release(pServer, connId);
}
///
/// 启动 HTTP 通信, 当通信组件设置为非自动启动 HTTP 通信时,需要调用本方法启动 HTTP 通信
///
///
///
public bool StartHttp(IntPtr connId)
{
return HttpSdk.HP_HttpServer_StartHttp(pServer, connId);
}
/******************************************************************************/
/***************************** Server 属性访问方法 *****************************/
///
/// 获取或设置连接释放延时(默认:3000 毫秒)
///
public uint ReleaseDelay
{
get
{
return HttpSdk.HP_HttpServer_GetReleaseDelay(pServer);
}
set
{
HttpSdk.HP_HttpServer_SetReleaseDelay(pServer, value);
}
}
///
/// 获取请求行 URL 域掩码(URL 域参考:HttpUrlField)
///
///
///
public HttpUrlField GetUrlFieldSet(IntPtr connId)
{
return (HttpUrlField)HttpSdk.HP_HttpServer_GetUrlFieldSet(pServer, connId);
}
///
/// 获取某个 URL 域值
///
///
///
///
public string GetUrlField(IntPtr connId, HttpUrlField enField)
{
IntPtr ptr = HttpSdk.HP_HttpServer_GetUrlField(pServer, connId, enField);
return Common.PtrToAnsiString(ptr);
}
///
/// 获取请求方法
///
///
///
public string GetMethod(IntPtr connId)
{
IntPtr ptr = HttpSdk.HP_HttpServer_GetMethod(pServer, connId);
return Common.PtrToAnsiString(ptr);
}
///
/// 获取或设置本地协议版本
///
public HttpVersion LocalVersion
{
get
{
return HttpSdk.HP_HttpServer_GetLocalVersion(pServer);
}
set
{
HttpSdk.HP_HttpServer_SetLocalVersion(pServer, value);
}
}
///
/// 检查是否升级协议
///
///
///
public bool IsUpgrade(IntPtr connId)
{
return HttpSdk.HP_HttpServer_IsUpgrade(pServer, connId);
}
///
/// 检查是否有 Keep-Alive 标识
///
///
///
public bool IsKeepAlive(IntPtr connId)
{
return HttpSdk.HP_HttpServer_IsKeepAlive(pServer, connId);
}
///
/// 获取协议版本
///
///
///
public HttpVersion GetVersion(IntPtr connId)
{
return (HttpVersion)HttpSdk.HP_HttpServer_GetVersion(pServer, connId);
}
///
/// 获取主机
///
///
///
public string GetHost(IntPtr connId)
{
IntPtr ptr = HttpSdk.HP_HttpServer_GetHost(pServer, connId);
return Common.PtrToAnsiString(ptr);
}
///
/// 获取内容长度
///
///
///
public long GetContentLength(IntPtr connId)
{
return HttpSdk.HP_HttpServer_GetContentLength(pServer, connId);
}
///
/// 获取内容类型
///
///
///
public string GetContentType(IntPtr connId)
{
IntPtr ptr = HttpSdk.HP_HttpServer_GetContentType(pServer, connId);
return Common.PtrToAnsiString(ptr);
}
///
/// 获取内容类型
///
///
public string GetContentEncoding(IntPtr connId)
{
IntPtr ptr = HttpSdk.HP_HttpServer_GetContentEncoding(pServer, connId);
return Common.PtrToAnsiString(ptr);
}
///
/// 获取传输编码
///
///
public string GetTransferEncoding(IntPtr connId)
{
IntPtr ptr = HttpSdk.HP_HttpServer_GetTransferEncoding(pServer, connId);
return Common.PtrToAnsiString(ptr);
}
///
/// 获取协议升级类型
///
///
///
public HttpUpgradeType GetUpgradeType(IntPtr connId)
{
return HttpSdk.HP_HttpServer_GetUpgradeType(pServer, connId);
}
///
/// 获取解析错误代码
///
///
///
public ErrorInfo GetParseErrorInfo(IntPtr connId)
{
IntPtr ptr = IntPtr.Zero;
var error = new ErrorInfo();
error.ErrorCode = HttpSdk.HP_HttpServer_GetParseErrorCode(pServer, connId, ref ptr);
if (ptr != IntPtr.Zero)
{
try
{
error.ErrorMsg = Common.PtrToAnsiString(ptr); ;
}
catch (Exception)
{
}
}
return error;
}
///
/// 获取某个请求头(单值)
///
///
///
///
public string GetHeader(IntPtr connId, string key)
{
IntPtr ptr = IntPtr.Zero;
if (HttpSdk.HP_HttpServer_GetHeader(pServer, connId, key, ref ptr))
{
return Common.PtrToAnsiString(ptr);
}
return "";
}
///
/// 获取某个请求头(多值)
///
///
///
///
public List GetHeaders(IntPtr connId, string key)
{
var list = new List();
try
{
IntPtr[] arr = null;
uint count = 0;
HttpSdk.HP_HttpServer_GetHeaders(pServer, connId, key, arr, ref count);
if (count > 0)
{
arr = new IntPtr[count];
if (HttpSdk.HP_HttpServer_GetHeaders(pServer, connId, key, arr, ref count) && count > 0)
{
foreach (var item in arr)
{
list.Add(Common.PtrToAnsiString(item));
}
}
}
}
catch (Exception)
{
}
return list;
}
///
/// 获取所有请求头
///
///
///
public List GetAllHeaders(IntPtr connId)
{
var list = new List();
try
{
uint count = 0;
IntPtr arrPtr = IntPtr.Zero;
HttpSdk.HP_HttpServer_GetAllHeaders(pServer, connId, arrPtr, ref count);
if (count > 0)
{
var ptrArr = new THeaderForIntPtr[count];
arrPtr = Marshal.UnsafeAddrOfPinnedArrayElement(ptrArr, 0);
if (HttpSdk.HP_HttpServer_GetAllHeaders(pServer, connId, arrPtr, ref count))
{
foreach (var item in ptrArr)
{
list.Add(new THeader()
{
Name = Common.PtrToAnsiString(item.Name),
Value = Common.PtrToAnsiString(item.Value),
});
}
}
}
}
catch (Exception)
{
}
return list;
}
///
/// 获取所有请求头名称
///
///
///
public List GetAllHeaderNames(IntPtr connId)
{
var list = new List();
try
{
IntPtr[] arr = null;
uint count = 0;
HttpSdk.HP_HttpServer_GetAllHeaderNames(pServer, connId, arr, ref count);
if (count > 0)
{
arr = new IntPtr[count];
if (HttpSdk.HP_HttpServer_GetAllHeaderNames(pServer, connId, arr, ref count) && count > 0)
{
foreach (var item in arr)
{
list.Add(Common.PtrToAnsiString(item));
}
}
}
}
catch (Exception)
{
}
return list;
}
///
/// 获取Cookie
///
///
///
///
public string GetCookie(IntPtr connId, string key)
{
IntPtr ptr = IntPtr.Zero;
if (HttpSdk.HP_HttpServer_GetCookie(pServer, connId, key, ref ptr))
{
return Common.PtrToAnsiString(ptr);
}
return "";
}
///
/// 获取所有 Cookie
///
///
///
///
///
public List GetAllCookies(IntPtr connId)
{
var list = new List();
try
{
uint count = 0;
IntPtr arrPtr = IntPtr.Zero;
HttpSdk.HP_HttpServer_GetAllCookies(pServer, connId, arrPtr, ref count);
if (count > 0)
{
var ptrArr = new THeaderForIntPtr[count];
arrPtr = Marshal.UnsafeAddrOfPinnedArrayElement(ptrArr, 0);
if (HttpSdk.HP_HttpServer_GetAllCookies(pServer, connId, arrPtr, ref count))
{
foreach (var item in ptrArr)
{
list.Add(new TCookie()
{
Name = Common.PtrToAnsiString(item.Name),
Value = Common.PtrToAnsiString(item.Value)
});
}
}
}
}
catch (Exception)
{
}
return list;
}
///
/// 获取或设置 HTTP 启动方式,默认为true
///
public bool HttpAutoStart
{
get
{
return HttpSdk.HP_HttpServer_IsHttpAutoStart(pServer);
}
set
{
HttpSdk.HP_HttpServer_SetHttpAutoStart(pServer, value);
}
}
}
}