Esempio n. 1
0
    public async Task ReadNextPair_ReturnsNullOnEmptyStream(bool bufferRequest)
    {
        var body = MakeStream(bufferRequest, "");

        var reader = new FormReader(body);

        Assert.Null(await ReadPair(reader));
    }
        public async Task ReadFormAsync_EmptyValuedAtEndAllowed()
        {
            // Arrange
            var formContent = Encoding.UTF8.GetBytes("foo=");
            var body        = new MemoryStream(formContent);

            var formCollection = await FormReader.ReadFormAsync(body);

            // Assert
            Assert.Equal("", formCollection["foo"].FirstOrDefault());
        }
        public async Task ReadFormAsync_EmptyKeyWithAdditionalEntryAllowed()
        {
            // Arrange
            var formContent = Encoding.UTF8.GetBytes("=bar&baz=2");
            var body        = new MemoryStream(formContent);

            var formCollection = await FormReader.ReadFormAsync(body);

            // Assert
            Assert.Equal("bar", formCollection[""].FirstOrDefault());
            Assert.Equal("2", formCollection["baz"].FirstOrDefault());
        }
Esempio n. 4
0
    public async Task ReadSmallFormAsyncStream()
    {
        var bytes  = Encoding.UTF8.GetBytes("foo=bar&baz=boo");
        var stream = new MemoryStream(bytes);

        for (var i = 0; i < 1000; i++)
        {
            var formReader = new FormReader(stream);
            await formReader.ReadFormAsync();

            stream.Position = 0;
        }
    }
Esempio n. 5
0
 public static IDictionary <string, string> ReadFormString(string queryString, bool unescapeDataString = true)
 {
     using (FormReader reader = new FormReader(queryString))
     {
         var collection = new FormCollection(reader.ReadForm());
         Dictionary <string, string> result = new Dictionary <string, string>(collection.Count);
         foreach (var kv in collection)
         {
             result[kv.Key] = Uri.UnescapeDataString(kv.Value);
         }
         return(result);
     }
 }
        protected async override Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var response = new HttpResponseMessage();

            if (request.RequestUri.AbsoluteUri.StartsWith("https://api.twitter.com/oauth/access_token"))
            {
                var formData = new FormCollection(await FormReader.ReadFormAsync(await request.Content.ReadAsStreamAsync()));
                if (formData["oauth_verifier"] == "valid_oauth_verifier")
                {
                    if (_requestTokenEndpointInvoked)
                    {
                        var response_Form_data = new List <KeyValuePair <string, string> >()
                        {
                            new KeyValuePair <string, string>("oauth_token", "valid_oauth_token"),
                            new KeyValuePair <string, string>("oauth_token_secret", "valid_oauth_token_secret"),
                            new KeyValuePair <string, string>("user_id", "valid_user_id"),
                            new KeyValuePair <string, string>("screen_name", "valid_screen_name"),
                        };

                        response.Content = new FormUrlEncodedContent(response_Form_data);
                    }
                    else
                    {
                        response.StatusCode = HttpStatusCode.InternalServerError;
                        response.Content    = new StringContent("RequestTokenEndpoint is not invoked");
                    }
                    return(response);
                }
                response.StatusCode = (HttpStatusCode)400;
                return(response);
            }
            else if (request.RequestUri.AbsoluteUri.StartsWith("https://api.twitter.com/oauth/request_token"))
            {
                var response_Form_data = new List <KeyValuePair <string, string> >()
                {
                    new KeyValuePair <string, string>("oauth_callback_confirmed", "true"),
                    new KeyValuePair <string, string>("oauth_token", "valid_oauth_token"),
                    new KeyValuePair <string, string>("oauth_token_secret", "valid_oauth_token_secret")
                };

                _requestTokenEndpointInvoked = true;
                response.Content             = new FormUrlEncodedContent(response_Form_data);
                return(response);
            }

            throw new NotImplementedException(request.RequestUri.AbsoluteUri);
        }
Esempio n. 7
0
        /// <summary>
        /// Gets the parameter base string.
        /// </summary>
        /// <param name="request">The HTTP request to be signed.</param>
        /// <param name="config">OAuth config information.</param>
        /// <param name="nonce">The nonce for this request.</param>
        /// <param name="timestamp">The timestamp for this request.</param>
        /// <param name="version">The OAuth version.</param>
        /// <returns>The parameter base string.</returns>
        public async Task <string> GetParameterBase(
            HttpRequestMessage request,
            OAuthConfig config,
            string nonce,
            string timestamp,
            string version)
        {
            Dictionary <string, StringValues> parameters = new Dictionary <string, StringValues>();

            if (request.Content != null &&
                request.Content.Headers.ContentType.MediaType == "application/x-www-form-urlencoded")
            {
                var content = await request.Content.ReadAsStringAsync().ConfigureAwait(false);

                var fr = new FormReader(content);
                parameters.Merge(await fr.ReadFormAsync().ConfigureAwait(false));
            }

            var queryParams = QueryHelpers.ParseQuery(request.RequestUri.Query);

            parameters.Merge(queryParams);

            parameters.Add("oauth_consumer_key", config.ConsumerKey);
            parameters.Add("oauth_nonce", nonce);
            parameters.Add("oauth_signature_method", this.SignatureMethod);
            parameters.Add("oauth_timestamp", timestamp);
            parameters.Add("oauth_token", config.AccessToken);
            parameters.Add("oauth_version", version);

            string parameterBase = string.Empty;

            foreach (var param in parameters.OrderBy(pair => pair.Key))
            {
                foreach (var value in param.Value.OrderBy(v => v))
                {
                    if (parameterBase.Length > 0)
                    {
                        parameterBase += "&";
                    }

                    parameterBase += Uri.EscapeDataString(param.Key)
                                     + "=" + Uri.EscapeDataString(value);
                }
            }

            return(parameterBase);
        }
        protected override async Task <OAuthTokenResponse> ExchangeCodeAsync(string code, string redirectUri)
        {
            log.LogDebug("ExchangeCodeAsync called with code " + code + " redirectUri " + redirectUri);
            //var queryBuilder = new QueryBuilder()
            //{
            //    { "grant_type", "authorization_code" },
            //    { "code", code },
            //    { "redirect_uri", redirectUri },
            //    { "client_id", Options.AppId },
            //    { "client_secret", Options.AppSecret },
            //};

            var currentSite = await GetSite();

            var tenantFbOptions
                = new MultiTenantFacebookOptionsResolver(
                      Options,
                      currentSite,
                      multiTenantOptions);


            var queryBuilder = new QueryBuilder()
            {
                { "grant_type", "authorization_code" },
                { "code", code },
                { "redirect_uri", tenantFbOptions.ResolveRedirectUrl(redirectUri) },
                { "client_id", tenantFbOptions.AppId },
                { "client_secret", tenantFbOptions.AppSecret },
            };

            var response = await Backchannel.GetAsync(Options.TokenEndpoint + queryBuilder.ToString(), Context.RequestAborted);

            response.EnsureSuccessStatusCode();

            var form    = new FormCollection(FormReader.ReadForm(await response.Content.ReadAsStringAsync()));
            var payload = new JObject();

            foreach (string key in form.Keys)
            {
                //payload.Add(string.Equals(key, "expires", StringComparison.OrdinalIgnoreCase) ? "expires_in" : key, form[key]);
                payload.Add(string.Equals(key, "expires", StringComparison.OrdinalIgnoreCase) ? "expires_in" : key, (string)form[key]);
            }

            // The refresh token is not available.
            return(new OAuthTokenResponse(payload));
        }
