コード例 #1
0
        /// <summary>
        /// 解析连接请求信息
        /// </summary>
        /// <param name="buffer">接收到的原始数量</param>
        /// <returns></returns>
        public static HttpRequest From(ReceiveBuffer buffer)
        {
            buffer.Position = 0;
            var bytes = buffer.ReadArray();

            buffer.Clear();
            return(HttpRequest.From(bytes, "ws"));
        }
コード例 #2
0
        public void ReadAndPositionTest()
        {
            ReceiveBuffer target = new ReceiveBuffer(); // TODO: 初始化为适当的值
            var           bytes  = new byte[] {
                1,
                3,
                0, 1,
                0, 0, 0, 1,
                0, 0, 0, 0, 0, 0, 0, 5,
                255,
                255, 255
            };

            target.Add(bytes, 0, bytes.Length);

            target.Position = 0;
            Assert.IsTrue(target.ReadBoolean() && target.Position == 1);
            Assert.IsTrue(target.ReadByte() == 3 && target.Position == 1 + 1);
            Assert.IsTrue(target.ReadInt16() == 1 && target.Position == 1 + 1 + 2);
            Assert.IsTrue(target.ReadInt32() == 1 && target.Position == 1 + 1 + 2 + 4);
            Assert.IsTrue(target.ReadInt64() == 5 && target.Position == 1 + 1 + 2 + 4 + 8);
            Assert.IsTrue(target.ReadArray(1)[0] == 255 && target.Position == 1 + 1 + 2 + 4 + 8 + 1);
            Assert.IsTrue(target.ReadArray().Length == 2 && target.Position == 1 + 1 + 2 + 4 + 8 + 1 + 2);
        }
コード例 #3
0
ファイル: HttpRequest.cs プロジェクト: tenove/NetworkSocket
        /// <summary>
        /// 生成表单和文件
        /// </summary>
        /// <param name="request"></param>
        /// <param name="buffer"></param>
        /// <param name="boundary">边界</param>
        private static void GenerateMultipartFormAndFiles(HttpRequest request, ReceiveBuffer buffer, string boundary)
        {
            var doubleCrlf    = Encoding.ASCII.GetBytes("\r\n\r\n");
            var boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary);
            var maxPosition   = buffer.Length - Encoding.ASCII.GetBytes("--\r\n").Length;

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

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

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

                var mHead = new MultipartHead(head);
                if (mHead.IsFile == true)
                {
                    var stream = buffer.ReadArray(bodyLength);
                    var file   = new HttpFile(mHead, stream);
                    files.Add(file);
                }
                else
                {
                    var value = HttpUtility.UrlDecode(buffer.ReadString(bodyLength, Encoding.UTF8));
                    form.Add(mHead.Name, value);
                }
                buffer.Position = buffer.Position + boundaryBytes.Length;
            }

            request.Form  = form;
            request.Files = files.ToArray();
        }
コード例 #4
0
        /// <summary>
        /// 解析连接请求信息
        /// </summary>
        /// <param name="buffer">接收到的原始数量</param>
        /// <returns></returns>
        public static HttpRequest From(ReceiveBuffer buffer)
        {
            buffer.Position = 0;
            var bytes = buffer.ReadArray();

            var request = HttpRequest.From(bytes, "http");

            if (request == null)
            {
                return(null);
            }

            if (string.Equals(request.Method, "POST", StringComparison.OrdinalIgnoreCase))
            {
                var contentLength = int.Parse(request["Content-Length"]);
                if (request.Body.Length < contentLength)
                {
                    return(null);
                }
            }

            buffer.Clear();
            return(request);
        }
コード例 #5
0
        /// <summary>
        /// 解析连接请求信息
        /// </summary>
        /// <param name="buffer">接收到的原始数量</param>
        /// <param name="localEndpoint">服务器的本地终结点</param>
        /// <param name="remoteEndpoint">远程端的IP和端口</param>
        /// <returns></returns>
        public static HttpRequest From(ReceiveBuffer buffer, IPEndPoint localEndpoint, IPEndPoint remoteEndpoint)
        {
            buffer.Position = 0;
            var bytes = buffer.ReadArray();

            var request = HttpRequest.From(bytes, localEndpoint, remoteEndpoint);
            if (request != null)
            {
                buffer.Clear();
            }
            return request;
        }
