/// <summary>
 /// 收到http请求
 /// </summary>
 /// <param name="context">上下文</param>
 /// <returns></returns>
 private async Task OnHttpRequestAsync(IContenxt context)
 {
     try
     {
         var result = HttpRequestParser.Parse(context);
         await this.ProcessParseResultAsync(context, result);
     }
     catch (HttpException ex)
     {
         this.OnException(context.Session, ex);
     }
     catch (Exception ex)
     {
         this.OnException(context.Session, new HttpException(500, ex.Message));
     }
 }
예제 #2
0
        /// <summary>
        /// 解析连接请求信息
        /// </summary>
        /// <param name="context">上下文</param>
        /// <returns></returns>
        private static HttpRequestParseResult ParseInternal(IContenxt context)
        {
            var headerLength  = 0;
            var contentLength = 0;
            var request       = default(HttpRequest);
            var result        = new HttpRequestParseResult();

            result.IsHttp = HttpRequestParser.TryGetRequest(context, out request, out headerLength, out contentLength);
            if (result.IsHttp == false)
            {
                return(result);
            }

            if (request == null) // 数据未完整
            {
                return(result);
            }

            switch (request.HttpMethod)
            {
            case HttpMethod.GET:
                request.Body  = new byte[0];
                request.Form  = new HttpNameValueCollection();
                request.Files = new HttpFile[0];
                break;

            default:
                context.StreamReader.Position = headerLength;
                request.Body = context.StreamReader.ReadArray(contentLength);
                context.StreamReader.Position = headerLength;
                HttpRequestParser.GeneratePostFormAndFiles(request, context.StreamReader);
                break;
            }

            result.Request       = request;
            result.RequestLength = headerLength + contentLength;
            return(result);
        }
예제 #3
0
        /// <summary>
        /// 是否为http协议
        /// </summary>
        /// <param name="stream">收到的数据</param>
        /// <param name="headerLength">头数据长度,包括双换行</param>
        /// <returns></returns>
        private static bool IsHttp(IStreamReader stream, out int headerLength)
        {
            var methodLength = HttpRequestParser.GetMthodLength(stream);
            var methodName   = stream.ReadString(Encoding.ASCII, methodLength);

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

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

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

            headerLength = headerIndex + HttpRequestParser.DoubleCrlf.Length;
            return(true);
        }
예제 #4
0
        /// <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.InputStream.Position = 0;

            result.IsHttp = HttpRequestParser.IsHttp(context.InputStream, out headerLength);
            if (result.IsHttp == false || headerLength <= 0)
            {
                return(result);
            }

            var          headerString = context.InputStream.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.InputStream.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.InputStream.ReadArray(contentLength);
                context.InputStream.Position = headerLength;
                HttpRequestParser.GeneratePostFormAndFiles(request, context.InputStream);
                break;
            }

            result.Request       = request;
            result.PackageLength = headerLength + contentLength;
            return(result);
        }