Esempio n. 9
0
    public async Task ReadNextPair_ReadsAllPairs(bool bufferRequest)
    {
        var body = MakeStream(bufferRequest, "foo=&baz=2");

        var reader = new FormReader(body);

        var pair = (KeyValuePair <string, string>) await ReadPair(reader);

        Assert.Equal("foo", pair.Key);
        Assert.Equal("", pair.Value);

        pair = (KeyValuePair <string, string>) await ReadPair(reader);

        Assert.Equal("baz", pair.Key);
        Assert.Equal("2", pair.Value);

        Assert.Null(await ReadPair(reader));
    }
Esempio n. 10
0
        private static bool IsFormWithClientCredentials(HttpContent content, string expectedClientId, string expectedClientSecret)
        {
            if (!(content is FormUrlEncodedContent))
            {
                return(false);
            }

            var contentStream = content.ReadAsStreamAsync().Result;

            using (var reader = new FormReader(contentStream))
            {
                var formData = reader.ReadFormAsync().Result;

                Assert.Equal(expectedClientId, formData["client_id"]);
                Assert.Equal(expectedClientSecret, formData["client_secret"]);
                return(true);
            }
        }
Esempio n. 11
0
        public async Task Should_map_null_if_there_are_no_parameters()
        {
            var requestGraph = RequestGraph
                               .CreateFor <Handler>(h => h.Post(null, null))
                               .WithRequestData("")
                               .WithRequestParameter("request");

            var reader = new FormReader(requestGraph.ValueMappers,
                                        requestGraph.Configuration);

            var result = await reader.Read(requestGraph.GetRequestReaderContext());

            result.ShouldNotBeNull();
            result.ShouldBeType <InputModel>();
            var inputModel = result.CastTo <InputModel>();

            inputModel.Param1.ShouldBeNull();
            inputModel.Param2.ShouldEqual(0);
        }
        protected async override Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var response = new HttpResponseMessage();

            if (request.RequestUri.AbsoluteUri.StartsWith("https://graph.facebook.com/v2.5/oauth/access_token"))
            {
                var formData = new FormCollection(await FormReader.ReadFormAsync(await request.Content.ReadAsStreamAsync()));
                if (formData["grant_type"] == "authorization_code")
                {
                    if (formData["code"] == "ValidCode")
                    {
                        Helpers.ThrowIfConditionFailed(() => ((string)formData["redirect_uri"]).EndsWith("signin-facebook"), "Redirect URI is not ending with /signin-facebook");
                        Helpers.ThrowIfConditionFailed(() => formData["client_id"] == "[AppId]", "Invalid client Id received");
                        Helpers.ThrowIfConditionFailed(() => formData["client_secret"] == "[AppSecret]", "Invalid client secret received");
                        response.Content = new StringContent("{ \"access_token\": \"ValidAccessToken\", \"expires_in\": \"100\" }");
                        return(response);
                    }
                    response.StatusCode = (HttpStatusCode)400;
                    return(response);
                }
            }
            else if (request.RequestUri.AbsoluteUri.StartsWith("https://graph.facebook.com/v2.5/me"))
            {
                var queryParameters = new QueryCollection(QueryHelpers.ParseQuery(request.RequestUri.Query));
                Helpers.ThrowIfConditionFailed(() => queryParameters["appsecret_proof"].Count > 0, "appsecret_proof is empty");
                if (queryParameters["access_token"] == "ValidAccessToken")
                {
                    response.Content = new StringContent("{\"id\":\"Id\",\"name\":\"AspnetvnextTest AspnetvnextTest\",\"first_name\":\"AspnetvnextTest\",\"last_name\":\"AspnetvnextTest\",\"link\":\"https:\\/\\/www.facebook.com\\/myLink\",\"username\":\"AspnetvnextTest.AspnetvnextTest.7\",\"gender\":\"male\",\"email\":\"AspnetvnextTest\\u0040test.com\",\"timezone\":-7,\"locale\":\"en_US\",\"verified\":true,\"updated_time\":\"2013-08-06T20:38:48+0000\",\"CertValidatorInvoked\":\"ValidAccessToken\"}");
                }
                else
                {
                    response.Content = new StringContent("{\"error\":{\"message\":\"Invalid OAuth access token.\",\"type\":\"OAuthException\",\"code\":190}}");
                }
                return(response);
            }

            throw new NotImplementedException(request.RequestUri.AbsoluteUri);
        }
        protected async override Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var response = new HttpResponseMessage();

            if (request.RequestUri.AbsoluteUri.StartsWith("https://login.live.com/oauth20_token.srf"))
            {
                var formData = new FormCollection(await FormReader.ReadFormAsync(await request.Content.ReadAsStreamAsync()));
                if (formData["grant_type"] == "authorization_code")
                {
                    if (formData["code"] == "ValidCode")
                    {
                        if (formData["redirect_uri"].Count > 0 && ((string)formData["redirect_uri"]).EndsWith("signin-microsoft") &&
                            formData["client_id"] == "[ClientId]" && formData["client_secret"] == "[ClientSecret]")
                        {
                            response.Content = new StringContent("{\"token_type\":\"bearer\",\"expires_in\":3600,\"scope\":\"wl.basic\",\"access_token\":\"ValidAccessToken\",\"refresh_token\":\"ValidRefreshToken\",\"authentication_token\":\"ValidAuthenticationToken\"}");
                            return(response);
                        }
                    }
                }

                response.StatusCode = (HttpStatusCode)400;
                return(response);
            }
            else if (request.RequestUri.AbsoluteUri.StartsWith("https://apis.live.net/v5.0/me"))
            {
                if (request.Headers.Authorization.Parameter == "ValidAccessToken")
                {
                    response.Content = new StringContent("{\r   \"id\": \"fccf9a24999f4f4f\", \r   \"name\": \"AspnetvnextTest AspnetvnextTest\", \r   \"first_name\": \"AspnetvnextTest\", \r   \"last_name\": \"AspnetvnextTest\", \r   \"link\": \"https://profile.live.com/\", \r   \"gender\": null, \r   \"locale\": \"en_US\", \r   \"updated_time\": \"2013-08-27T22:18:14+0000\"\r}");
                }
                else
                {
                    response.Content = new StringContent("{\r   \"error\": {\r      \"code\": \"request_token_invalid\", \r      \"message\": \"The access token isn't valid.\"\r   }\r}", Encoding.UTF8, "text/javascript");
                }
                return(response);
            }

            throw new NotImplementedException(request.RequestUri.AbsoluteUri);
        }
