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()); }
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; } }
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); }
/// <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)); }
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)); }
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); } }
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); }
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 })); } }
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"]) }); }
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()); }
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(); }
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); }
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]); }
protected override async Task <Dictionary <string, StringValues> > ReadFormAsync(FormReader reader) { return(await reader.ReadFormAsync()); }
protected override async Task <KeyValuePair <string, string>?> ReadPair(FormReader reader) { return(await reader.ReadNextPairAsync()); }
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)); }
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); }
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; } } }
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(); }
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); }
protected virtual Task <Dictionary <string, StringValues> > ReadFormAsync(FormReader reader) { return(Task.FromResult(reader.ReadForm())); }
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); }