コード例 #6
0
 /// <summary>
 /// 解析连接请求信息
 /// </summary>
 /// <param name="buffer">接收到的原始数量</param>
 /// <returns></returns>
 public static HttpRequest From(ReceiveBuffer buffer)
 {
     buffer.Position = 0;
     var bytes = buffer.ReadArray();
     buffer.Clear();
     return HttpRequest.From(bytes, "ws");
 }
コード例 #7
0
        /// <summary>
        /// 解析请求的数据
        /// 返回请求数据包
        /// </summary>
        /// <param name="buffer">所有收到的数据</param>
        /// <returns></returns>
        public unsafe static FrameRequest From(ReceiveBuffer buffer)
        {
            if (buffer.Length < 2)
            {
                return(null);
            }

            ByteBits byte0     = buffer[0];
            var      fin       = byte0[0];
            var      frameCode = (FrameCodes)(byte)byte0.Take(4, 4);

            if (fin == false || frameCode == FrameCodes.Continuation)
            {
                return(null);
            }

            var      rsv   = byte0.Take(1, 3);
            ByteBits byte1 = buffer[1];
            var      mask  = byte1[0];

            if (mask == false || Enum.IsDefined(typeof(FrameCodes), frameCode) == false || rsv != 0)
            {
                return(null);
            }

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

            buffer.Position = 2;

            if (contentLength == 127)
            {
                contentLength = (int)buffer.ReadUInt64();
            }
            else if (contentLength == 126)
            {
                contentLength = (int)buffer.ReadUInt16();
            }

            var packetLength = 6 + contentLength;

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

            var maskingKey = buffer.ReadArray(4);
            var content    = buffer.ReadArray(contentLength);

            buffer.Clear(packetLength);

            if (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
            });
        }
コード例 #8
0
ファイル: FastPacket.cs プロジェクト: tenove/NetworkSocket
        /// <summary>
        /// 解析一个数据包
        /// 不足一个封包时返回null
        /// </summary>
        /// <param name="buffer">接收到的历史数据</param>
        /// <exception cref="ProtocolException"></exception>
        /// <returns></returns>
        public static FastPacket From(ReceiveBuffer buffer)
        {
            if (buffer.Length < 4)
            {
                return(null);
            }

            buffer.Position = 0;
            var       totalBytes    = buffer.ReadInt32();
            const int packegMaxSize = 10 * 1204 * 1024; // 10M

            if (totalBytes > packegMaxSize)
            {
                throw new ProtocolException();
            }

            // 少于15字节是异常数据,清除收到的所有数据
            const int packetMinSize = 15;

            if (totalBytes < packetMinSize)
            {
                throw new ProtocolException();
            }

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

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

            if (totalBytes < apiNameLength + packetMinSize)
            {
                throw new ProtocolException();
            }

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

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

            var apiName = Encoding.UTF8.GetString(apiNameBytes);
            var packet  = new FastPacket(apiName, id, isFromClient)
            {
                TotalBytes    = totalBytes,
                ApiNameLength = apiNameLength,
                IsException   = isException,
                Body          = body
            };

            return(packet);
        }