Esempio n. 14
0
        protected async override Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var response = new HttpResponseMessage();

            if (request.RequestUri.AbsoluteUri.StartsWith("https://www.googleapis.com/oauth2/v3/token"))
            {
                var formData = new FormCollection(await FormReader.ReadFormAsync(await request.Content.ReadAsStreamAsync()));
                if (formData["grant_type"] == "authorization_code")
                {
                    if (formData["code"] == "ValidCode")
                    {
                        if (formData["redirect_uri"].Count > 0 && ((string)formData["redirect_uri"]).EndsWith("signin-google") &&
                            formData["client_id"] == "[ClientId]" && formData["client_secret"] == "[ClientSecret]")
                        {
                            response.Content = new StringContent("{\"access_token\":\"ValidAccessToken\",\"refresh_token\":\"ValidRefreshToken\",\"token_type\":\"Bearer\",\"expires_in\":\"1200\",\"id_token\":\"Token\"}", Encoding.UTF8, "application/json");
                            return(response);
                        }
                    }
                }
                response.StatusCode = (HttpStatusCode)400;
                return(response);
            }
            else if (request.RequestUri.AbsoluteUri.StartsWith("https://www.googleapis.com/plus/v1/people/me"))
            {
                if (request.Headers.Authorization.Parameter == "ValidAccessToken")
                {
                    response.Content = new StringContent("{ \"kind\": \"plus#person\",\n \"etag\": \"\\\"YFr-hUROXQN7IOa3dUHg9dQ8eq0/2hY18HdHEP8NLykSTVEiAhkKsBE\\\"\",\n \"gender\": \"male\",\n \"emails\": [\n  {\n   \"value\": \"[email protected]\",\n   \"type\": \"account\"\n  }\n ],\n \"objectType\": \"person\",\n \"id\": \"106790274378320830963\",\n \"displayName\": \"AspnetvnextTest AspnetvnextTest\",\n \"name\": {\n  \"familyName\": \"AspnetvnextTest\",\n  \"givenName\": \"FirstName\"\n },\n \"url\": \"https://plus.google.com/106790274378320830963\",\n \"image\": {\n  \"url\": \"https://lh3.googleusercontent.com/-XdUIqdMkCWA/AAAAAAAAAAI/AAAAAAAAAAA/4252rscbv5M/photo.jpg?sz=50\"\n },\n \"isPlusUser\": true,\n \"language\": \"en\",\n \"circledByCount\": 0,\n \"verified\": false\n}\n", Encoding.UTF8, "application/json");
                }
                else
                {
                    response.Content = new StringContent("{\"error\":{\"message\":\"Invalid OAuth access token.\",\"type\":\"OAuthException\",\"code\":190}}");
                }
                return(response);
            }

            throw new NotImplementedException(request.RequestUri.AbsoluteUri);
        }
        public async Task <IActionResult> New(IFormCollection form, [FromServices] ILoanManagement loanManagement)
        {
            JsonElement loanJson        = JsonDocument.Parse(FormReader.GetLoanJson(form)).RootElement;
            JsonElement collateralsJson = JsonDocument.Parse($"[{FormReader.GetCollateralJson(form, _logger)}]").RootElement;

            _logger.LogInformation(collateralsJson.GetRawText());

            try
            {
                //return Ok(await loanManagement.SaveWithCollaterals(loanJson, collateralsJson));
                if (await loanManagement.SaveWithCollaterals(loanJson, collateralsJson))
                {
                    int newLoanId = FormReader.GetLoan(form).Id;
                    return(RedirectToAction(actionName: nameof(LoanController.ViewLoan), new { id = newLoanId }));
                }
                //return Ok("loan and collaterals saved successfully");
                else
                {
                    return(StatusCode((int)HttpStatusCode.InternalServerError, new { error = "error occurred while saving loan and collaterals" }));
                }
            }
            catch (HttpRequestException) { return(StatusCode((int)HttpStatusCode.ServiceUnavailable, new { error = "cannot connect with LoanManagementApi" })); }
            catch (UnexpectedResponseException e) { return(StatusCode((int)HttpStatusCode.InternalServerError, new { error = e.Message })); }
        }
