Exemplo n.º 1
0
        internal async Task <bool> ProcessAsync()
        {
            //Core.Log.LibVerbose("Connection from {0}:{1}", RemoteAddress, RemotePort);

            #region Init
            //Core.Log.LibVerbose("Initializing request...");
            var request = await _streamReader.ReadLineAsync().ConfigureAwait(false);

            if (string.IsNullOrEmpty(request))
            {
                throw new Exception("Invalid http request line");
            }

            //Core.Log.LibVerbose("Request: {0}", request);

            var newIndex = request.IndexOf(' ', 2);
            if (newIndex < 0)
            {
                throw new Exception("Invalid http request line");
            }

            var strMethod = request.Substring(0, newIndex);
            var lastIndex = newIndex + 1;
            newIndex = request.IndexOf(' ', lastIndex);
            if (newIndex < 0)
            {
                throw new Exception("Invalid http request line");
            }
            RawUrl = request.Substring(lastIndex, newIndex - lastIndex);

            switch (strMethod)
            {
            case "GET":
                Method = HttpMethod.GET;
                break;

            case "POST":
                Method = HttpMethod.POST;
                break;

            case "OPTIONS":
                Method = HttpMethod.OPTIONS;
                break;

            case "HEAD":
                Method = HttpMethod.HEAD;
                break;

            case "PUT":
                Method = HttpMethod.PUT;
                break;

            case "DELETE":
                Method = HttpMethod.DELETE;
                break;

            case "TRACE":
                Method = HttpMethod.TRACE;
                break;

            default:
                throw new Exception("Http method invalid");
            }
            #endregion

            #region Extract Headers
            //Core.Log.LibVerbose("Extracting headers...");
            string line;
            var    hostHeader        = false;
            string host              = null;
            var    contentTypeHeader = false;
            while (!string.IsNullOrEmpty(line = await _streamReader.ReadLineAsync().ConfigureAwait(false)))
            {
                var separator = line.IndexOf(':', 1);
                if (separator > -1)
                {
                    var name  = line.Substring(0, separator);
                    var value = line[separator + 1] == ' ' ? line.Substring(separator + 2) : line.Substring(separator + 1);
                    Headers[name] = value;
                    if (!hostHeader && name == "Host")
                    {
                        host       = value;
                        hostHeader = true;
                    }
                    if (!contentTypeHeader && name == "Content-Type")
                    {
                        ContentType       = value;
                        contentTypeHeader = true;
                    }
                    //Core.Log.LibVerbose("Header: {0}:{1}", name, value);
                }
                else
                {
                    Core.Log.Warning("Invalid http header line: " + line);
                }
            }
            //Core.Log.LibVerbose("Headers done.");
            #endregion

            #region Extract Post Data
            if (Method == HttpMethod.POST || Method == HttpMethod.PUT)
            {
                HasPostObject = true;
                Core.Log.LibVerbose("Getting Post Data...");
                ContentLength = 0;
                if (Headers.ContainsKey("Content-Length"))
                {
                    ContentLength = Convert.ToInt32(Headers["Content-Length"]);
                    if (ContentLength > MaxPostSize)
                    {
                        throw new Exception(string.Format("POST Content-Length({0}) too big for this simple server", ContentLength));
                    }
                    if (ContentLength > 0)
                    {
                        var data = new byte[ContentLength];
                        await InputStream.FillAsync(data).ConfigureAwait(false);

                        PostData = data;
                    }
                }
                Core.Log.LibVerbose("Post Data done.");
            }
            #endregion

            Url         = new Uri("http://" + host + RawUrl);
            QueryString = HttpUtility.ParseQueryString(Url.Query);
            Form        = ContentType == "application/x-www-form-urlencoded" ?
                          new FormUrlEncodedContentParser(PostData) :
                          new FormUrlEncodedContentParser();

            return(true);
        }