From db1290e83c45ef4f97cdc65952fac330969f9b6c Mon Sep 17 00:00:00 2001 From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com> Date: Tue, 6 Dec 2022 19:53:44 -0500 Subject: [PATCH 1/3] use XDocument directly for TwiMLResult.cs --- .../MinimalApiTwiMLResult.cs | 3 ++- src/Twilio.AspNet.Core/TwiMLResult.cs | 24 ++++++++++++------- .../Twilio.AspNet.Core.csproj | 2 +- .../Twilio.AspNet.Mvc.UnitTests.csproj | 2 +- src/Twilio.AspNet.Mvc/TwiMLResult.cs | 9 ++----- .../Twilio.AspNet.Mvc.csproj | 2 +- .../AspNetFramework/AspNetFramework.csproj | 4 ++-- src/testapps/AspNetFramework/packages.config | 2 +- 8 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/Twilio.AspNet.Core/MinimalApiTwiMLResult.cs b/src/Twilio.AspNet.Core/MinimalApiTwiMLResult.cs index 6b5e9f7..a519615 100644 --- a/src/Twilio.AspNet.Core/MinimalApiTwiMLResult.cs +++ b/src/Twilio.AspNet.Core/MinimalApiTwiMLResult.cs @@ -41,5 +41,6 @@ public partial class TwiMLResult : IResult /// Writes the TwiML to the HTTP response body /// /// The HttpContext containing the Response to write the TwiML to - public Task ExecuteAsync(HttpContext httpContext) => WriteTwiMLToResponse(httpContext.Response); + public Task ExecuteAsync(HttpContext httpContext) + => WriteTwiMLToResponse(httpContext.Response, httpContext.RequestAborted); } \ No newline at end of file diff --git a/src/Twilio.AspNet.Core/TwiMLResult.cs b/src/Twilio.AspNet.Core/TwiMLResult.cs index 9f6f648..72d9157 100644 --- a/src/Twilio.AspNet.Core/TwiMLResult.cs +++ b/src/Twilio.AspNet.Core/TwiMLResult.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Threading; +using System.Threading.Tasks; using System.Xml.Linq; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; @@ -17,7 +18,7 @@ public partial class TwiMLResult : IActionResult public TwiMLResult(TwiML.TwiML twiml) : this(twiml, SaveOptions.None) { } - + /// The TwiML to respond with /// Specifies how to format TwiML public TwiMLResult(TwiML.TwiML twiml, SaveOptions formattingOptions) @@ -29,20 +30,25 @@ public TwiMLResult(TwiML.TwiML twiml, SaveOptions formattingOptions) public async Task ExecuteResultAsync(ActionContext actionContext) { var response = actionContext.HttpContext.Response; - await WriteTwiMLToResponse(response); + await WriteTwiMLToResponse(response, actionContext.HttpContext.RequestAborted); } - - private async Task WriteTwiMLToResponse(HttpResponse response) + + private async Task WriteTwiMLToResponse(HttpResponse response, CancellationToken cancellationToken) { response.ContentType = "application/xml"; if (twiml == null) { - await response.WriteAsync(""); + await response.WriteAsync("", cancellationToken); return; } - var data = twiml.ToString(formattingOptions); - await response.WriteAsync(data); + var doc = twiml.ToXDocument(); + +#if NET5_0_OR_GREATER + await doc.SaveAsync(response.Body, formattingOptions, cancellationToken); +#else + await response.WriteAsync(doc.ToString(formattingOptions), cancellationToken); +#endif } } -} +} \ No newline at end of file diff --git a/src/Twilio.AspNet.Core/Twilio.AspNet.Core.csproj b/src/Twilio.AspNet.Core/Twilio.AspNet.Core.csproj index 9c936a7..6257de3 100644 --- a/src/Twilio.AspNet.Core/Twilio.AspNet.Core.csproj +++ b/src/Twilio.AspNet.Core/Twilio.AspNet.Core.csproj @@ -30,7 +30,7 @@ true - + all diff --git a/src/Twilio.AspNet.Mvc.UnitTests/Twilio.AspNet.Mvc.UnitTests.csproj b/src/Twilio.AspNet.Mvc.UnitTests/Twilio.AspNet.Mvc.UnitTests.csproj index ffa41b9..27a14ae 100644 --- a/src/Twilio.AspNet.Mvc.UnitTests/Twilio.AspNet.Mvc.UnitTests.csproj +++ b/src/Twilio.AspNet.Mvc.UnitTests/Twilio.AspNet.Mvc.UnitTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/Twilio.AspNet.Mvc/TwiMLResult.cs b/src/Twilio.AspNet.Mvc/TwiMLResult.cs index 76296bd..e888fdb 100644 --- a/src/Twilio.AspNet.Mvc/TwiMLResult.cs +++ b/src/Twilio.AspNet.Mvc/TwiMLResult.cs @@ -30,13 +30,8 @@ public override void ExecuteResult(ControllerContext controllerContext) return; } - var twimlString = dataTwiml.ToString(formattingOptions); - if (encoding != "utf-8") - { - twimlString = twimlString.Replace("utf-8", encoding); - } - - response.Output.Write(twimlString); + var doc = dataTwiml.ToXDocument(); + doc.Save(response.Output); } } } \ No newline at end of file diff --git a/src/Twilio.AspNet.Mvc/Twilio.AspNet.Mvc.csproj b/src/Twilio.AspNet.Mvc/Twilio.AspNet.Mvc.csproj index c960f07..4ca45ac 100644 --- a/src/Twilio.AspNet.Mvc/Twilio.AspNet.Mvc.csproj +++ b/src/Twilio.AspNet.Mvc/Twilio.AspNet.Mvc.csproj @@ -50,7 +50,7 @@ - + all diff --git a/src/testapps/AspNetFramework/AspNetFramework.csproj b/src/testapps/AspNetFramework/AspNetFramework.csproj index 7ad128c..fbddb19 100644 --- a/src/testapps/AspNetFramework/AspNetFramework.csproj +++ b/src/testapps/AspNetFramework/AspNetFramework.csproj @@ -112,8 +112,8 @@ ..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll - - ..\packages\Twilio.6.0.1\lib\net451\Twilio.dll + + ..\packages\Twilio.6.1.0\lib\net451\Twilio.dll True diff --git a/src/testapps/AspNetFramework/packages.config b/src/testapps/AspNetFramework/packages.config index ffc2d4e..942c945 100644 --- a/src/testapps/AspNetFramework/packages.config +++ b/src/testapps/AspNetFramework/packages.config @@ -16,6 +16,6 @@ - + \ No newline at end of file From 7d6755bc57e595748e180984b450321721e5f37a Mon Sep 17 00:00:00 2001 From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com> Date: Tue, 6 Dec 2022 19:53:44 -0500 Subject: [PATCH 2/3] use XDocument directly for TwiMLResult.cs --- .../MinimalApiTwiMLResult.cs | 3 ++- src/Twilio.AspNet.Core/TwiMLResult.cs | 24 ++++++++++++------- .../Twilio.AspNet.Core.csproj | 2 +- .../Twilio.AspNet.Mvc.UnitTests.csproj | 2 +- src/Twilio.AspNet.Mvc/TwiMLResult.cs | 9 ++----- .../Twilio.AspNet.Mvc.csproj | 2 +- .../ValidateRequestAttribute.cs | 2 +- src/testapps/AspNetCore/appsettings.json | 2 +- .../AspNetFramework/AspNetFramework.csproj | 4 ++-- src/testapps/AspNetFramework/packages.config | 2 +- 10 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/Twilio.AspNet.Core/MinimalApiTwiMLResult.cs b/src/Twilio.AspNet.Core/MinimalApiTwiMLResult.cs index 6b5e9f7..a519615 100644 --- a/src/Twilio.AspNet.Core/MinimalApiTwiMLResult.cs +++ b/src/Twilio.AspNet.Core/MinimalApiTwiMLResult.cs @@ -41,5 +41,6 @@ public partial class TwiMLResult : IResult /// Writes the TwiML to the HTTP response body /// /// The HttpContext containing the Response to write the TwiML to - public Task ExecuteAsync(HttpContext httpContext) => WriteTwiMLToResponse(httpContext.Response); + public Task ExecuteAsync(HttpContext httpContext) + => WriteTwiMLToResponse(httpContext.Response, httpContext.RequestAborted); } \ No newline at end of file diff --git a/src/Twilio.AspNet.Core/TwiMLResult.cs b/src/Twilio.AspNet.Core/TwiMLResult.cs index 9f6f648..72d9157 100644 --- a/src/Twilio.AspNet.Core/TwiMLResult.cs +++ b/src/Twilio.AspNet.Core/TwiMLResult.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Threading; +using System.Threading.Tasks; using System.Xml.Linq; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; @@ -17,7 +18,7 @@ public partial class TwiMLResult : IActionResult public TwiMLResult(TwiML.TwiML twiml) : this(twiml, SaveOptions.None) { } - + /// The TwiML to respond with /// Specifies how to format TwiML public TwiMLResult(TwiML.TwiML twiml, SaveOptions formattingOptions) @@ -29,20 +30,25 @@ public TwiMLResult(TwiML.TwiML twiml, SaveOptions formattingOptions) public async Task ExecuteResultAsync(ActionContext actionContext) { var response = actionContext.HttpContext.Response; - await WriteTwiMLToResponse(response); + await WriteTwiMLToResponse(response, actionContext.HttpContext.RequestAborted); } - - private async Task WriteTwiMLToResponse(HttpResponse response) + + private async Task WriteTwiMLToResponse(HttpResponse response, CancellationToken cancellationToken) { response.ContentType = "application/xml"; if (twiml == null) { - await response.WriteAsync(""); + await response.WriteAsync("", cancellationToken); return; } - var data = twiml.ToString(formattingOptions); - await response.WriteAsync(data); + var doc = twiml.ToXDocument(); + +#if NET5_0_OR_GREATER + await doc.SaveAsync(response.Body, formattingOptions, cancellationToken); +#else + await response.WriteAsync(doc.ToString(formattingOptions), cancellationToken); +#endif } } -} +} \ No newline at end of file diff --git a/src/Twilio.AspNet.Core/Twilio.AspNet.Core.csproj b/src/Twilio.AspNet.Core/Twilio.AspNet.Core.csproj index 9c936a7..6257de3 100644 --- a/src/Twilio.AspNet.Core/Twilio.AspNet.Core.csproj +++ b/src/Twilio.AspNet.Core/Twilio.AspNet.Core.csproj @@ -30,7 +30,7 @@ true - + all diff --git a/src/Twilio.AspNet.Mvc.UnitTests/Twilio.AspNet.Mvc.UnitTests.csproj b/src/Twilio.AspNet.Mvc.UnitTests/Twilio.AspNet.Mvc.UnitTests.csproj index ffa41b9..27a14ae 100644 --- a/src/Twilio.AspNet.Mvc.UnitTests/Twilio.AspNet.Mvc.UnitTests.csproj +++ b/src/Twilio.AspNet.Mvc.UnitTests/Twilio.AspNet.Mvc.UnitTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/Twilio.AspNet.Mvc/TwiMLResult.cs b/src/Twilio.AspNet.Mvc/TwiMLResult.cs index 76296bd..c4fdaf1 100644 --- a/src/Twilio.AspNet.Mvc/TwiMLResult.cs +++ b/src/Twilio.AspNet.Mvc/TwiMLResult.cs @@ -30,13 +30,8 @@ public override void ExecuteResult(ControllerContext controllerContext) return; } - var twimlString = dataTwiml.ToString(formattingOptions); - if (encoding != "utf-8") - { - twimlString = twimlString.Replace("utf-8", encoding); - } - - response.Output.Write(twimlString); + var doc = dataTwiml.ToXDocument(); + doc.Save(response.Output, formattingOptions); } } } \ No newline at end of file diff --git a/src/Twilio.AspNet.Mvc/Twilio.AspNet.Mvc.csproj b/src/Twilio.AspNet.Mvc/Twilio.AspNet.Mvc.csproj index c960f07..4ca45ac 100644 --- a/src/Twilio.AspNet.Mvc/Twilio.AspNet.Mvc.csproj +++ b/src/Twilio.AspNet.Mvc/Twilio.AspNet.Mvc.csproj @@ -50,7 +50,7 @@ - + all diff --git a/src/Twilio.AspNet.Mvc/ValidateRequestAttribute.cs b/src/Twilio.AspNet.Mvc/ValidateRequestAttribute.cs index df185a7..e2f98af 100644 --- a/src/Twilio.AspNet.Mvc/ValidateRequestAttribute.cs +++ b/src/Twilio.AspNet.Mvc/ValidateRequestAttribute.cs @@ -56,7 +56,7 @@ public override void OnActionExecuting(ActionExecutingContext filterContext) { var httpContext = filterContext.HttpContext; string urlOverride = null; - if (BaseUrlOverride != null) + if (!string.IsNullOrEmpty(BaseUrlOverride)) { urlOverride = $"{BaseUrlOverride}{httpContext.Request.Path}{httpContext.Request.QueryString}"; } diff --git a/src/testapps/AspNetCore/appsettings.json b/src/testapps/AspNetCore/appsettings.json index fe06ec3..a50f119 100644 --- a/src/testapps/AspNetCore/appsettings.json +++ b/src/testapps/AspNetCore/appsettings.json @@ -21,7 +21,7 @@ "RequestValidation": { "AuthToken": "MyAuthToken!", "AllowLocal": false, - "BaseUrlOverride": "https://90e6b6c4f366.ngrok.io" + "BaseUrlOverride": null } } } diff --git a/src/testapps/AspNetFramework/AspNetFramework.csproj b/src/testapps/AspNetFramework/AspNetFramework.csproj index 7ad128c..fbddb19 100644 --- a/src/testapps/AspNetFramework/AspNetFramework.csproj +++ b/src/testapps/AspNetFramework/AspNetFramework.csproj @@ -112,8 +112,8 @@ ..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll - - ..\packages\Twilio.6.0.1\lib\net451\Twilio.dll + + ..\packages\Twilio.6.1.0\lib\net451\Twilio.dll True diff --git a/src/testapps/AspNetFramework/packages.config b/src/testapps/AspNetFramework/packages.config index ffc2d4e..942c945 100644 --- a/src/testapps/AspNetFramework/packages.config +++ b/src/testapps/AspNetFramework/packages.config @@ -16,6 +16,6 @@ - + \ No newline at end of file From 6599e1f4785bd502a1dbe34a6a393b6bf0a93ce5 Mon Sep 17 00:00:00 2001 From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com> Date: Wed, 14 Dec 2022 18:07:00 -0500 Subject: [PATCH 3/3] Use ConfigureAwait(false) --- src/Twilio.AspNet.Core/TwiMLResult.cs | 12 ++++++++---- .../ValidateTwilioRequestFilter.cs | 6 +++--- .../ValidateTwilioRequestMiddleware.cs | 6 +++--- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/Twilio.AspNet.Core/TwiMLResult.cs b/src/Twilio.AspNet.Core/TwiMLResult.cs index 72d9157..9973d9b 100644 --- a/src/Twilio.AspNet.Core/TwiMLResult.cs +++ b/src/Twilio.AspNet.Core/TwiMLResult.cs @@ -30,7 +30,8 @@ public TwiMLResult(TwiML.TwiML twiml, SaveOptions formattingOptions) public async Task ExecuteResultAsync(ActionContext actionContext) { var response = actionContext.HttpContext.Response; - await WriteTwiMLToResponse(response, actionContext.HttpContext.RequestAborted); + await WriteTwiMLToResponse(response, actionContext.HttpContext.RequestAborted) + .ConfigureAwait(false); } private async Task WriteTwiMLToResponse(HttpResponse response, CancellationToken cancellationToken) @@ -38,16 +39,19 @@ private async Task WriteTwiMLToResponse(HttpResponse response, CancellationToken response.ContentType = "application/xml"; if (twiml == null) { - await response.WriteAsync("", cancellationToken); + await response.WriteAsync("", cancellationToken) + .ConfigureAwait(false); return; } var doc = twiml.ToXDocument(); #if NET5_0_OR_GREATER - await doc.SaveAsync(response.Body, formattingOptions, cancellationToken); + await doc.SaveAsync(response.Body, formattingOptions, cancellationToken) + .ConfigureAwait(false); #else - await response.WriteAsync(doc.ToString(formattingOptions), cancellationToken); + await response.WriteAsync(doc.ToString(formattingOptions), cancellationToken) + .ConfigureAwait(false); #endif } } diff --git a/src/Twilio.AspNet.Core/ValidateTwilioRequestFilter.cs b/src/Twilio.AspNet.Core/ValidateTwilioRequestFilter.cs index 3849fe3..f72b233 100644 --- a/src/Twilio.AspNet.Core/ValidateTwilioRequestFilter.cs +++ b/src/Twilio.AspNet.Core/ValidateTwilioRequestFilter.cs @@ -28,7 +28,7 @@ public ValidateTwilioRequestFilter(IServiceProvider serviceProvider) AllowLocal = options.AllowLocal ?? true; } - public async ValueTask InvokeAsync( + public ValueTask InvokeAsync( EndpointFilterInvocationContext efiContext, EndpointFilterDelegate next ) @@ -43,10 +43,10 @@ EndpointFilterDelegate next if (RequestValidationHelper.IsValidRequest(httpContext, AuthToken, urlOverride, AllowLocal)) { - return await next(efiContext); + return next(efiContext); } - return Results.StatusCode((int) HttpStatusCode.Forbidden); + return ValueTask.FromResult((object)Results.StatusCode((int) HttpStatusCode.Forbidden)); } } diff --git a/src/Twilio.AspNet.Core/ValidateTwilioRequestMiddleware.cs b/src/Twilio.AspNet.Core/ValidateTwilioRequestMiddleware.cs index a55b898..99040a5 100644 --- a/src/Twilio.AspNet.Core/ValidateTwilioRequestMiddleware.cs +++ b/src/Twilio.AspNet.Core/ValidateTwilioRequestMiddleware.cs @@ -24,7 +24,7 @@ IOptions options this.options = options.Value ?? throw new Exception("RequestValidationOptions is not configured."); } - public async Task InvokeAsync(HttpContext context) + public Task InvokeAsync(HttpContext context) { var request = context.Request; @@ -38,10 +38,10 @@ public async Task InvokeAsync(HttpContext context) if (!isValid) { context.Response.StatusCode = (int) HttpStatusCode.Forbidden; - return; + return Task.CompletedTask; } - await next(context); + return next(context); } }