Esempio n. 16
0
        private async Task <AccessToken> ObtainAccessTokenAsync(string consumerKey, string consumerSecret, RequestToken token, string verifier)
        {
            // https://dev.twitter.com/docs/api/1/post/oauth/access_token

            Logger.LogVerbose("ObtainAccessToken");

            var nonce = Guid.NewGuid().ToString("N");

            var authorizationParts = new SortedDictionary <string, string>
            {
                { "oauth_consumer_key", consumerKey },
                { "oauth_nonce", nonce },
                { "oauth_signature_method", "HMAC-SHA1" },
                { "oauth_token", token.Token },
                { "oauth_timestamp", GenerateTimeStamp() },
                { "oauth_verifier", verifier },
                { "oauth_version", "1.0" },
            };

            var parameterBuilder = new StringBuilder();

            foreach (var authorizationKey in authorizationParts)
            {
                parameterBuilder.AppendFormat("{0}={1}&", UrlEncoder.UrlEncode(authorizationKey.Key), UrlEncoder.UrlEncode(authorizationKey.Value));
            }
            parameterBuilder.Length--;
            var parameterString = parameterBuilder.ToString();

            var canonicalizedRequestBuilder = new StringBuilder();

            canonicalizedRequestBuilder.Append(HttpMethod.Post.Method);
            canonicalizedRequestBuilder.Append("&");
            canonicalizedRequestBuilder.Append(UrlEncoder.UrlEncode(AccessTokenEndpoint));
            canonicalizedRequestBuilder.Append("&");
            canonicalizedRequestBuilder.Append(UrlEncoder.UrlEncode(parameterString));

            var signature = ComputeSignature(consumerSecret, token.TokenSecret, canonicalizedRequestBuilder.ToString());

            authorizationParts.Add("oauth_signature", signature);
            authorizationParts.Remove("oauth_verifier");

            var authorizationHeaderBuilder = new StringBuilder();

            authorizationHeaderBuilder.Append("OAuth ");
            foreach (var authorizationPart in authorizationParts)
            {
                authorizationHeaderBuilder.AppendFormat(
                    "{0}=\"{1}\", ", authorizationPart.Key, UrlEncoder.UrlEncode(authorizationPart.Value));
            }
            authorizationHeaderBuilder.Length = authorizationHeaderBuilder.Length - 2;

            var request = new HttpRequestMessage(HttpMethod.Post, AccessTokenEndpoint);

            request.Headers.Add("Authorization", authorizationHeaderBuilder.ToString());

            var formPairs = new Dictionary <string, string>()
            {
                { "oauth_verifier", verifier },
            };

            request.Content = new FormUrlEncodedContent(formPairs);

            var response = await _httpClient.SendAsync(request, Context.RequestAborted);

            if (!response.IsSuccessStatusCode)
            {
                Logger.LogError("AccessToken request failed with a status code of " + response.StatusCode);
                response.EnsureSuccessStatusCode(); // throw
            }

            var responseText = await response.Content.ReadAsStringAsync();

            var responseParameters = new FormCollection(FormReader.ReadForm(responseText));

            return(new AccessToken
            {
                Token = Uri.UnescapeDataString(responseParameters["oauth_token"]),
                TokenSecret = Uri.UnescapeDataString(responseParameters["oauth_token_secret"]),
                UserId = Uri.UnescapeDataString(responseParameters["user_id"]),
                ScreenName = Uri.UnescapeDataString(responseParameters["screen_name"])
            });
        }
Esempio n. 17
0
        private async Task <RequestToken> ObtainRequestTokenAsync(string consumerKey, string consumerSecret, string callBackUri, AuthenticationProperties properties)
        {
            Logger.LogVerbose("ObtainRequestToken");

            var nonce = Guid.NewGuid().ToString("N");

            var authorizationParts = new SortedDictionary <string, string>
            {
                { "oauth_callback", callBackUri },
                { "oauth_consumer_key", consumerKey },
                { "oauth_nonce", nonce },
                { "oauth_signature_method", "HMAC-SHA1" },
                { "oauth_timestamp", GenerateTimeStamp() },
                { "oauth_version", "1.0" }
            };

            var parameterBuilder = new StringBuilder();

            foreach (var authorizationKey in authorizationParts)
            {
                parameterBuilder.AppendFormat("{0}={1}&", UrlEncoder.UrlEncode(authorizationKey.Key), UrlEncoder.UrlEncode(authorizationKey.Value));
            }
            parameterBuilder.Length--;
            var parameterString = parameterBuilder.ToString();

            var canonicalizedRequestBuilder = new StringBuilder();

            canonicalizedRequestBuilder.Append(HttpMethod.Post.Method);
            canonicalizedRequestBuilder.Append("&");
            canonicalizedRequestBuilder.Append(UrlEncoder.UrlEncode(RequestTokenEndpoint));
            canonicalizedRequestBuilder.Append("&");
            canonicalizedRequestBuilder.Append(UrlEncoder.UrlEncode(parameterString));

            var signature = ComputeSignature(consumerSecret, null, canonicalizedRequestBuilder.ToString());

            authorizationParts.Add("oauth_signature", signature);

            var authorizationHeaderBuilder = new StringBuilder();

            authorizationHeaderBuilder.Append("OAuth ");
            foreach (var authorizationPart in authorizationParts)
            {
                authorizationHeaderBuilder.AppendFormat(
                    "{0}=\"{1}\", ", authorizationPart.Key, UrlEncoder.UrlEncode(authorizationPart.Value));
            }
            authorizationHeaderBuilder.Length = authorizationHeaderBuilder.Length - 2;

            var request = new HttpRequestMessage(HttpMethod.Post, RequestTokenEndpoint);

            request.Headers.Add("Authorization", authorizationHeaderBuilder.ToString());

            var response = await _httpClient.SendAsync(request, Context.RequestAborted);

            response.EnsureSuccessStatusCode();
            string responseText = await response.Content.ReadAsStringAsync();

            var responseParameters = new FormCollection(FormReader.ReadForm(responseText));

            if (string.Equals(responseParameters["oauth_callback_confirmed"], "true", StringComparison.Ordinal))
            {
                return(new RequestToken {
                    Token = Uri.UnescapeDataString(responseParameters["oauth_token"]), TokenSecret = Uri.UnescapeDataString(responseParameters["oauth_token_secret"]), CallbackConfirmed = true, Properties = properties
                });
            }

            return(new RequestToken());
        }
Esempio n. 18
0
        public async Task BindModelAsync(ModelBindingContext bindingContext)
        {
            var request = bindingContext.HttpContext.Request;

            if (request.ContentType != null)
            {
                var contentType = MediaTypeHeaderValue.Parse(request.ContentType);
                if (contentType.MediaType == BinarySerializer.MEDIA_TYPE)
                {
                    bindingContext.Result = ModelBindingResult.Success(await DeserializeBinary(request.Body, bindingContext));
                    return;
                }
                else if (contentType.MediaType == "multipart/form-data")
                {
                    object obj = null;

                    if (contentType.Boundary == null)
                    {
                        throw new InvalidOperationException("MultiPartBoundary not found");
                    }

                    var boundary = HeaderUtilities.RemoveQuotes(contentType.Boundary).Value;

                    var reader  = new MultipartReader(boundary, request.Body);
                    var section = await reader.ReadNextSectionAsync();

                    while (section != null)
                    {
                        ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);
                        MediaTypeHeaderValue.TryParse(section.ContentType, out contentType);

                        if (contentDisposition == null)
                        {
                            continue;
                        }

                        if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                        {
                            //json body
                            if (contentType?.MediaType == "application/json")
                            {
                                var json = await section.ReadAsStringAsync();

                                obj = JsonConvert.DeserializeObject(json, bindingContext.ModelType);
                            }
                            else if (contentType?.MediaType == BinarySerializer.MEDIA_TYPE)
                            {
                                obj = await DeserializeBinary(section.Body, bindingContext);
                            }
                            else
                            {
                                obj ??= Activator.CreateInstance(bindingContext.ModelType);

                                //form value
                                var sectionValue = await section.AsFormDataSection().GetValueAsync();

                                var formReader = new FormReader(sectionValue);
                                var form       = formReader.ReadForm();

                                if (form.Count == 0)
                                {
                                    if (contentDisposition.Name != null)
                                    {
                                        SetValue(bindingContext, obj, sectionValue, contentDisposition.Name.Value);
                                    }
                                }
                                else
                                {
                                    foreach (var value in form)
                                    {
                                        SetValue(bindingContext, obj, value.Value.ToString(), value.Key);
                                    }
                                }
                            }
                        }
                        else if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                        {
                            var stream = new MemoryStream();
                            await section.AsFileSection().FileStream.CopyToAsync(stream);

                            stream.Position = 0;

                            if (bindingContext.ModelType == typeof(Stream))
                            {
                                obj = stream;
                            }
                            else
                            {
                                obj ??= Activator.CreateInstance(bindingContext.ModelType);
                                SetValue(bindingContext, obj, stream, contentDisposition.Name.Value);
                            }
                        }

                        section = await reader.ReadNextSectionAsync();
                    }

                    bindingContext.Result = ModelBindingResult.Success(obj);
                    return;
                }
                else
                {
                    bindingContext.Result = ModelBindingResult.Failed();
                    return;
                }
            }
            else if (bindingContext.ModelType == typeof(Stream))
            {
                bindingContext.Result = ModelBindingResult.Success(request.Body);
                return;
            }

            bindingContext.Result = ModelBindingResult.Failed();
        }
