From 1ef6c3e8d43105f81b615a163e360e4b959d470c Mon Sep 17 00:00:00 2001 From: Eric Steuart Date: Fri, 6 Dec 2024 15:29:32 -0500 Subject: [PATCH] Checks if the body of the request is a `FileBufferingReadStream` and, if so, uses that instead of using a `MemoryStream`. A `FileBufferingReadStream` is used when `Request.EnableBuffering()` is called. It caches to disk if the stream is large. By using this instead of a `MemoryStream`, an `OutOfMemoryException` can be avoided when processing a very large request. --- .../MessageEncoder/SoapMessageEncoder.cs | 18 +++++++++++++----- src/SoapCore/SoapEndpointMiddleware.cs | 6 ++++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/SoapCore/MessageEncoder/SoapMessageEncoder.cs b/src/SoapCore/MessageEncoder/SoapMessageEncoder.cs index 5b53ee68..a6369295 100644 --- a/src/SoapCore/MessageEncoder/SoapMessageEncoder.cs +++ b/src/SoapCore/MessageEncoder/SoapMessageEncoder.cs @@ -3,11 +3,9 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections.Generic; using System.Globalization; using System.IO; using System.IO.Pipelines; -using System.Linq; using System.Net.Http.Headers; using System.ServiceModel; using System.ServiceModel.Channels; @@ -15,6 +13,7 @@ using System.Threading.Tasks; using System.Xml; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.WebUtilities; namespace SoapCore.MessageEncoder { @@ -137,9 +136,18 @@ public async Task ReadMessageAsync(Stream stream, int maxSizeOfHeaders, throw new ArgumentNullException(nameof(stream)); } - var ms = new MemoryStream(); - await stream.CopyToAsync(ms); - ms.Seek(0, SeekOrigin.Begin); + Stream ms; + if (stream is FileBufferingReadStream) + { + ms = stream; + } + else + { + ms = new MemoryStream(); + await stream.CopyToAsync(ms); + ms.Seek(0, SeekOrigin.Begin); + } + XmlReader reader; var readEncoding = SoapMessageEncoderDefaults.ContentTypeToEncoding(contentType); diff --git a/src/SoapCore/SoapEndpointMiddleware.cs b/src/SoapCore/SoapEndpointMiddleware.cs index 2b01160b..ae937ccc 100644 --- a/src/SoapCore/SoapEndpointMiddleware.cs +++ b/src/SoapCore/SoapEndpointMiddleware.cs @@ -246,9 +246,15 @@ private async Task ReadMessageAsync(HttpContext httpContext, SoapMessag } } } + #if !NETCOREAPP3_0_OR_GREATER return await messageEncoder.ReadMessageAsync(httpContext.Request.Body, messageEncoder.MaxSoapHeaderSize, httpContext.Request.ContentType); #else + if (httpContext.Request.Body is FileBufferingReadStream) + { + return await messageEncoder.ReadMessageAsync(httpContext.Request.Body, messageEncoder.MaxSoapHeaderSize, httpContext.Request.ContentType); + } + return await messageEncoder.ReadMessageAsync(httpContext.Request.BodyReader, messageEncoder.MaxSoapHeaderSize, httpContext.Request.ContentType); #endif }