コード例 #9
0
        /// <summary>
        /// 解析请求的数据
        /// 返回请求数据包
        /// </summary>
        /// <param name="buffer">所有收到的数据</param>  
        /// <returns></returns>
        public static unsafe FrameRequest From(ReceiveBuffer buffer)
        {
            if (buffer.Length < 2)
            {
                return null;
            }

            ByteBits byte0 = buffer[0];
            var fin = byte0[0];
            var frameCode = (FrameCodes)(byte)byte0.Take(4, 4);

            if (fin == false || frameCode == FrameCodes.Continuation)
            {
                return null;
            }

            var rsv = byte0.Take(1, 3);
            ByteBits byte1 = buffer[1];
            var mask = byte1[0];

            if (mask == false || Enum.IsDefined(typeof(FrameCodes), frameCode) == false || rsv != 0)
            {
                return null;
            }

            var contentLength = (int)byte1.Take(1, 7);
            buffer.Position = 2;

            if (contentLength == 127)
            {
                contentLength = (int)buffer.ReadUInt64();
            }
            else if (contentLength == 126)
            {
                contentLength = (int)buffer.ReadUInt16();
            }

            var packetLength = 6 + contentLength;
            if (buffer.Length < packetLength)
            {
                return null;
            }

            var maskingKey = buffer.ReadArray(4);
            var content = buffer.ReadArray(contentLength);
            buffer.Clear(packetLength);

            if (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
            };
        }
コード例 #10
0
ファイル: HttpRequest.cs プロジェクト: tenove/NetworkSocket
        /// <summary>
        /// 解析连接请求信息
        /// 如果数据未完整则返回null
        /// </summary>
        /// <param name="buffer">接收到的原始数量</param>
        /// <param name="localEndpoint">服务器的本地终结点</param>
        /// <param name="remoteEndpoint">远程端的IP和端口</param>
        /// <exception cref="HttpException"></exception>
        /// <returns></returns>
        public static HttpRequest Parse(ReceiveBuffer buffer, IPEndPoint localEndpoint, IPEndPoint remoteEndpoint)
        {
            buffer.Position = 0;
            var doubleCrlf  = Encoding.ASCII.GetBytes("\r\n\r\n");
            var headerIndex = buffer.IndexOf(doubleCrlf);

            if (headerIndex < 0)
            {
                return(null); // 数据未完整
            }

            var          headerLength = headerIndex + doubleCrlf.Length;
            var          headerString = 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)
            {
                throw new HttpException(400, "请求中有语法问题,或不能满足请求");
            }

            var httpMethod    = GetHttpMethod(match.Groups["method"].Value);
            var httpHeader    = new HttpHeader(match.Groups["field_name"].Captures, match.Groups["field_value"].Captures);
            var contentLength = httpHeader.TryGet <int>("Content-Length");

            if (httpMethod == HttpMethod.POST && buffer.Length - headerLength < contentLength)
            {
                return(null); // 数据未完整
            }

            var request = new HttpRequest
            {
                LocalEndPoint  = localEndpoint,
                RemoteEndPoint = remoteEndpoint,
                HttpMethod     = httpMethod,
                Headers        = httpHeader
            };

            request.Url   = new Uri("http://localhost:" + localEndpoint.Port + match.Groups["path"].Value);
            request.Path  = request.Url.AbsolutePath;
            request.Query = new HttpNameValueCollection(HttpUtility.UrlDecode(request.Url.Query.TrimStart('?')));

            if (httpMethod == HttpMethod.GET)
            {
                request.InputStrem = new byte[0];
                request.Form       = new HttpNameValueCollection();
                request.Files      = new HttpFile[0];
            }
            else
            {
                request.InputStrem = buffer.ReadArray(contentLength);
                buffer.Position    = headerLength;
                HttpRequest.GeneratePostFormAndFiles(request, buffer);
            }

            buffer.Clear(headerLength + contentLength);
            return(request);
        }
コード例 #11
0
ファイル: FastPacket.cs プロジェクト: dzvane/NetworkSocket
        /// <summary>
        /// 解析一个数据包       
        /// 不足一个封包时返回null
        /// </summary>
        /// <param name="buffer">接收到的历史数据</param>
        /// <exception cref="ProtocolException"></exception>
        /// <returns></returns>
        public static FastPacket From(ReceiveBuffer buffer)
        {
            if (buffer.Length < 4)
            {
                return null;
            }

            buffer.Position = 0;
            var totalBytes = buffer.ReadInt32();
            const int packegMaxSize = 10 * 1204 * 1024; // 10M
            if (totalBytes > packegMaxSize)
            {
                throw new ProtocolException();
            }

            // 少于15字节是异常数据,清除收到的所有数据
            const int packetMinSize = 15;
            if (totalBytes < packetMinSize)
            {
                throw new ProtocolException();
            }

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

            // api名称数据长度
            var apiNameLength = buffer.ReadByte();
            if (totalBytes < apiNameLength + packetMinSize)
            {
                throw new ProtocolException();
            }

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

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

            var apiName = Encoding.UTF8.GetString(apiNameBytes);
            var packet = new FastPacket(apiName, id, isFromClient)
            {
                TotalBytes = totalBytes,
                ApiNameLength = apiNameLength,
                IsException = isException,
                Body = body
            };
            return packet;
        }