Esempio n. 19
0
        private async Task <IFormCollection> InnerReadFormAsync(CancellationToken cancellationToken)
        {
            if (!HasFormContentType)
            {
                throw new InvalidOperationException("Incorrect Content-Type: " + _request.ContentType);
            }

            cancellationToken.ThrowIfCancellationRequested();

            //if (_options.BufferBody)
            //{
            //    _request.EnableRewind(_options.MemoryBufferThreshold, _options.BufferBodyLengthLimit);
            //}

            FormCollection     formFields = null;
            FormFileCollection files      = null;

            // Some of these code paths use StreamReader which does not support cancellation tokens.
            using (cancellationToken.Register((state) => ((HttpContext)state).Abort(), _request.HttpContext))
            {
                var contentType = ContentType;
                // Check the content-type
                if (HasApplicationFormContentType(contentType))
                {
                    var encoding = FilterEncoding(contentType.Encoding);
                    using (var formReader = new FormReader(_request.Body, encoding)
                    {
                        ValueCountLimit = _options.ValueCountLimit,
                        KeyLengthLimit = _options.KeyLengthLimit,
                        ValueLengthLimit = _options.ValueLengthLimit,
                    })
                    {
                        formFields = new FormCollection(await formReader.ReadFormAsync(cancellationToken));
                    }
                }
                else if (HasMultipartFormContentType(contentType))
                {
                    var formAccumulator = new KeyValueAccumulator();

                    var boundary        = GetBoundary(contentType, _options.MultipartBoundaryLengthLimit);
                    var multipartReader = new MultipartReader(boundary, _request.Body)
                    {
                        HeadersCountLimit  = _options.MultipartHeadersCountLimit,
                        HeadersLengthLimit = _options.MultipartHeadersLengthLimit,
                        BodyLengthLimit    = _options.MultipartBodyLengthLimit,
                    };
                    var section = await multipartReader.ReadNextSectionAsync(cancellationToken);

                    while (section != null)
                    {
                        // Parse the content disposition here and pass it further to avoid reparsings
                        ContentDispositionHeaderValue contentDisposition;
                        ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition);

                        if (contentDisposition.IsFileDisposition())
                        {
                            var fileSection = new FileMultipartSection(section, contentDisposition);

                            FormFile file;
                            if (section.Body.CanSeek)
                            {
                                // Find the end
                                await section.Body.ConsumeAsync(cancellationToken);

                                var name     = fileSection.Name;
                                var fileName = fileSection.FileName;


                                if (section.BaseStreamOffset.HasValue)
                                {
                                    // Relative reference to buffered request body
                                    file = new StreamFormFile(_request.Body, section.BaseStreamOffset.Value, section.Body.Length, name, fileName);
                                }
                                else
                                {
                                    // Individually buffered file body
                                    file = new StreamFormFile(section.Body, 0, section.Body.Length, name, fileName);
                                }
                                file.Headers = new HeaderDictionary(section.Headers);
                            }
                            else
                            {
                                //// Enable buffering for the file if not already done for the full body
                                //section.EnableRewind(
                                //    _request.HttpContext.Response.RegisterForDispose,
                                //    _options.MemoryBufferThreshold, _options.MultipartBodyLengthLimit);

                                //read all bytes.
                                var bytes = await section.Body.ReadAllBytesAsync(cancellationToken);

                                var name     = fileSection.Name;
                                var fileName = fileSection.FileName;

                                if (section.BaseStreamOffset.HasValue)
                                {
                                    // Relative reference to buffered request body
                                    file = new BufferedFormFile(new ArraySegment <byte>(bytes, (int)section.BaseStreamOffset.Value, (int)section.Body.Length), name, fileName);
                                }
                                else
                                {
                                    // Individually buffered file body
                                    file = new BufferedFormFile(new ArraySegment <byte>(bytes, 0, (int)section.Body.Length), name, fileName);
                                }
                                file.Headers = new HeaderDictionary(section.Headers);
                            }

                            if (files == null)
                            {
                                files = new FormFileCollection();
                            }
                            if (files.Count >= _options.ValueCountLimit)
                            {
                                throw new InvalidDataException($"Form value count limit {_options.ValueCountLimit} exceeded.");
                            }
                            files.Add(file);
                        }
                        else if (contentDisposition.IsFormDisposition())
                        {
                            var formDataSection = new FormMultipartSection(section, contentDisposition);

                            // Content-Disposition: form-data; name="key"
                            //
                            // value

                            // Do not limit the key name length here because the mulipart headers length limit is already in effect.
                            var key   = formDataSection.Name;
                            var value = await formDataSection.GetValueAsync();

                            formAccumulator.Append(key, value);
                            if (formAccumulator.ValueCount > _options.ValueCountLimit)
                            {
                                throw new InvalidDataException($"Form value count limit {_options.ValueCountLimit} exceeded.");
                            }
                        }
                        else
                        {
                            System.Diagnostics.Debug.Assert(false, "Unrecognized content-disposition for this section: " + section.ContentDisposition);
                        }

                        section = await multipartReader.ReadNextSectionAsync(cancellationToken);
                    }

                    if (formAccumulator.HasValues)
                    {
                        formFields = new FormCollection(formAccumulator.GetResults(), files);
                    }
                }
            }

            // Rewind so later readers don't have to.
            if (_request.Body.CanSeek)
            {
                _request.Body.Seek(0, SeekOrigin.Begin);
            }

            if (formFields != null)
            {
                Form = formFields;
            }
            else if (files != null)
            {
                Form = new FormCollection(null, files);
            }
            else
            {
                Form = FormCollection.Empty;
            }

            return(Form);
        }
