/// <summary> /// Api行为上下文 /// </summary> /// <param name="requestContext">请求上下文</param> /// <param name="action">Api行为</param> /// <param name="context">上下文</param> public ActionContext(RequestContext requestContext, HttpAction action, IContenxt context) : base(requestContext.Request, requestContext.Response) { this.Action = action; this.Session = context.Session; this.AllSessions = context.AllSessions; }
/// <summary> /// 会话断开连接时 /// </summary> /// <param name="sender"></param> /// <param name="context"></param> static void Events_OnDisconnected(object sender, IContenxt context) { if (context.Session.IsProtocol("websocket") != true) { return; } var name = context.Session.Tag.TryGet<string>("name"); if (name == null) { return; } var webSocketSessions = context .AllSessions .FilterWrappers<JsonWebSocketSession>(); var members = webSocketSessions .Select(item => item.Tag.TryGet<string>("name")) .Where(item => item != null) .ToArray(); // 推送成员下线通知 foreach (var item in webSocketSessions) { item.InvokeApi("OnMemberChange", 0, name, members); } }
/// <summary> /// 触发OnDisconnected /// </summary> /// <param name="sender"></param> /// <param name="context"></param> internal void RaiseDisconnected(object sender, IContenxt context) { var @event = this.OnDisconnected; if (@event != null) { @event.Invoke(sender, context); } }
/// <summary> /// 执行中间件 /// </summary> /// <param name="context">上下文</param> /// <returns></returns> Task IMiddleware.Invoke(IContenxt context) { if (context.Session.IsProtocol("http") == false) { return this.Next.Invoke(context); } return this.OnHttpRequest(context); }
/// <summary> /// 回复握手,请求体已被http中间件解析 /// </summary> /// <param name="context">上下文</param> /// <returns></returns> private Task OnWebSocketHandshake(IContenxt context) { const string seckey = "Sec-WebSocket-Key"; var secValue = context.Session.Tag.TryGet<string>(seckey); if (string.IsNullOrEmpty(secValue) == true) { return this.Next.Invoke(context); } context.Session.Tag.Remove(seckey); return this.ResponseHandshake(context, secValue); }
/// <summary> /// 执行中间件 /// </summary> /// <param name="context">上下文</param> /// <returns></returns> Task IMiddleware.Invoke(IContenxt context) { if (context.Session.Protocol != null || context.Buffer.Length != 23) { return this.Next.Invoke(context); } context.Buffer.Position = 0; var request = context.Buffer.ReadString(Encoding.ASCII); if (string.Equals(request, "<policy-file-request/>\0", StringComparison.OrdinalIgnoreCase)) { return new Task(() => this.SendPolicyXML(context)); } return this.Next.Invoke(context); }
/// <summary> /// 发送策略文件 /// </summary> /// <param name="context">上下文</param> private void SendPolicyXML(IContenxt context) { try { var policyXml = this.GeneratePolicyXml(); var bytes = Encoding.UTF8.GetBytes(policyXml.ToCharArray()); context.Session.Send(new ByteRange(bytes)); } catch (Exception) { } finally { context.Session.Close(); } }
/// <summary> /// 收到http请求 /// </summary> /// <param name="context">上下文</param> /// <returns></returns> private Task OnHttpRequest(IContenxt context) { try { var request = default(HttpRequest); if (HttpRequest.Parse(context, out request) == false) { return this.Next.Invoke(context); } if (context.Session.Protocol == null) { context.Session.SetProtocolWrapper("http", null); } if (request == null) { return new Task(() => { }); } if (request.IsWebsocketRequest() == true) { const string secKey = "Sec-WebSocket-Key"; context.Session.Tag.Set(secKey, request.Headers[secKey]); return this.Next.Invoke(context); } return new Task(() => { var response = new HttpResponse(context.Session); var requestContext = new RequestContext(request, response); this.OnHttpRequest(context, requestContext); }); } catch (HttpException ex) { return new Task(() => this.OnException(context.Session, ex)); } catch (Exception ex) { return new Task(() => this.OnException(context.Session, new HttpException(500, ex.Message))); } }
/// <summary> /// 执行中间件 /// </summary> /// <param name="context">上下文</param> /// <returns></returns> Task IMiddleware.Invoke(IContenxt context) { var isWebSocket = context.Session.IsProtocol("websocket"); if (isWebSocket == true) { return this.OnWebSocketFrameRequest(context); } if (isWebSocket == null) { return this.OnWebSocketHandshakeRequest(context); } if (context.Session.IsProtocol("http") == true) { return this.OnWebSocketHandshake(context); } return this.Next.Invoke(context); }
/// <summary> /// 收到WebSocket的握手请求 /// </summary> /// <param name="context">上下文</param> /// <returns></returns> private Task OnWebSocketHandshakeRequest(IContenxt context) { try { var httpRequest = default(HttpRequest); if (HttpRequest.Parse(context, out httpRequest) == false) { return this.Next.Invoke(context); } if (httpRequest == null || httpRequest.IsWebsocketRequest() == false) { return this.Next.Invoke(context); } const string seckey = "Sec-WebSocket-Key"; var secValue = httpRequest.Headers[seckey]; return this.ResponseHandshake(context, secValue); } catch (Exception) { return this.Next.Invoke(context); } }
/// <summary> /// 收到http请求 /// </summary> /// <param name="context">上下文</param> /// <param name="requestContext">请求上下文</param> protected override void OnHttpRequest(IContenxt context, NetworkSocket.Http.RequestContext requestContext) { var request = requestContext.Request; var response = requestContext.Response; if (AppConfig.PathPattern.IsMatch(request.Path) == false) { var message = "路径不匹配,数据未转发 .."; response.Write(message); Console.WriteLine(message); } else { var fastSessions = context.AllSessions.FilterWrappers<FastSession>().ToArray(); foreach (var session in fastSessions) { this.PushRequest(session, request); } var message = string.Format("数据已转发到{0}到客户端 ..", fastSessions.Length); response.Write(message); Console.WriteLine(message); } }
/// <summary> /// 中间件业务执行 /// </summary> /// <param name="context"></param> /// <returns></returns> protected override async Task Invoke(IContenxt context) { await Task.CompletedTask; }
/// <summary> /// 收到Http请求时触发 /// </summary> /// <param name="context">上下文</param> /// <param name="requestContext">请求上下文对象</param> protected abstract void OnHttpRequest(IContenxt context, RequestContext requestContext);
/// <summary> /// 收到到数据帧请求 /// </summary> /// <param name="context">会话对象</param> /// <param name="frameRequest">数据帧</param> private void OnWebSocketRequest(IContenxt context, FrameRequest frameRequest) { switch (frameRequest.Frame) { case FrameCodes.Close: var reason = StatusCodes.NormalClosure; if (frameRequest.Content.Length > 1) { var status = ByteConverter.ToUInt16(frameRequest.Content, 0, Endians.Big); reason = (StatusCodes)status; } this.OnClose(context, reason); context.Session.Close(); break; case FrameCodes.Binary: this.OnBinary(context, frameRequest.Content); break; case FrameCodes.Text: var content = Encoding.UTF8.GetString(frameRequest.Content); this.OnText(context, content); break; case FrameCodes.Ping: try { var session = context.Session.Wrapper as WebSocketSession; session.Send(new FrameResponse(FrameCodes.Pong, frameRequest.Content)); } catch (Exception) { } finally { this.OnPing(context, frameRequest.Content); } break; case FrameCodes.Pong: this.OnPong(context, frameRequest.Content); break; default: break; } }
/// <summary> /// 解析连接请求信息 /// 如果数据未完整则返回null /// </summary> /// <param name="context">上下文</param> /// <param name="request">http请求</param> /// <exception cref="HttpException"></exception> /// <returns></returns> public static bool Parse(IContenxt context, out HttpRequest request) { var headerLength = 0; request = null; if (Protocol.IsHttp(context.Buffer, out headerLength) == false) { return(false); } if (headerLength <= 0) { return(true); } context.Buffer.Position = 0; var headerString = context.Buffer.ReadString(headerLength, Encoding.ASCII); const string pattern = @"^(?<method>[^\s]+)\s(?<path>[^\s]+)\sHTTP\/1\.1\r\n" + @"((?<field_name>[^:\r\n]+):\s(?<field_value>[^\r\n]*)\r\n)+" + @"\r\n"; var match = Regex.Match(headerString, pattern, RegexOptions.IgnoreCase); if (match.Success == false) { return(false); } var httpMethod = GetHttpMethod(match.Groups["method"].Value); var httpHeader = HttpHeader.Parse(match.Groups["field_name"].Captures, match.Groups["field_value"].Captures); var contentLength = httpHeader.TryGet <int>("Content-Length"); if (httpMethod == HttpMethod.POST && context.Buffer.Length - headerLength < contentLength) { return(true); // 数据未完整 } request = new HttpRequest { LocalEndPoint = context.Session.LocalEndPoint, RemoteEndPoint = context.Session.RemoteEndPoint, HttpMethod = httpMethod, Headers = httpHeader }; var scheme = context.Session.IsSecurity ? "https" : "http"; var url = string.Format("{0}://localhost:{1}{2}", scheme, context.Session.LocalEndPoint.Port, match.Groups["path"].Value); request.Url = new Uri(url); request.Path = request.Url.AbsolutePath; request.Query = HttpNameValueCollection.Parse(request.Url.Query.TrimStart('?'), false); if (httpMethod == HttpMethod.GET) { request.Body = new byte[0]; request.Form = new HttpNameValueCollection(); request.Files = new HttpFile[0]; } else { request.Body = context.Buffer.ReadArray(contentLength); context.Buffer.Position = headerLength; HttpRequest.GeneratePostFormAndFiles(request, context.Buffer); } context.Buffer.Clear(headerLength + contentLength); return(true); }
/// <summary> /// 收到Http请求时触发 /// </summary> /// <param name="context">上下文</param> /// <param name="requestContext">请求上下文对象</param> /// <returns ></returns> protected abstract Task OnHttpRequestAsync(IContenxt context, RequestContext requestContext);
/// <summary> /// 解析生成请求帧 /// </summary> /// <param name="context">上下文</param> /// <returns></returns> private IList<FrameRequest> GenerateWebSocketRequest(IContenxt context) { var list = new List<FrameRequest>(); while (true) { var request = FrameRequest.Parse(context.Buffer); if (request == null) { return list; } list.Add(request); } }
/// <summary> /// 会话断开后触发 /// </summary> /// <param name="sender">发生者</param> /// <param name="context">上下文</param> void IPlug.OnDisconnected(object sender, IContenxt context) { this.OnDisconnected(sender, context); }
/// <summary> /// 执行中间件 /// </summary> /// <param name="context">上下文</param> /// <returns></returns> public Task Invoke(IContenxt context) { context.InputStream.Clear(); context.Session.Close(); return(TaskExtend.CompletedTask); }
/// <summary> /// 收到文本请求类型时触发此方法 /// </summary> /// <param name="context">会话对象</param> /// <param name="content">文本内容</param> protected virtual void OnText(IContenxt context, string content) { }
/// <summary> /// 回复握手请求 /// </summary> /// <param name="context">上下文</param> /// <param name="secValue">Sec-WebSocket-Key</param> /// <returns></returns> private Task ResponseHandshake(IContenxt context, string secValue) { return new Task(() => { try { var wrapper = new WebSocketSession(context.Session); var hansshakeResponse = new HandshakeResponse(secValue); wrapper.Send(hansshakeResponse); this.OnSetProtocolWrapper(context.Session, wrapper); } catch (Exception) { } }); }
/// <summary> /// 收到会话的关闭信息 /// 在触发此方法后,基础服务将自动安全回收此会话对象 /// </summary> /// <param name="context">上下文</param> /// <param name="code">关闭码</param> protected virtual void OnClose(IContenxt context, StatusCodes code) { }
/// <summary> /// Ping后会话对象将回复Pong触发此方法 /// </summary> /// <param name="context">上下文</param> /// <param name="content">二进制内容</param> protected virtual void OnPong(IContenxt context, byte[] content) { }
/// <summary> /// 收到二进制类型请求时触发此方法 /// </summary> /// <param name="context">会话对象</param> /// <param name="content">二进制内容</param> protected virtual void OnBinary(IContenxt context, byte[] content) { }
protected override void OnConnected(object sender, IContenxt context) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine($"HttpServer-> {DateTime.Now} {context.Session}连接.."); Console.ForegroundColor = ConsoleColor.Gray; }
/// <summary> /// 解析连接请求信息 /// </summary> /// <param name="context">上下文</param> /// <exception cref="HttpException"></exception> /// <returns></returns> public static HttpParseResult Parse(IContenxt context) { var headerLength = 0; var result = new HttpParseResult(); context.StreamReader.Position = 0; result.IsHttp = HttpRequestParser.IsHttp(context.StreamReader, out headerLength); if (result.IsHttp == false || headerLength <= 0) { return(result); } var headerString = context.StreamReader.ReadString(Encoding.ASCII, headerLength); const string pattern = @"^(?<method>[^\s]+)\s(?<path>[^\s]+)\sHTTP\/1\.1\r\n" + @"((?<field_name>[^:\r\n]+):\s(?<field_value>[^\r\n]*)\r\n)+" + @"\r\n"; var match = Regex.Match(headerString, pattern, RegexOptions.IgnoreCase); result.IsHttp = match.Success; if (result.IsHttp == false) { return(result); } var httpMethod = HttpRequestParser.CastHttpMethod(match.Groups["method"].Value); var httpHeader = HttpHeader.Parse(match.Groups["field_name"].Captures, match.Groups["field_value"].Captures); var contentLength = httpHeader.TryGet <int>("Content-Length"); if (httpMethod == HttpMethod.POST && context.StreamReader.Length - headerLength < contentLength) { return(result);// 数据未完整 } var request = new HttpRequest { LocalEndPoint = context.Session.LocalEndPoint, RemoteEndPoint = context.Session.RemoteEndPoint, HttpMethod = httpMethod, Headers = httpHeader }; var scheme = context.Session.IsSecurity ? "https" : "http"; var host = httpHeader["Host"]; if (string.IsNullOrEmpty(host) == true) { host = context.Session.LocalEndPoint.ToString(); } var url = string.Format("{0}://{1}{2}", scheme, host, match.Groups["path"].Value); request.Url = new Uri(url); request.Path = request.Url.AbsolutePath; request.Query = HttpNameValueCollection.Parse(request.Url.Query.TrimStart('?')); switch (httpMethod) { case HttpMethod.GET: request.Body = new byte[0]; request.Form = new HttpNameValueCollection(); request.Files = new HttpFile[0]; break; default: request.Body = context.StreamReader.ReadArray(contentLength); context.StreamReader.Position = headerLength; HttpRequestParser.GeneratePostFormAndFiles(request, context.StreamReader); break; } result.Request = request; result.PackageLength = headerLength + contentLength; return(result); }
protected sealed override void OnConnected(object sender, IContenxt context) { Globle.AddDataLog("XDP", Globle.LangController.GetLang("LOG.XDPClientConnect", DateTime.Now.ToString("mm:ss"), context.Session.ToString())); }
/// <summary> /// 会话断开后事件 /// </summary> protected override void OnDisconnected(object sender, IContenxt context) { this.ProcessOfflineNotify(context); }
/// <summary> /// 收到请求后触发 /// 如果关闭了会话,将停止传递给下个插件的OnRequested /// </summary> /// <param name="sender">发生者</param> /// <param name="context">上下文</param> void IPlug.OnRequested(object sender, IContenxt context) { this.OnRequested(sender, context); }
/// <summary> /// 收到会话的关闭信息 /// 在触发此方法后,基础服务将自动安全回收此会话对象 /// </summary> /// <param name="context">上下文</param> /// <param name="code">关闭码</param> /// <param name="reason">备注原因</param> protected virtual void OnClose(IContenxt context, StatusCodes code, string reason) { }
protected override void OnConnected(object sender, IContenxt context) { Console.WriteLine($"HttpServer-> {DateTime.Now} {context.Session}连接.."); }
protected override void OnConnected(object sender, IContenxt context) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("{0} HttpServer->{1}连接..", DateTime.Now.ToString("HH:mm:ss.fff"), context.Session); Console.ForegroundColor = ConsoleColor.Gray; }
protected abstract Task Invoke(IContenxt context);
/// <summary> /// 把收到的内容当作ip,并绑定到ws会话 /// </summary> /// <param name="context">上下文</param> /// <param name="frame">数据</param> protected override void OnText(IContenxt context, FrameRequest frame) { var ipAddress = Encoding.UTF8.GetString(frame.Content); context.Session.Tag.Set("ip", ipAddress); }
/// <summary> /// 会话连接成功后触发 /// 如果关闭了会话,将停止传递给下个插件的OnConnected /// </summary> /// <param name="sender"></param> /// <param name="context"></param> protected override void OnConnected(object sender, IContenxt context) { Console.WriteLine("{0} 上线通知:{1}", DateTime.Now, context.Session.RemoteEndPoint.ToString()); }
/// <summary> /// 接收到文本信息时 /// </summary> /// <param name="context">上下文</param> /// <param name="content">内容</param> protected sealed override void OnText(IContenxt context, string content) { var jsonPacket = this.TryGetJsonPacket(context, content); if (jsonPacket == null) { return; } var session = context.Session.Wrapper as JsonWebSocketSession; var requestContext = new RequestContext(session, jsonPacket, context.AllSessions); if (jsonPacket.state == false) { this.ProcessRemoteException(requestContext); } else { this.ProcessRequest(requestContext); } }
/// <summary> /// 执行中间件 /// </summary> /// <param name="context">上下文</param> /// <returns></returns> public Task Invoke(IContenxt context) { context.Stream.Clear(); context.Session.Close(); return(null); }
/// <summary> /// 收到二进制类型请求时触发此方法 /// </summary> /// <param name="context">会话对象</param> /// <param name="frame">帧</param> protected virtual void OnBinary(IContenxt context, FrameRequest frame) { }
/// <summary> /// 尝试当作http头解析,生成请求对象 /// 如果不是http头则返回false /// </summary> /// <param name="context">上下文</param> /// <param name="request">请求对象</param> /// <param name="headerLength">请求头长度</param> /// <param name="contentLength">请求内容长度</param> /// <returns></returns> private static bool TryGetRequest(IContenxt context, out HttpRequest request, out int headerLength, out int contentLength) { request = null; headerLength = 0; contentLength = 0; var reader = context.StreamReader; // HTTP Method reader.Position = 0; var methodLength = reader.IndexOf(Space); if (methodLength < 0 || methodLength > MedthodMaxLength) { return(false); } var methodName = reader.ReadString(Encoding.ASCII, methodLength); if (MethodNames.Contains(methodName) == false) { return(false); } var httpMethod = (HttpMethod)Enum.Parse(typeof(HttpMethod), methodName, true); // HTTP Path reader.Position += 1; var pathLength = reader.IndexOf(Space); if (pathLength < 0) { return(false); } var path = reader.ReadString(Encoding.ASCII, pathLength); // HTTP Version reader.Position += 1; if (reader.StartWith(HttpVersion11) == false) { return(false); } reader.Position += HttpVersion11.Length; if (reader.StartWith(CRLF) == false) { return(false); } // HTTP Second line reader.Position += CRLF.Length; var endIndex = reader.IndexOf(DoubleCRLF); if (endIndex < 0) { return(false); } var httpHeader = new HttpHeader(); headerLength = reader.Position + endIndex + DoubleCRLF.Length; while (reader.Position < headerLength - CRLF.Length) { var keyLength = reader.IndexOf(KvSpliter); if (keyLength <= 0) { break; } var key = reader.ReadString(Encoding.ASCII, keyLength); reader.Position += KvSpliter.Length; var valueLength = reader.IndexOf(CRLF); if (valueLength < 0) { break; } var value = reader.ReadString(Encoding.ASCII, valueLength); if (reader.StartWith(CRLF) == false) { break; } reader.Position += CRLF.Length; httpHeader.Add(key, value); } if (httpMethod != HttpMethod.GET) { contentLength = httpHeader.TryGet <int>("Content-Length"); if (reader.Length - headerLength < contentLength) { return(true);// 数据未完整 } } request = new HttpRequest { LocalEndPoint = context.Session.LocalEndPoint, RemoteEndPoint = context.Session.RemoteEndPoint, HttpMethod = httpMethod, Headers = httpHeader }; var scheme = context.Session.IsSecurity ? "https" : "http"; var host = httpHeader["Host"]; if (string.IsNullOrEmpty(host) == true) { host = context.Session.LocalEndPoint.ToString(); } request.Url = new Uri(string.Format("{0}://{1}{2}", scheme, host, path)); request.Path = request.Url.AbsolutePath; request.Query = HttpNameValueCollection.Parse(request.Url.Query.TrimStart('?')); return(true); }
/// <summary> /// 收到fast请求 /// </summary> /// <param name="context">上下文</param> /// <returns></returns> private Task OnFastRequest(IContenxt context) { var fastPacket = default(FastPacket); if (FastPacket.Parse(context.Buffer, out fastPacket) == false) { return this.Next.Invoke(context); } if (fastPacket == null) { return new Task(() => { }); } if (context.Session.Protocol == null) { var wrapper = new FastSession(context.Session, this); context.Session.SetProtocolWrapper("fast", wrapper); } var fastSession = (FastSession)context.Session.Wrapper; var fastPackets = this.GenerateFastPackets(context, fastPacket); return new Task(() => { foreach (var packet in fastPackets) { var requestContext = new RequestContext(fastSession, packet, context.AllSessions); this.OnRecvFastPacket(requestContext); } }); }
/// <summary> /// 触发执行中间件 /// </summary> /// <param name="context">上下文</param> /// <returns></returns> public Task RaiseInvoke(IContenxt context) { return(this.middlewares.First.Value.Invoke(context)); }
/// <summary> /// 收到Http请求时触发 /// </summary> /// <param name="context">上下文</param> /// <param name="requestContext">请求上下文对象</param> protected override void OnHttpRequest(IContenxt context, RequestContext requestContext) { var extenstion = Path.GetExtension(requestContext.Request.Path); if (string.IsNullOrWhiteSpace(extenstion) == false) { this.ProcessStaticFileRequest(extenstion, requestContext); } else { this.ProcessActionRequest(requestContext.Request.Path, context, requestContext); } }
/// <summary> /// 执行httpAction /// </summary> /// <param name="action">httpAction</param> /// <param name="context">上下文</param> /// <param name="requestContext">请求上下文</param> private void ExecuteHttpAction(HttpAction action, IContenxt context, RequestContext requestContext) { var actionContext = new ActionContext(requestContext, action, context); var controller = GetHttpController(actionContext); if (controller != null) { controller.Execute(actionContext); this.DependencyResolver.TerminateService(controller); } }
/// <summary> /// 执行中间件 /// </summary> /// <param name="context">上下文</param> /// <returns></returns> public Task Invoke(IContenxt context) { context.Buffer.Clear(); context.Session.Close(); return null; }
/// <summary> /// 尝试获取数据包 /// </summary> /// <param name="context">上下文</param> /// <param name="content">内容</param> /// <returns></returns> private JsonPacket TryGetJsonPacket(IContenxt context, string content) { try { var packet = this.JsonSerializer.Deserialize(content); var jsonPacket = new JsonPacket { api = packet.api, id = packet.id ?? 0, state = packet.state ?? true, fromClient = packet.fromClient ?? true, body = packet.body }; return jsonPacket; } catch (Exception ex) { var session = context.Session.Wrapper as JsonWebSocketSession; var requestContext = new RequestContext(session, null, context.AllSessions); var exceptionConext = new ExceptionContext(requestContext, ex); this.ExecGlobalExceptionFilters(exceptionConext); return null; } }
/// <summary> /// 收到WebSocket请求 /// </summary> /// <param name="context">上下文</param> /// <returns></returns> private Task OnWebSocketFrameRequest(IContenxt context) { var requests = this.GenerateWebSocketRequest(context); return new Task(() => { foreach (var request in requests) { this.OnWebSocketRequest(context, request); } }); }
/// <summary> /// SSL验证完成后触发 /// 如果起用了SSL,验证通过后才可以往客户端发送数据 /// 如果关闭了会话,将停止传递给下个插件的OnAuthenticated /// </summary> /// <param name="sender">发生者</param> /// <param name="context">上下文</param> protected virtual void OnSSLAuthenticated(object sender, IContenxt context) { }
/// <summary> /// 收到请求后触发 /// 如果关闭了会话或清空了数据,将停止传递给下个插件的OnRequested /// </summary> /// <param name="sender">发生者</param> /// <param name="context">上下文</param> protected virtual void OnRequested(object sender, IContenxt context) { }
/// <summary> /// 生成数据包 /// </summary> /// <param name="context">上下文</param> /// <param name="fastPacket">数据包</param> /// <returns></returns> private IList<FastPacket> GenerateFastPackets(IContenxt context, FastPacket fastPacket) { var list = new List<FastPacket> { fastPacket }; while (true) { var packet = default(FastPacket); if (FastPacket.Parse(context.Buffer, out packet) == false) { return list; } if (packet == null) { return list; } list.Add(packet); } }
/// <summary> /// 会话断开后触发 /// </summary> /// <param name="sender">发生者</param> /// <param name="context">上下文</param> protected virtual void OnDisconnected(object sender, IContenxt context) { }
/// <summary> /// 处理一般的请求 /// </summary> /// <param name="route">路由</param> /// <param name="context">上下文</param> /// <param name="requestContext">请求上下文</param> private void ProcessActionRequest(string route, IContenxt context, RequestContext requestContext) { var action = this.httpActionList.TryGet(requestContext.Request); if (action == null) { var ex = new HttpException(404, "找不到路径" + route); this.ProcessHttpException(ex, requestContext); } else { this.ExecuteHttpAction(action, context, requestContext); } }
/// <summary> /// SSL验证完成后触发 /// 如果起用了SSL,验证通过后才可以往客户端发送数据 /// 如果关闭了会话,将停止传递给下个插件的OnAuthenticated /// </summary> /// <param name="sender">发生者</param> /// <param name="context">上下文</param> void IPlug.OnAuthenticated(object sender, IContenxt context) { this.OnSSLAuthenticated(sender, context); }
/// <summary> /// 解析连接请求信息 /// 如果数据未完整则返回null /// </summary> /// <param name="context">上下文</param> /// <param name="request">http请求</param> /// <exception cref="HttpException"></exception> /// <returns></returns> public static bool Parse(IContenxt context, out HttpRequest request) { var headerLength = 0; request = null; if (Protocol.IsHttp(context.Buffer, out headerLength) == false) { return false; } if (headerLength <= 0) { return true; } context.Buffer.Position = 0; var headerString = context.Buffer.ReadString(headerLength, Encoding.ASCII); const string pattern = @"^(?<method>[^\s]+)\s(?<path>[^\s]+)\sHTTP\/1\.1\r\n" + @"((?<field_name>[^:\r\n]+):\s(?<field_value>[^\r\n]*)\r\n)+" + @"\r\n"; var match = Regex.Match(headerString, pattern, RegexOptions.IgnoreCase); if (match.Success == false) { return false; } var httpMethod = GetHttpMethod(match.Groups["method"].Value); var httpHeader = HttpHeader.Parse(match.Groups["field_name"].Captures, match.Groups["field_value"].Captures); var contentLength = httpHeader.TryGet<int>("Content-Length"); if (httpMethod == HttpMethod.POST && context.Buffer.Length - headerLength < contentLength) { return true; // 数据未完整 } request = new HttpRequest { LocalEndPoint = context.Session.LocalEndPoint, RemoteEndPoint = context.Session.RemoteEndPoint, HttpMethod = httpMethod, Headers = httpHeader }; var scheme = context.Session.IsSecurity ? "https" : "http"; var url = string.Format("{0}://localhost:{1}{2}", scheme, context.Session.LocalEndPoint.Port, match.Groups["path"].Value); request.Url = new Uri(url); request.Path = request.Url.AbsolutePath; request.Query = HttpNameValueCollection.Parse(request.Url.Query.TrimStart('?'), false); if (httpMethod == HttpMethod.GET) { request.Body = new byte[0]; request.Form = new HttpNameValueCollection(); request.Files = new HttpFile[0]; } else { request.Body = context.Buffer.ReadArray(contentLength); context.Buffer.Position = headerLength; HttpRequest.GeneratePostFormAndFiles(request, context.Buffer); } context.Buffer.Clear(headerLength + contentLength); return true; }
/// <summary> /// 过滤上下文 /// 返回true的上下文将被idle计时检测 /// </summary> /// <param name="context">上下文</param> /// <returns></returns> protected virtual bool FilterContext(IContenxt context) { return(true); }