예제 #1
0
 /// <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;
 }
예제 #2
0
        /// <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);
            }
        }
예제 #3
0
 /// <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);
     }
 }
예제 #4
0
 /// <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);
        }
예제 #6
0
        /// <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);
        }
예제 #7
0
 /// <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();
     }
 }
예제 #8
0
        /// <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);
            }
        }
예제 #11
0
        /// <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);
            }
        }
예제 #12
0
 /// <summary>
 /// 中间件业务执行
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 protected override async Task Invoke(IContenxt context)
 {
     await Task.CompletedTask;
 }
예제 #13
0
 /// <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;
            }
        }
예제 #15
0
        /// <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);
     }
 }
예제 #18
0
 /// <summary>
 /// 会话断开后触发
 /// </summary>
 /// <param name="sender">发生者</param>
 /// <param name="context">上下文</param>
 void IPlug.OnDisconnected(object sender, IContenxt context)
 {
     this.OnDisconnected(sender, context);
 }
예제 #19
0
 /// <summary>
 /// 执行中间件
 /// </summary>
 /// <param name="context">上下文</param>
 /// <returns></returns>
 public Task Invoke(IContenxt context)
 {
     context.InputStream.Clear();
     context.Session.Close();
     return(TaskExtend.CompletedTask);
 }
예제 #20
0
 /// <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="content">文本内容</param>
 protected virtual void OnText(IContenxt context, string content)
 {
 }
 /// <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)
 {
 }
예제 #26
0
 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);
        }
예제 #28
0
 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()));
 }
예제 #29
0
 /// <summary>
 /// 会话断开后事件
 /// </summary>
 protected override void OnDisconnected(object sender, IContenxt context)
 {
     this.ProcessOfflineNotify(context);
 }
예제 #30
0
 /// <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)
 {
 }
예제 #32
0
 protected override void OnConnected(object sender, IContenxt context)
 {
     Console.WriteLine($"HttpServer-> {DateTime.Now} {context.Session}连接..");
 }
 /// <summary>
 /// Ping后会话对象将回复Pong触发此方法
 /// </summary>
 /// <param name="context">上下文</param>
 /// <param name="content">二进制内容</param>
 protected virtual void OnPong(IContenxt context, byte[] content)
 {
 }
예제 #34
0
 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;
 }
 /// <summary>
 /// 收到会话的关闭信息
 /// 在触发此方法后,基础服务将自动安全回收此会话对象
 /// </summary>
 /// <param name="context">上下文</param>
 /// <param name="code">关闭码</param>
 protected virtual void OnClose(IContenxt context, StatusCodes code)
 {
 }
예제 #36
0
 protected abstract Task Invoke(IContenxt context);
예제 #37
0
        /// <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);
        }
예제 #38
0
 /// <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);
            }
        }
예제 #40
0
 /// <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)
 {
 }
예제 #42
0
        /// <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);
        }
예제 #43
0
        /// <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);
                }
            });
        }
예제 #44
0
 /// <summary>
 /// 触发执行中间件
 /// </summary>
 /// <param name="context">上下文</param>
 /// <returns></returns>
 public Task RaiseInvoke(IContenxt context)
 {
     return(this.middlewares.First.Value.Invoke(context));
 }
예제 #45
0
 /// <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);
     }
 }
예제 #46
0
 /// <summary>
 /// 收到Http请求时触发
 /// </summary>
 /// <param name="context">上下文</param>
 /// <param name="requestContext">请求上下文对象</param>
 protected abstract void OnHttpRequest(IContenxt context, RequestContext requestContext);
예제 #47
0
        /// <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);
            }
        }
예제 #48
0
 /// <summary>
 /// 收到二进制类型请求时触发此方法
 /// </summary>
 /// <param name="context">会话对象</param>
 /// <param name="content">二进制内容</param>
 protected virtual void OnBinary(IContenxt context, byte[] content)
 {
 }
예제 #49
0
 /// <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);
         }
     });
 }
예제 #52
0
 /// <summary>
 /// SSL验证完成后触发
 /// 如果起用了SSL,验证通过后才可以往客户端发送数据
 /// 如果关闭了会话,将停止传递给下个插件的OnAuthenticated
 /// </summary>
 /// <param name="sender">发生者</param>
 /// <param name="context">上下文</param>
 protected virtual void OnSSLAuthenticated(object sender, IContenxt context)
 {
 }
예제 #53
0
 /// <summary>
 /// 收到请求后触发
 /// 如果关闭了会话或清空了数据,将停止传递给下个插件的OnRequested
 /// </summary>
 /// <param name="sender">发生者</param>
 /// <param name="context">上下文</param>
 protected virtual void OnRequested(object sender, IContenxt context)
 {
 }
예제 #54
0
 /// <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);
     }
 }
예제 #55
0
 /// <summary>
 /// 会话断开后触发
 /// </summary>
 /// <param name="sender">发生者</param>
 /// <param name="context">上下文</param>
 protected virtual void OnDisconnected(object sender, IContenxt context)
 {
 }
예제 #56
0
 /// <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);
     }
 }
예제 #57
0
 /// <summary>
 /// SSL验证完成后触发
 /// 如果起用了SSL,验证通过后才可以往客户端发送数据
 /// 如果关闭了会话,将停止传递给下个插件的OnAuthenticated
 /// </summary>
 /// <param name="sender">发生者</param>
 /// <param name="context">上下文</param>
 void IPlug.OnAuthenticated(object sender, IContenxt context)
 {
     this.OnSSLAuthenticated(sender, context);
 }
예제 #58
0
        /// <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;
        }
예제 #59
0
 /// <summary>
 /// 过滤上下文
 /// 返回true的上下文将被idle计时检测
 /// </summary>
 /// <param name="context">上下文</param>
 /// <returns></returns>
 protected virtual bool FilterContext(IContenxt context)
 {
     return(true);
 }