Exemplo n.º 1
0
        /// <summary>
        /// 设置握手结果
        /// </summary>
        /// <param name="streamReader">数据读取器</param>
        /// <returns></returns>
        public bool TrySetResult(ISessionStreamReader streamReader)
        {
            streamReader.Position = 0;
            var index = streamReader.IndexOf(DoubleCrlf);

            if (index < 0)
            {
                return(false);
            }

            var length = index + DoubleCrlf.Length;
            var header = streamReader.ReadString(Encoding.ASCII, length);

            streamReader.Clear(length);

            const string pattern = @"^HTTP/1.1 101 Switching Protocols\r\n((?<field_name>[^:\r\n]+):\s(?<field_value>[^\r\n]*)\r\n)+\r\n";
            var          match   = Regex.Match(header, pattern, RegexOptions.IgnoreCase);

            if (match.Success == true)
            {
                var httpHeader = HttpHeader.Parse(match.Groups["field_name"].Captures, match.Groups["field_value"].Captures);
                var secAccept  = httpHeader["Sec-WebSocket-Accept"];

                const string guid     = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
                var          bytes    = SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(this.secKey + guid));
                var          secValue = Convert.ToBase64String(bytes);

                if (secValue == secAccept)
                {
                    return(this.TrySetResult(SocketError.Success));
                }
            }
            return(this.TrySetResult(SocketError.SocketError));
        }
Exemplo n.º 2
0
        /// <summary>
        /// 设置握手结果
        /// </summary>
        /// <param name="streamReader">数据读取器</param>
        /// <returns></returns>
        public bool TrySetResult(ISessionStreamReader streamReader)
        {
            var result = HttpResponseParser.Parse(streamReader);

            if (result.IsHttp == false)
            {
                return(false);
            }
            else
            {
                streamReader.Clear();
            }

            if (result.Status == 101)
            {
                const string guid      = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
                var          bytes     = SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(this.secKey + guid));
                var          secValue  = Convert.ToBase64String(bytes);
                var          secAccept = result.Header["Sec-WebSocket-Accept"];
                if (secValue == secAccept)
                {
                    return(this.TrySetResult(SocketError.Success));
                }
            }

            return(this.TrySetResult(SocketError.SocketError));
        }