Esempio n. 20
0
    public async Task PkceSentToTokenEndpoint()
    {
        using var host = await CreateHost(o =>
        {
            o.ClientId               = "Test Client Id";
            o.ClientSecret           = "Test Client Secret";
            o.BackchannelHttpHandler = new TestHttpMessageHandler
            {
                Sender = req =>
                {
                    if (req.RequestUri.AbsoluteUri == "https://login.microsoftonline.com/common/oauth2/v2.0/token")
                    {
                        var body    = req.Content.ReadAsStringAsync().Result;
                        var form    = new FormReader(body);
                        var entries = form.ReadForm();
                        Assert.Equal("Test Client Id", entries["client_id"]);
                        Assert.Equal("https://example.com/signin-microsoft", entries["redirect_uri"]);
                        Assert.Equal("Test Client Secret", entries["client_secret"]);
                        Assert.Equal("TestCode", entries["code"]);
                        Assert.Equal("authorization_code", entries["grant_type"]);
                        Assert.False(string.IsNullOrEmpty(entries["code_verifier"]));

                        return(ReturnJsonResponse(new
                        {
                            access_token = "Test Access Token",
                            expire_in = 3600,
                            token_type = "Bearer",
                        }));
                    }
                    else if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == "https://graph.microsoft.com/v1.0/me")
                    {
                        return(ReturnJsonResponse(new
                        {
                            id = "Test User ID",
                            displayName = "Test Name",
                            givenName = "Test Given Name",
                            surname = "Test Family Name",
                            mail = "Test email"
                        }));
                    }

                    return(null);
                }
            };
        });

        using var server = host.GetTestServer();
        var transaction = await server.SendAsync("https://example.com/challenge");

        Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
        var locationUri = transaction.Response.Headers.Location;

        Assert.StartsWith("https://login.microsoftonline.com/common/oauth2/v2.0/authorize", locationUri.AbsoluteUri);

        var queryParams = QueryHelpers.ParseQuery(locationUri.Query);

        Assert.False(string.IsNullOrEmpty(queryParams["code_challenge"]));
        Assert.Equal("S256", queryParams["code_challenge_method"]);

        var nonceCookie = transaction.SetCookie.Single();

        nonceCookie = nonceCookie.Substring(0, nonceCookie.IndexOf(';'));

        transaction = await server.SendAsync(
            "https://example.com/signin-microsoft?code=TestCode&state=" + queryParams["state"],
            nonceCookie);

        Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
        Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First());
        Assert.Equal(2, transaction.SetCookie.Count);
        Assert.StartsWith(".AspNetCore.Correlation.", transaction.SetCookie[0]);
        Assert.StartsWith(".AspNetCore." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]);
    }
Esempio n. 21
0
 protected override async Task <Dictionary <string, StringValues> > ReadFormAsync(FormReader reader)
 {
     return(await reader.ReadFormAsync());
 }
Esempio n. 22
0
 protected override async Task <KeyValuePair <string, string>?> ReadPair(FormReader reader)
 {
     return(await reader.ReadNextPairAsync());
 }
Esempio n. 23
0
        public async Task <IActionResult> AuthorizePost(string transactionId)
        {
            var result = await connector.ExecuteTransaction(transactionId,
                                                            async payload =>
            {
                var formReader     = new FormReader(payload);
                var values         = await formReader.ReadFormAsync().ConfigureAwait(false);
                var formCollection = new FormCollection(values);

                var amount     = decimal.Parse(formCollection["Amount"].Single());
                var customerId = formCollection["CustomerId"].Single();

                return(new AuthorizeRequest
                {
                    CustomerId = customerId,
                    TransactionId = transactionId,
                    Amount = amount
                }, customerId.Substring(0, 2));
            },
                                                            async session =>
            {
                Account account;
                try
                {
                    account = await session.TransactionContext.Batch()
                              .ReadItemAsync <Account>(session.Payload.CustomerId);
                }
                catch (CosmosException e)
                {
                    if (e.StatusCode == HttpStatusCode.NotFound)
                    {
                        account = new Account
                        {
                            Number       = session.Payload.CustomerId,
                            Partition    = session.Payload.CustomerId.Substring(0, 2),
                            Balance      = 0,
                            Transactions = new List <Transaction>()
                        };
                    }
                    else
                    {
                        throw new Exception("Error while loading account data", e);
                    }
                }

                account.Balance -= session.Payload.Amount;
                session.TransactionContext.Batch().UpsertItem(account);
                await session.Send(new SettleTransaction
                {
                    AccountNumber = account.Number,
                    Amount        = session.Payload.Amount,
                    TransactionId = transactionId
                });

                return(new StoredResponse(200, null));
            });

            if (result.Body != null)
            {
                Response.Body = result.Body;
            }
            return(StatusCode(result.Code));
        }
Esempio n. 24
0
        public async Task <IFormCollection> ReadFormAsync(CancellationToken cancellationToken)
        {
            if (Form != null)
            {
                return(Form);
            }

            if (!HasFormContentType)
            {
                throw new InvalidOperationException("Incorrect Content-Type: " + _request.ContentType);
            }

            cancellationToken.ThrowIfCancellationRequested();

            _request.EnableRewind();

            IDictionary <string, string[]> formFields = null;
            var files = new FormFileCollection();

            // Some of these code paths use StreamReader which does not support cancellation tokens.
            using (cancellationToken.Register(_request.HttpContext.Abort))
            {
                var contentType = ContentType;
                // Check the content-type
                if (HasApplicationFormContentType(contentType))
                {
                    var encoding = FilterEncoding(contentType.Encoding);
                    formFields = await FormReader.ReadFormAsync(_request.Body, encoding, cancellationToken);
                }
                else if (HasMultipartFormContentType(contentType))
                {
                    var formAccumulator = new KeyValueAccumulator <string, string>(StringComparer.OrdinalIgnoreCase);

                    var boundary        = GetBoundary(contentType);
                    var multipartReader = new MultipartReader(boundary, _request.Body);
                    var section         = await multipartReader.ReadNextSectionAsync(cancellationToken);

                    while (section != null)
                    {
                        var headers = new HeaderDictionary(section.Headers);
                        ContentDispositionHeaderValue contentDisposition;
                        ContentDispositionHeaderValue.TryParse(headers.Get(HeaderNames.ContentDisposition), out contentDisposition);
                        if (HasFileContentDisposition(contentDisposition))
                        {
                            // Find the end
                            await section.Body.DrainAsync(cancellationToken);

                            var file = new FormFile(_request.Body, section.BaseStreamOffset.Value, section.Body.Length)
                            {
                                Headers = headers,
                            };
                            files.Add(file);
                        }
                        else if (HasFormDataContentDisposition(contentDisposition))
                        {
                            // Content-Disposition: form-data; name="key"
                            //
                            // value

                            var key = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                            MediaTypeHeaderValue mediaType;
                            MediaTypeHeaderValue.TryParse(headers.Get(HeaderNames.ContentType), out mediaType);
                            var encoding = FilterEncoding(mediaType?.Encoding);
                            using (var reader = new StreamReader(section.Body, encoding, detectEncodingFromByteOrderMarks: true, bufferSize: 1024, leaveOpen: true))
                            {
                                var value = await reader.ReadToEndAsync();

                                formAccumulator.Append(key, value);
                            }
                        }
                        else
                        {
                            System.Diagnostics.Debug.Assert(false, "Unrecognized content-disposition for this section: " + headers.Get(HeaderNames.ContentDisposition));
                        }

                        section = await multipartReader.ReadNextSectionAsync(cancellationToken);
                    }

                    formFields = formAccumulator.GetResults();
                }
            }

            Form = new FormCollection(formFields, files);
            return(Form);
        }
