Example #1
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();
        }
        /// <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();
        }
Example #3
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);
        }
        /// <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;
        }