Exemplo n.º 3
0
        /// <summary>
        /// 生成表单和文件
        /// </summary>
        /// <param name="request">请求</param>
        /// <param name="streamReader">数据读取器</param>
        /// <param name="boundary">边界</param>
        private static void GenerateMultipartFormAndFiles(HttpRequest request, ISessionStreamReader streamReader, string boundary)
        {
            var boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary);
            var maxPosition   = streamReader.Length - Encoding.ASCII.GetBytes("--\r\n").Length;

            var files = new List <HttpFile>();
            var form  = new HttpNameValueCollection();

            streamReader.Position = streamReader.Position + boundaryBytes.Length;
            while (streamReader.Position < maxPosition)
            {
                var headLength = streamReader.IndexOf(DoubleCRLF) + DoubleCRLF.Length;
                if (headLength < DoubleCRLF.Length)
                {
                    break;
                }

                var head       = streamReader.ReadString(Encoding.UTF8, headLength);
                var bodyLength = streamReader.IndexOf(boundaryBytes);
                if (bodyLength < 0)
                {
                    break;
                }

                var mHead = new MultipartHead(head);
                if (mHead.TryGetFileName(out string fileName) == true)
                {
                    var bytes = streamReader.ReadArray(bodyLength);
                    var file  = new HttpFile(mHead.Name, fileName, bytes);
                    files.Add(file);
                }
Exemplo n.º 4
0
        /// <summary>
        /// 生成Post得到的表单和文件
        /// </summary>
        /// <param name="request">请求</param>
        /// <param name="streamReader">数据读取器</param>
        private static void GeneratePostFormAndFiles(HttpRequest request, ISessionStreamReader streamReader)
        {
            var boundary = default(string);

            if (request.IsApplicationFormRequest() == true)
            {
                HttpRequestParser.GenerateApplicationForm(request);
            }
            else if (request.IsMultipartFormRequest(out boundary) == true)
            {
                if (request.Body.Length >= boundary.Length)
                {
                    HttpRequestParser.GenerateMultipartFormAndFiles(request, streamReader, boundary);
                }
            }


            if (request.Form == null)
            {
                request.Form = new HttpNameValueCollection();
            }

            if (request.Files == null)
            {
                request.Files = new HttpFile[0];
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// 解析一个数据包
        /// 不足一个封包时返回null
        /// </summary>
        /// <param name="streamReader">数据读取器</param>
        /// <param name="packet">数据包</param>
        /// <returns></returns>
        public static bool Parse(ISessionStreamReader streamReader, out FastPacket packet)
        {
            packet = null;
            const int packetMinSize = 16;

            if (streamReader.Length < packetMinSize || streamReader[0] != FastPacket.Mark)
            {
                return(false);
            }

            streamReader.Position = 1;
            var totalBytes = streamReader.ReadInt32();

            if (totalBytes < packetMinSize)
            {
                return(false);
            }

            // 数据包未接收完整
            if (streamReader.Length < totalBytes)
            {
                return(true);
            }

            // api名称数据长度
            var apiNameLength = streamReader.ReadByte();

            if (totalBytes < apiNameLength + packetMinSize)
            {
                return(false);
            }

            // api名称数据
            var apiNameBytes = streamReader.ReadArray(apiNameLength);
            // 标识符
            var id = streamReader.ReadInt64();
            // 是否为客户端封包
            var isFromClient = streamReader.ReadBoolean();
            // 是否异常
            var isException = streamReader.ReadBoolean();
            // 实体数据
            var body = streamReader.ReadArray(totalBytes - streamReader.Position);

            // 清空本条数据
            streamReader.Clear(totalBytes);

            var apiName = Encoding.UTF8.GetString(apiNameBytes);

            packet = new FastPacket(apiName, id, isFromClient)
            {
                TotalBytes    = totalBytes,
                ApiNameLength = apiNameLength,
                IsException   = isException,
                Body          = body
            };
            return(true);
        }
Exemplo n.º 6
0
        /// <summary>
        /// 收到请求数据
        /// </summary>
        /// <param name="streamReader">数据读取器</param>
        /// <returns></returns>
        private Task OnWebSocketRequestAsync(ISessionStreamReader streamReader)
        {
            var frames = this.GenerateWebSocketFrame(streamReader);

            foreach (var frame in frames)
            {
                this.OnFrameRequest(frame);
            }
            return(TaskExtend.CompletedTask);
        }
Exemplo n.º 7
0
        /// <summary>
        /// 当接收到远程端的数据时,将触发此方法
        /// </summary>
        /// <param name="streamReader">数据读取器</param>
        /// <returns></returns>
        protected sealed override Task OnReceiveAsync(ISessionStreamReader streamReader)
        {
            var packages = this.GenerateFastPackets(streamReader);

            foreach (var package in packages)
            {
                this.ProcessPacketAsync(package);
            }
            return(TaskExtend.CompletedTask);
        }
Exemplo n.º 8
0
 /// <summary>
 /// 收到数据时
 /// </summary>
 /// <param name="streamReader">数据读取器</param>
 /// <returns></returns>
 protected override sealed async Task OnReceiveAsync(ISessionStreamReader streamReader)
 {
     if (this.handshake.IsWaitting == true)
     {
         this.handshake.TrySetResult(streamReader);
     }
     else
     {
         await this.OnWebSocketRequestAsync(streamReader);
     }
 }
        /// <summary>
        /// 获取当前的http方法长度
        /// </summary>
        /// <param name="streamReader">数据读取器</param>
        /// <returns></returns>
        private static int GetMthodLength(ISessionStreamReader streamReader)
        {
            var maxLength = Math.Min(streamReader.Length, HttpRequestParser.MedthodMaxLength + 1);

            for (var i = 0; i < maxLength; i++)
            {
                if (streamReader[i] == HttpRequestParser.Space)
                {
                    return(i);
                }
            }
            return(maxLength);
        }
Exemplo n.º 10
0
        /// <summary>
        /// 生成数据包
        /// </summary>
        /// <param name="streamReader">数据流</param>
        /// <returns></returns>
        private IList <FastPacket> GenerateFastPackets(ISessionStreamReader streamReader)
        {
            var list = new List <FastPacket>();

            while (true)
            {
                if (FastPacket.Parse(streamReader, out FastPacket packet) == false)
                {
                    return(list);
                }
                if (packet == null)
                {
                    return(list);
                }
                list.Add(packet);
            }
        }
Exemplo n.º 11
0
        /// <summary>
        /// 生成表单和文件
        /// </summary>
        /// <param name="request">请求</param>
        /// <param name="streamReader">数据读取器</param>
        /// <param name="boundary">边界</param>
        private static void GenerateMultipartFormAndFiles(HttpRequest request, ISessionStreamReader streamReader, string boundary)
        {
            var boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary);
            var maxPosition   = streamReader.Length - Encoding.ASCII.GetBytes("--\r\n").Length;

            var files = new List <HttpFile>();
            var form  = new HttpNameValueCollection();

            streamReader.Position = streamReader.Position + boundaryBytes.Length;
            while (streamReader.Position < maxPosition)
            {
                var headLength = streamReader.IndexOf(DoubleCRLF) + DoubleCRLF.Length;
                if (headLength < DoubleCRLF.Length)
                {
                    break;
                }

                var head       = streamReader.ReadString(Encoding.UTF8, headLength);
                var bodyLength = streamReader.IndexOf(boundaryBytes);
                if (bodyLength < 0)
                {
                    break;
                }

                string fileName = null;
                var    partItem = new MultipartItem(head);

                if (partItem.TryGetFileName(out fileName) == true)
                {
                    var bytes = streamReader.ReadArray(bodyLength);
                    var file  = new HttpFile(partItem.Name, fileName, bytes);
                    files.Add(file);
                }
                else
                {
                    var byes  = streamReader.ReadArray(bodyLength);
                    var value = HttpUtility.UrlDecode(byes, Encoding.UTF8);
                    form.Add(partItem.Name, value);
                }
                streamReader.Position = streamReader.Position + boundaryBytes.Length;
            }

            request.Form  = form;
            request.Files = files.ToArray();
        }
Exemplo n.º 12
0
        /// <summary>
        /// 解析生成请求帧
        /// </summary>
        /// <param name="streamReader">数据读取器</param>
        /// <returns></returns>
        private IList <FrameRequest> GenerateWebSocketFrame(ISessionStreamReader streamReader)
        {
            var list = new List <FrameRequest>();

            while (true)
            {
                try
                {
                    var request = FrameRequest.Parse(streamReader, false);
                    if (request == null)
                    {
                        return(list);
                    }
                    list.Add(request);
                }
                catch (NotSupportedException ex)
                {
                    this.Close(StatusCodes.ProtocolError, ex.Message);
                    return(list);
                }
            }
        }
Exemplo n.º 13
0
 /// <summary>
 /// 解析一个数据包
 /// 不足一个封包时packet返回null
 /// 中间件不符合则返回false
 /// </summary>
 /// <param name="session">会话</param>
 /// <param name="packet">数据包</param>
 /// <returns></returns>
 public virtual bool Parse(ISessionStreamReader streamReader, ISession session, out string packet)
 {
     packet = null;
     try
     {
         int required = 28;
         int remain   = session.RemainDataLength;//剩余长度
         while (remain >= required)
         {
             // 实体数据
             packet = Encoding.UTF8.GetString(streamReader.ReadArray(required));
             // 清空本条数据
             streamReader.Clear(required);
             return(true);
         }
         return(true);
     }
     catch (Exception)
     {
         return(false);
     }
 }
        /// <summary>
        /// 是否为http协议
        /// </summary>
        /// <param name="streamReader">数据读取器</param>
        /// <param name="headerLength">头数据长度,包括双换行</param>
        /// <returns></returns>
        private static bool IsHttp(ISessionStreamReader streamReader, out int headerLength)
        {
            var methodLength = HttpRequestParser.GetMthodLength(streamReader);
            var methodName   = streamReader.ReadString(Encoding.ASCII, methodLength);

            if (HttpRequestParser.MethodNames.Any(m => m.StartsWith(methodName, StringComparison.OrdinalIgnoreCase)) == false)
            {
                headerLength = 0;
                return(false);
            }

            streamReader.Position = 0;
            var headerIndex = streamReader.IndexOf(HttpRequestParser.DoubleCrlf);

            if (headerIndex < 0)
            {
                headerLength = 0;
                return(true);
            }

            headerLength = headerIndex + HttpRequestParser.DoubleCrlf.Length;
            return(true);
        }
Exemplo n.º 15
0
 /// <summary>
 /// 当接收到远程端的数据时,将触发此方法
 /// </summary>
 /// <param name="streamReader">接收到的数据读取器</param>
 /// <returns></returns>
 protected abstract Task OnReceiveAsync(ISessionStreamReader streamReader);
Exemplo n.º 16
0
        /// <summary>
        /// 解析回复头信息
        /// </summary>
        /// <param name="streamReader">数据读取器</param>
        /// <returns></returns>
        public static HttpResponseParseResult Parse(ISessionStreamReader streamReader)
        {
            var result = new HttpResponseParseResult();

            streamReader.Position = 0;

            if (streamReader.StartWith(HttpVersion11) == false)
            {
                return(result);
            }

            var endIndex = streamReader.IndexOf(DoubleCRLF);

            if (endIndex < 0)
            {
                return(result);
            }

            streamReader.Position += HttpVersion11.Length + 1;
            var statusLength = streamReader.IndexOf(Space);

            if (statusLength < 0)
            {
                return(result);
            }
            var status = streamReader.ReadString(Encoding.ASCII, statusLength);

            streamReader.Position += 1;
            var descriptionLenth = streamReader.IndexOf(CRLF);

            if (descriptionLenth < 0)
            {
                return(result);
            }
            var description = streamReader.ReadString(Encoding.ASCII, descriptionLenth);

            streamReader.Position += CRLF.Length;
            var httpHeader   = new HttpHeader();
            var headerLength = endIndex + DoubleCRLF.Length;

            while (streamReader.Position < headerLength)
            {
                var keyLength = streamReader.IndexOf(KvSpliter);
                if (keyLength <= 0)
                {
                    break;
                }
                var key = streamReader.ReadString(Encoding.ASCII, keyLength);

                streamReader.Position += KvSpliter.Length;
                var valueLength = streamReader.IndexOf(CRLF);
                if (valueLength < 0)
                {
                    break;
                }
                var value = streamReader.ReadString(Encoding.ASCII, valueLength);

                if (streamReader.StartWith(CRLF) == false)
                {
                    break;
                }
                streamReader.Position += CRLF.Length;
                httpHeader.Add(key, value);
            }

            result.Description = description;
            result.Status      = int.Parse(status);
            result.IsHttp      = true;
            result.Header      = httpHeader;
            return(result);
        }
Exemplo n.º 17
0
        /// <summary>
        /// 解析请求的数据
        /// 返回请求数据包
        /// </summary>
        /// <param name="streamReader">数据读取器</param>
        /// <param name="requiredMask">是否要求必须Mask</param>
        /// <exception cref="NotSupportedException"></exception>
        /// <returns></returns>
        public unsafe static FrameRequest Parse(ISessionStreamReader streamReader, bool requiredMask = true)
        {
            if (streamReader.Length < 2)
            {
                return(null);
            }

            ByteBits byte0     = streamReader[0];
            var      fin       = byte0[0];
            var      rsv       = byte0.Take(1, 3);
            var      frameCode = (FrameCodes)(byte)byte0.Take(4, 4);

            ByteBits byte1 = streamReader[1];
            var      mask  = byte1[0];

            if (requiredMask && mask == false)
            {
                throw new NotSupportedException("mask is required");
            }

            if (Enum.IsDefined(typeof(FrameCodes), frameCode) == false || rsv != 0)
            {
                throw new NotSupportedException();
            }

            var contentSize   = 0;
            var contentLength = (int)byte1.Take(1, 7);

            streamReader.Position = 2;

            if (contentLength == 127)
            {
                contentSize   = 8;
                contentLength = (int)streamReader.ReadUInt64();
            }
            else if (contentLength == 126)
            {
                contentSize   = 2;
                contentLength = (int)streamReader.ReadUInt16();
            }

            var maskSize     = mask ? 4 : 0;
            var packetLength = 2 + maskSize + contentSize + contentLength;

            if (streamReader.Length < packetLength)
            {
                return(null);
            }

            var maskingKey = mask ? streamReader.ReadArray(4) : null;
            var content    = streamReader.ReadArray(contentLength);

            streamReader.Clear(packetLength);

            if (mask && contentLength > 0)
            {
                fixed(byte *pcontent = &content[0], pmask = &maskingKey[0])
                {
                    for (var i = 0; i < contentLength; i++)
                    {
                        *(pcontent + i) = (byte)(*(pcontent + i) ^ *(pmask + i % 4));
                    }
                }
            }

            return(new FrameRequest
            {
                Fin = fin,
                Rsv = rsv,
                Mask = mask,
                Frame = frameCode,
                ContentLength = contentLength,
                MaskingKey = maskingKey,
                Content = content
            });
        }