Esempio n. 25
0
        public static IEndpointConventionBuilder UseFilteredAutoForeignKeys(this IEndpointRouteBuilder builder, string explicitTenantParam, bool forAreas, bool withAuthorization = true)
        {
            bool forExplicitTenants = !string.IsNullOrEmpty(explicitTenantParam);

            ContextExtensions.Init();
            RequestDelegate dlg = async context =>
            {
                //{{connection:regex(^[\\w_]+$)}}/{{table:regex(^[\\w_]+$)}}
                RouteData        routeData        = context.GetRouteData();
                ActionDescriptor actionDescriptor = new ActionDescriptor();
                ActionContext    actionContext    = new ActionContext(context, routeData, actionDescriptor);
                var ok = !withAuthorization || context.RequestServices.VerifyCurrentUser();
                if (ok)
                {
                    if (context.Request.RouteValues.ContainsKey("dataResolveHint"))
                    {
                        var baseHint = ((string)context.Request.RouteValues["dataResolveHint"])?.Split("/")
                                       .Select(n => HttpUtility.UrlDecode(n)).ToArray();
                        if (baseHint is { Length : 2 })
                        {
                            string area = null;
                            if (context.Request.RouteValues.ContainsKey("area"))
                            {
                                area = (string)context.Request.RouteValues["area"];
                            }

                            var connection =
                                RegexValidate(baseHint[0], "^[\\w_]+$")
                                    ? baseHint[0]
                                    : null; //(string) context.Request.RouteValues["connection"];
                            var dbContext = context.RequestServices.ContextForFkQuery(connection, area);
                            if (dbContext != null)
                            {
                                var table = RegexValidate(baseHint[1], dbContext.CustomFkSettings?.CustomTableValidation ?? "^[\\w_]+$")
                                    ? baseHint[1]
                                    : null; //(string) context.Request.RouteValues["table"];

                                FormReader former          = new FormReader(context.Request.Body);
                                var        formsDictionary = await former.ReadFormAsync();

                                //LogEnvironment.LogEvent(Stringify(formsDictionary), LogSeverity.Report);
                                var        newDic     = TranslateForm(formsDictionary, true);
                                JsonResult result     = null;
                                bool       authorized = true;
                                try
                                {
                                    result = new JsonResult(dbContext.ReadForeignKey(table, postedFilter: newDic)
                                                            .ToDummyDataSourceResult());
                                }
                                catch (SecurityException)
                                {
                                    authorized = false;
                                }

                                if (authorized)
                                {
                                    await result.ExecuteResultAsync(actionContext);

                                    return;
                                }

                                UnauthorizedResult ill = new UnauthorizedResult();
                                await ill.ExecuteResultAsync(actionContext);

                                return;
                            }
                        }
                    }
Esempio n. 26
0
        public static void Run()
        {
            var host = new WebHostBuilder()
                       .UseUrls("http://*:5000")
                       .ConfigureServices(services =>
            {
                // Use a custom server
                services.AddTransient <IServer, HttpServer>();
            })
                       // .UseKestrel()
                       .Configure(app =>
            {
                var view = @"
<html>
<head>
<title></title>
</head>
<body>
<form action="""" method=""post"">
    Username:<input type=""text"" name=""username"">
    Password:<input type=""password"" name=""password"">
    <input type=""submit"" value=""Login"">
</form>
</body>
</html>";
                app.Run(async context =>
                {
                    if (!string.Equals(context.Request.Method, "GET", StringComparison.OrdinalIgnoreCase))
                    {
                        var contentLength = context.Request.ContentLength;

                        // Access the raw connection
                        var connection = context.Features.Get <ITcpConnectionFeature>();

                        var reader = new FormReader(contentLength);

                        // Reads the form body
                        while (true)
                        {
                            var buffer = await connection.Input.ReadAsync();

                            try
                            {
                                if (buffer.IsEmpty && connection.Input.Completion.IsCompleted)
                                {
                                    // Connection closed
                                    return;
                                }

                                if (reader.TryParse(ref buffer))
                                {
                                    break;
                                }
                            }
                            finally
                            {
                                buffer.Consumed();
                            }
                        }

                        foreach (var item in reader.FormValues)
                        {
                            Console.WriteLine($"{item.Key}={item.Value}");
                        }

                        // This is the idiomatic approach
                        // var form = await context.Request.ReadFormAsync();
                    }
                    context.Response.ContentLength = view.Length;
                    await context.Response.WriteAsync(view);
                });
            })
                       .Build();

            host.Run();
        }
Esempio n. 27
0
        public async Task Register(ModificationContext modificationContext, IJSEngine engine)
        {
            FormCollection formFields = null;

            MediaTypeHeaderValue contentType;

            MediaTypeHeaderValue.TryParse(modificationContext.ContentType, out contentType);

            _originalEncoding = contentType?.Encoding ?? Encoding.UTF8;

            if (HasApplicationFormContentType(contentType))
            {
                var encoding = FilterEncoding(contentType.Encoding);

                using (var formReader = new FormReader(modificationContext.ContentStream, encoding)
                {
                    ValueCountLimit = _options.Value.FormOptions.ValueCountLimit,
                    KeyLengthLimit = _options.Value.FormOptions.KeyLengthLimit,
                    ValueLengthLimit = _options.Value.FormOptions.ValueLengthLimit,
                })
                {
                    formFields = new FormCollection(await formReader.ReadFormAsync());
                }
            }
            else if (HasMultipartFormContentType(contentType))
            {
                _isMultiPart = true;

                _originalBoundary = GetBoundary(contentType, _options.Value.FormOptions.MultipartBoundaryLengthLimit);

                formFields = await GetMultipartFormCollection(modificationContext);
            }

            _internalForm = formFields ?? FormCollection.Empty;

            if (modificationContext.ContentStream.CanSeek)
            {
                modificationContext.ContentStream.Seek(0, SeekOrigin.Begin);
            }

            _formFieldContainer = new Dictionary <string, List <string> >();

            foreach (var field in _internalForm)
            {
                foreach (var value in field.Value)
                {
                    if (_formFieldContainer.ContainsKey(field.Key))
                    {
                        _formFieldContainer[field.Key].Add(value);
                    }
                    else
                    {
                        _formFieldContainer.Add(field.Key, new List <string> {
                            value
                        });
                    }
                }
            }

            engine.InitializeFormApi(_formFieldContainer, _formFiles);
        }
Esempio n. 28
0
 protected virtual Task <Dictionary <string, StringValues> > ReadFormAsync(FormReader reader)
 {
     return(Task.FromResult(reader.ReadForm()));
 }
Esempio n. 29
0
 protected virtual Task <KeyValuePair <string, string>?> ReadPair(FormReader reader)
 {
     return(Task.FromResult(reader.ReadNextPair()));
 }
        private async Task <IFormCollection> InnerReadFormAsync(CancellationToken cancellationToken)
        {
            if (!HasFormContentType)
            {
                throw new InvalidOperationException("Incorrect Content-Type: " + _request.ContentType);
            }

            cancellationToken.ThrowIfCancellationRequested();

            if (_options.BufferBody)
            {
                _request.EnableRewind(_options.MemoryBufferThreshold, _options.BufferBodyLengthLimit);
            }

            FormCollection     formFields = null;
            FormFileCollection files      = null;

            // Some of these code paths use StreamReader which does not support cancellation tokens.
            using (cancellationToken.Register((state) => ((HttpContext)state).Abort(), _request.HttpContext))
            {
                var contentType = ContentType;
                // Check the content-type
                if (HasApplicationFormContentType(contentType))
                {
                    var encoding = FilterEncoding(contentType.Encoding);
                    using (var formReader = new FormReader(_request.Body, encoding)
                    {
                        ValueCountLimit = _options.ValueCountLimit,
                        KeyLengthLimit = _options.KeyLengthLimit,
                        ValueLengthLimit = _options.ValueLengthLimit,
                    })
                    {
                        formFields = new FormCollection(await formReader.ReadFormAsync(cancellationToken));
                    }
                }
                else if (HasMultipartFormContentType(contentType))
                {
                    var formAccumulator = new KeyValueAccumulator();

                    var boundary        = GetBoundary(contentType, _options.MultipartBoundaryLengthLimit);
                    var multipartReader = new MultipartReader(boundary, _request.Body)
                    {
                        HeadersCountLimit  = _options.MultipartHeadersCountLimit,
                        HeadersLengthLimit = _options.MultipartHeadersLengthLimit,
                        BodyLengthLimit    = _options.MultipartBodyLengthLimit,
                    };
                    var section = await multipartReader.ReadNextSectionAsync(cancellationToken);

                    while (section != null)
                    {
                        ContentDispositionHeaderValue contentDisposition;
                        ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition);
                        if (HasFileContentDisposition(contentDisposition))
                        {
                            // Enable buffering for the file if not already done for the full body
                            section.EnableRewind(_request.HttpContext.Response.RegisterForDispose,
                                                 _options.MemoryBufferThreshold, _options.MultipartBodyLengthLimit);
                            // Find the end
                            await section.Body.DrainAsync(cancellationToken);

                            var name     = HeaderUtilities.RemoveQuotes(contentDisposition.Name) ?? string.Empty;
                            var fileName = HeaderUtilities.RemoveQuotes(contentDisposition.FileName) ?? string.Empty;

                            FormFile file;
                            if (section.BaseStreamOffset.HasValue)
                            {
                                // Relative reference to buffered request body
                                file = new FormFile(_request.Body, section.BaseStreamOffset.Value, section.Body.Length, name, fileName);
                            }
                            else
                            {
                                // Individually buffered file body
                                file = new FormFile(section.Body, 0, section.Body.Length, name, fileName);
                            }
                            file.Headers = new HeaderDictionary(section.Headers);

                            if (files == null)
                            {
                                files = new FormFileCollection();
                            }
                            if (files.Count >= _options.ValueCountLimit)
                            {
                                throw new InvalidDataException($"Form value count limit {_options.ValueCountLimit} exceeded.");
                            }
                            files.Add(file);
                        }
                        else if (HasFormDataContentDisposition(contentDisposition))
                        {
                            // Content-Disposition: form-data; name="key"
                            //
                            // value

                            // Do not limit the key name length here because the mulipart headers length limit is already in effect.
                            var key = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                            MediaTypeHeaderValue mediaType;
                            MediaTypeHeaderValue.TryParse(section.ContentType, out mediaType);
                            var encoding = FilterEncoding(mediaType?.Encoding);
                            using (var reader = new StreamReader(section.Body, encoding, detectEncodingFromByteOrderMarks: true, bufferSize: 1024, leaveOpen: true))
                            {
                                // The value length limit is enforced by MultipartBodyLengthLimit
                                var value = await reader.ReadToEndAsync();

                                formAccumulator.Append(key, value);
                                if (formAccumulator.ValueCount > _options.ValueCountLimit)
                                {
                                    throw new InvalidDataException($"Form value count limit {_options.ValueCountLimit} exceeded.");
                                }
                            }
                        }
                        else
                        {
                            System.Diagnostics.Debug.Assert(false, "Unrecognized content-disposition for this section: " + section.ContentDisposition);
                        }

                        section = await multipartReader.ReadNextSectionAsync(cancellationToken);
                    }

                    if (formAccumulator.HasValues)
                    {
                        formFields = new FormCollection(formAccumulator.GetResults(), files);
                    }
                }
            }

            // Rewind so later readers don't have to.
            if (_request.Body.CanSeek)
            {
                _request.Body.Seek(0, SeekOrigin.Begin);
            }

            if (formFields != null)
            {
                Form = formFields;
            }
            else if (files != null)
            {
                Form = new FormCollection(null, files);
            }
            else
            {
                Form = FormCollection.Empty;
            }

            return(Form);
        }