コード例 #12
0
        /// <summary>
        /// 生成表单和文件
        /// </summary>
        /// <param name="request"></param>
        /// <param name="buffer"></param>   
        /// <param name="boundary">边界</param>
        private static void GenerateMultipartFormAndFiles(HttpRequest request, ReceiveBuffer buffer, string boundary)
        {
            var doubleCrlf = Encoding.ASCII.GetBytes("\r\n\r\n");
            var boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary);
            var maxPosition = buffer.Length - Encoding.ASCII.GetBytes("--\r\n").Length;

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

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

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

                var mHead = new MultipartHead(head);
                if (mHead.IsFile == true)
                {
                    var stream = buffer.ReadArray(bodyLength);
                    var file = new HttpFile(mHead, stream);
                    files.Add(file);
                }
                else
                {
                    var value = HttpUtility.UrlDecode(buffer.ReadString(bodyLength, Encoding.UTF8));
                    form.Add(mHead.Name, value);
                }
                buffer.Position = buffer.Position + boundaryBytes.Length;
            }

            request.Form = form;
            request.Files = files.ToArray();
        }
コード例 #13
0
        /// <summary>
        /// 解析连接请求信息
        /// 如果数据未完整则返回null
        /// </summary>
        /// <param name="buffer">接收到的原始数量</param>
        /// <param name="localEndpoint">服务器的本地终结点</param>
        /// <param name="remoteEndpoint">远程端的IP和端口</param>
        /// <exception cref="HttpException"></exception>
        /// <returns></returns>
        public static HttpRequest Parse(ReceiveBuffer buffer, IPEndPoint localEndpoint, IPEndPoint remoteEndpoint)
        {
            buffer.Position = 0;
            var doubleCrlf = Encoding.ASCII.GetBytes("\r\n\r\n");
            var headerIndex = buffer.IndexOf(doubleCrlf);
            if (headerIndex < 0)
            {
                return null; // 数据未完整
            }

            var headerLength = headerIndex + doubleCrlf.Length;
            var headerString = 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)
            {
                throw new HttpException(400, "请求中有语法问题,或不能满足请求");
            }

            var httpMethod = GetHttpMethod(match.Groups["method"].Value);
            var httpHeader = new HttpHeader(match.Groups["field_name"].Captures, match.Groups["field_value"].Captures);
            var contentLength = httpHeader.TryGet<int>("Content-Length");

            if (httpMethod == HttpMethod.POST && buffer.Length - headerLength < contentLength)
            {
                return null; // 数据未完整
            }

            var request = new HttpRequest
            {
                LocalEndPoint = localEndpoint,
                RemoteEndPoint = remoteEndpoint,
                HttpMethod = httpMethod,
                Headers = httpHeader
            };

            request.Url = new Uri("http://localhost:" + localEndpoint.Port + match.Groups["path"].Value);
            request.Path = request.Url.AbsolutePath;
            request.Query = new HttpNameValueCollection(HttpUtility.UrlDecode(request.Url.Query.TrimStart('?')));

            if (httpMethod == HttpMethod.GET)
            {
                request.InputStrem = new byte[0];
                request.Form = new HttpNameValueCollection();
                request.Files = new HttpFile[0];
            }
            else
            {
                request.InputStrem = buffer.ReadArray(contentLength);
                buffer.Position = headerLength;
                HttpRequest.GeneratePostFormAndFiles(request, buffer);
            }

            buffer.Clear(headerLength + contentLength);
            return request;
        }