From a1b7fa9a03e1eb23da706d0c22f76ac1a7757692 Mon Sep 17 00:00:00 2001 From: Mike Alhayek Date: Mon, 4 Nov 2024 12:04:26 -0800 Subject: [PATCH 1/8] Use RecyclableMemoryStream Fix #16946 Related Work Items: #169 --- Directory.Packages.props | 1 + .../RemotePublishing/MetaWeblogHandler.cs | 2 +- .../OrchardCore.Media.Indexing.Pdf.csproj | 1 + .../Services/PdfMediaFileTextProvider.cs | 2 +- .../OrchardCore.Media/Recipes/MediaStep.cs | 2 +- .../Drivers/ElasticSettingsDisplayDriver.cs | 2 +- .../Services/ElasticSearchService.cs | 2 +- .../Controllers/SitemapController.cs | 2 +- .../Controllers/HomeController.cs | 2 +- .../OrchardCore.XmlRpc.csproj | 1 + .../IFileBuilder.cs | 2 +- .../FileProviders/ContentFileInfo.cs | 2 +- .../BlobFileStore.cs | 10 +++++++--- .../OrchardCore.FileStorage.AzureBlob.csproj | 1 + .../MemoryStreamFactory.cs | 20 +++++++++++++++++++ ...ardCore.Infrastructure.Abstractions.csproj | 4 ++++ .../Documents/DefaultDocumentSerializer.cs | 10 +++++----- .../Scripting/CommonGeneratorMethods.cs | 6 +++--- .../Scripting/Files/FilesScriptEngine.cs | 2 +- .../DatabaseShellConfigurationSources.cs | 2 +- .../DatabaseShellsSettingsSources.cs | 4 ++-- .../Services/ElasticQueryService.cs | 2 +- .../BlobShellConfigurationSources.cs | 2 +- .../BlobShellsSettingsSources.cs | 4 ++-- .../OrchardCore.Shells.Azure.csproj | 1 + .../Apis/Context/BlogPostDeploymentContext.cs | 2 +- .../PortableObjectStringLocalizerTests.cs | 2 +- .../OrchardCore.Media/MediaEventTests.cs | 4 ++-- .../SubResourceIntegrityTests.cs | 2 +- .../Stubs/MemoryFileBuilder.cs | 2 +- 30 files changed, 67 insertions(+), 34 deletions(-) create mode 100644 src/OrchardCore/OrchardCore.Infrastructure.Abstractions/MemoryStreamFactory.cs diff --git a/Directory.Packages.props b/Directory.Packages.props index cc1bd445047..08c3a35cfb1 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -49,6 +49,7 @@ See https://github.com/OrchardCMS/OrchardCore/pull/16057 for more information. --> + diff --git a/src/OrchardCore.Modules/OrchardCore.Lists/RemotePublishing/MetaWeblogHandler.cs b/src/OrchardCore.Modules/OrchardCore.Lists/RemotePublishing/MetaWeblogHandler.cs index 51c4a22ce94..2539d6c54b1 100644 --- a/src/OrchardCore.Modules/OrchardCore.Lists/RemotePublishing/MetaWeblogHandler.cs +++ b/src/OrchardCore.Modules/OrchardCore.Lists/RemotePublishing/MetaWeblogHandler.cs @@ -156,7 +156,7 @@ private async Task MetaWeblogNewMediaObjectAsync(string userName, st Stream stream = null; try { - stream = new MemoryStream(bits); + stream = MemoryStreamFactory.GetStream(bits); filePath = await _mediaFileStore.CreateFileFromStreamAsync(filePath, stream); } finally diff --git a/src/OrchardCore.Modules/OrchardCore.Media.Indexing.Pdf/OrchardCore.Media.Indexing.Pdf.csproj b/src/OrchardCore.Modules/OrchardCore.Media.Indexing.Pdf/OrchardCore.Media.Indexing.Pdf.csproj index f4daa34ac01..97082314fa8 100644 --- a/src/OrchardCore.Modules/OrchardCore.Media.Indexing.Pdf/OrchardCore.Media.Indexing.Pdf.csproj +++ b/src/OrchardCore.Modules/OrchardCore.Media.Indexing.Pdf/OrchardCore.Media.Indexing.Pdf.csproj @@ -17,6 +17,7 @@ + diff --git a/src/OrchardCore.Modules/OrchardCore.Media.Indexing.Pdf/Services/PdfMediaFileTextProvider.cs b/src/OrchardCore.Modules/OrchardCore.Media.Indexing.Pdf/Services/PdfMediaFileTextProvider.cs index 11f1bd98dac..ed13a0cb407 100644 --- a/src/OrchardCore.Modules/OrchardCore.Media.Indexing.Pdf/Services/PdfMediaFileTextProvider.cs +++ b/src/OrchardCore.Modules/OrchardCore.Media.Indexing.Pdf/Services/PdfMediaFileTextProvider.cs @@ -18,7 +18,7 @@ public async Task GetTextAsync(string path, Stream fileStream) { // Since fileStream.Length might not be supported either, we can't preconfigure the capacity of the // MemoryStream. - seekableStream = new MemoryStream(); + seekableStream = MemoryStreamFactory.GetStream(); // While this involves loading the file into memory, we don't really have a choice. await fileStream.CopyToAsync(seekableStream); seekableStream.Position = 0; diff --git a/src/OrchardCore.Modules/OrchardCore.Media/Recipes/MediaStep.cs b/src/OrchardCore.Modules/OrchardCore.Media/Recipes/MediaStep.cs index b73f9e069af..027d5fc9a9a 100644 --- a/src/OrchardCore.Modules/OrchardCore.Media/Recipes/MediaStep.cs +++ b/src/OrchardCore.Modules/OrchardCore.Media/Recipes/MediaStep.cs @@ -48,7 +48,7 @@ protected override async Task HandleAsync(RecipeExecutionContext context) if (!string.IsNullOrWhiteSpace(file.Base64)) { - stream = new MemoryStream(Convert.FromBase64String(file.Base64)); + stream = MemoryStreamFactory.GetStream(Convert.FromBase64String(file.Base64)); } else if (!string.IsNullOrWhiteSpace(file.SourcePath)) { diff --git a/src/OrchardCore.Modules/OrchardCore.Search.Elasticsearch/Drivers/ElasticSettingsDisplayDriver.cs b/src/OrchardCore.Modules/OrchardCore.Search.Elasticsearch/Drivers/ElasticSettingsDisplayDriver.cs index 6ef78eec748..b16ce62deb7 100644 --- a/src/OrchardCore.Modules/OrchardCore.Search.Elasticsearch/Drivers/ElasticSettingsDisplayDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Search.Elasticsearch/Drivers/ElasticSettingsDisplayDriver.cs @@ -101,7 +101,7 @@ public override async Task UpdateAsync(ISite site, ElasticSettin section.DefaultQuery = jsonObject.ToJsonString(JOptions.Indented); try { - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(model.DefaultQuery)); + using var stream = MemoryStreamFactory.GetStream(Encoding.UTF8.GetBytes(model.DefaultQuery)); var searchRequest = await _elasticClient.RequestResponseSerializer.DeserializeAsync(stream); } catch diff --git a/src/OrchardCore.Modules/OrchardCore.Search.Elasticsearch/Services/ElasticSearchService.cs b/src/OrchardCore.Modules/OrchardCore.Search.Elasticsearch/Services/ElasticSearchService.cs index 316476f503f..823b7d8a0e5 100644 --- a/src/OrchardCore.Modules/OrchardCore.Search.Elasticsearch/Services/ElasticSearchService.cs +++ b/src/OrchardCore.Modules/OrchardCore.Search.Elasticsearch/Services/ElasticSearchService.cs @@ -98,7 +98,7 @@ public async Task SearchAsync(string indexName, string term, int s try { - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(tokenizedContent)); + using var stream = MemoryStreamFactory.GetStream(Encoding.UTF8.GetBytes(tokenizedContent)); var searchRequest = await _elasticClient.RequestResponseSerializer.DeserializeAsync(stream); diff --git a/src/OrchardCore.Modules/OrchardCore.Sitemaps/Controllers/SitemapController.cs b/src/OrchardCore.Modules/OrchardCore.Sitemaps/Controllers/SitemapController.cs index 859550d9e15..bd00efea6f4 100644 --- a/src/OrchardCore.Modules/OrchardCore.Sitemaps/Controllers/SitemapController.cs +++ b/src/OrchardCore.Modules/OrchardCore.Sitemaps/Controllers/SitemapController.cs @@ -86,7 +86,7 @@ public async Task Index(string sitemapId, CancellationToken cance document.Declaration = new XDeclaration("1.0", "utf-8", null); - var stream = new MemoryStream(); + var stream = MemoryStreamFactory.GetStream(); await document.SaveAsync(stream, SaveOptions.None, cancellationToken); if (stream.Length >= ErrorLength) diff --git a/src/OrchardCore.Modules/OrchardCore.XmlRpc/Controllers/HomeController.cs b/src/OrchardCore.Modules/OrchardCore.XmlRpc/Controllers/HomeController.cs index 7d4dc97022d..c9207b01e09 100644 --- a/src/OrchardCore.Modules/OrchardCore.XmlRpc/Controllers/HomeController.cs +++ b/src/OrchardCore.Modules/OrchardCore.XmlRpc/Controllers/HomeController.cs @@ -47,7 +47,7 @@ public async Task ServiceEndpoint([ModelBinder(BinderType = typeo }; // Save to an intermediate MemoryStream to preserve the encoding declaration. - using var stream = new MemoryStream(); + using var stream = MemoryStreamFactory.GetStream(); using (var w = XmlWriter.Create(stream, settings)) { var result = _writer.MapMethodResponse(methodResponse); diff --git a/src/OrchardCore.Modules/OrchardCore.XmlRpc/OrchardCore.XmlRpc.csproj b/src/OrchardCore.Modules/OrchardCore.XmlRpc/OrchardCore.XmlRpc.csproj index a2e816892fe..d27c9fdcba0 100644 --- a/src/OrchardCore.Modules/OrchardCore.XmlRpc/OrchardCore.XmlRpc.csproj +++ b/src/OrchardCore.Modules/OrchardCore.XmlRpc/OrchardCore.XmlRpc.csproj @@ -14,6 +14,7 @@ + diff --git a/src/OrchardCore/OrchardCore.Deployment.Abstractions/IFileBuilder.cs b/src/OrchardCore/OrchardCore.Deployment.Abstractions/IFileBuilder.cs index 5ae90999c35..2ac4b767027 100644 --- a/src/OrchardCore/OrchardCore.Deployment.Abstractions/IFileBuilder.cs +++ b/src/OrchardCore/OrchardCore.Deployment.Abstractions/IFileBuilder.cs @@ -9,7 +9,7 @@ public static class IFileBuilderExtensions { public static async Task SetFileAsync(this IFileBuilder fileBuilder, string subpath, byte[] content) { - using var stream = new MemoryStream(content); + using var stream = MemoryStreamFactory.GetStream(content); await fileBuilder.SetFileAsync(subpath, stream); } } diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/FileProviders/ContentFileInfo.cs b/src/OrchardCore/OrchardCore.DisplayManagement/FileProviders/ContentFileInfo.cs index af0b0bdcdad..dfaea058c9f 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/FileProviders/ContentFileInfo.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/FileProviders/ContentFileInfo.cs @@ -33,6 +33,6 @@ public DateTimeOffset LastModified public Stream CreateReadStream() { - return new MemoryStream(_content); + return MemoryStreamFactory.GetStream(_content); } } diff --git a/src/OrchardCore/OrchardCore.FileStorage.AzureBlob/BlobFileStore.cs b/src/OrchardCore/OrchardCore.FileStorage.AzureBlob/BlobFileStore.cs index 081f26a8e77..e4145ab31bb 100644 --- a/src/OrchardCore/OrchardCore.FileStorage.AzureBlob/BlobFileStore.cs +++ b/src/OrchardCore/OrchardCore.FileStorage.AzureBlob/BlobFileStore.cs @@ -39,14 +39,17 @@ public class BlobFileStore : IFileStore private readonly IClock _clock; private readonly BlobContainerClient _blobContainer; private readonly IContentTypeProvider _contentTypeProvider; + private readonly string _basePrefix; - public BlobFileStore(BlobStorageOptions options, IClock clock, IContentTypeProvider contentTypeProvider) + public BlobFileStore( + BlobStorageOptions options, + IClock clock, + IContentTypeProvider contentTypeProvider) { _options = options; _clock = clock; _contentTypeProvider = contentTypeProvider; - _blobContainer = new BlobContainerClient(_options.ConnectionString, _options.ContainerName); if (!string.IsNullOrEmpty(_options.BasePath)) @@ -435,7 +438,8 @@ private async Task CreateDirectoryAsync(string path) var placeholderBlob = GetBlobReference(this.Combine(path, DirectoryMarkerFileName)); // Create a directory marker file to make this directory appear when listing directories. - using var stream = new MemoryStream(MarkerFileContent); + using var stream = MemoryStreamFactory.GetStream(MarkerFileContent); + await placeholderBlob.UploadAsync(stream); } diff --git a/src/OrchardCore/OrchardCore.FileStorage.AzureBlob/OrchardCore.FileStorage.AzureBlob.csproj b/src/OrchardCore/OrchardCore.FileStorage.AzureBlob/OrchardCore.FileStorage.AzureBlob.csproj index 71c90e93f7e..07e3942070e 100644 --- a/src/OrchardCore/OrchardCore.FileStorage.AzureBlob/OrchardCore.FileStorage.AzureBlob.csproj +++ b/src/OrchardCore/OrchardCore.FileStorage.AzureBlob/OrchardCore.FileStorage.AzureBlob.csproj @@ -21,6 +21,7 @@ + diff --git a/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/MemoryStreamFactory.cs b/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/MemoryStreamFactory.cs new file mode 100644 index 00000000000..da16421d425 --- /dev/null +++ b/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/MemoryStreamFactory.cs @@ -0,0 +1,20 @@ +using Microsoft.IO; + +namespace OrchardCore; + +public static class MemoryStreamFactory +{ + private static readonly RecyclableMemoryStreamManager _manager = new(); + + public static MemoryStream GetStream(byte[] buffer, int offset, int count, string tag = null) + => _manager.GetStream(tag, buffer, offset, count); + + public static MemoryStream GetStream(byte[] buffer, string tag = null) + => _manager.GetStream(tag, buffer, 0, buffer.Length); + + public static MemoryStream GetStream() + => _manager.GetStream(); + + public static MemoryStream GetStream(string tag) + => _manager.GetStream(tag); +} diff --git a/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/OrchardCore.Infrastructure.Abstractions.csproj b/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/OrchardCore.Infrastructure.Abstractions.csproj index 591952cab93..4ce6d6c55c9 100644 --- a/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/OrchardCore.Infrastructure.Abstractions.csproj +++ b/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/OrchardCore.Infrastructure.Abstractions.csproj @@ -14,6 +14,10 @@ + + + + diff --git a/src/OrchardCore/OrchardCore.Infrastructure/Documents/DefaultDocumentSerializer.cs b/src/OrchardCore/OrchardCore.Infrastructure/Documents/DefaultDocumentSerializer.cs index aab1271b1c5..0614ef69e96 100644 --- a/src/OrchardCore/OrchardCore.Infrastructure/Documents/DefaultDocumentSerializer.cs +++ b/src/OrchardCore/OrchardCore.Infrastructure/Documents/DefaultDocumentSerializer.cs @@ -38,7 +38,7 @@ public Task DeserializeAsync(byte[] data) data = Decompress(data); } - using var ms = new MemoryStream(data); + using var ms = MemoryStreamFactory.GetStream(data); var document = JsonSerializer.Deserialize(ms, _serializerOptions); @@ -59,8 +59,8 @@ internal static bool IsCompressed(byte[] data) internal static byte[] Compress(byte[] data) { - using var input = new MemoryStream(data); - using var output = new MemoryStream(); + using var input = MemoryStreamFactory.GetStream(data); + using var output = MemoryStreamFactory.GetStream(); using (var gzip = new GZipStream(output, CompressionMode.Compress)) { input.CopyTo(gzip); @@ -76,8 +76,8 @@ internal static byte[] Compress(byte[] data) internal static byte[] Decompress(byte[] data) { - using var input = new MemoryStream(data); - using var output = new MemoryStream(); + using var input = MemoryStreamFactory.GetStream(data); + using var output = MemoryStreamFactory.GetStream(); using (var gzip = new GZipStream(input, CompressionMode.Decompress)) { gzip.CopyTo(output); diff --git a/src/OrchardCore/OrchardCore.Infrastructure/Scripting/CommonGeneratorMethods.cs b/src/OrchardCore/OrchardCore.Infrastructure/Scripting/CommonGeneratorMethods.cs index 1029b9aeef2..0761635d558 100644 --- a/src/OrchardCore/OrchardCore.Infrastructure/Scripting/CommonGeneratorMethods.cs +++ b/src/OrchardCore/OrchardCore.Infrastructure/Scripting/CommonGeneratorMethods.cs @@ -28,15 +28,15 @@ public class CommonGeneratorMethods : IGlobalMethodProvider /// Converts a Base64 encoded gzip stream to an uncompressed Base64 string. /// See http://www.txtwizard.net/compression. /// - private static readonly GlobalMethod _gZip = new() + private readonly GlobalMethod _gZip = new() { Name = "gzip", Method = serviceProvider => (Func)(encoded => { var bytes = Convert.FromBase64String(encoded); - using var gzip = new GZipStream(new MemoryStream(bytes), CompressionMode.Decompress); + using var gzip = new GZipStream(MemoryStreamFactory.GetStream(bytes), CompressionMode.Decompress); - var decompressed = new MemoryStream(); + var decompressed = MemoryStreamFactory.GetStream(); var buffer = new byte[1024]; int nRead; diff --git a/src/OrchardCore/OrchardCore.Infrastructure/Scripting/Files/FilesScriptEngine.cs b/src/OrchardCore/OrchardCore.Infrastructure/Scripting/Files/FilesScriptEngine.cs index 1854717278c..cd59fca2861 100644 --- a/src/OrchardCore/OrchardCore.Infrastructure/Scripting/Files/FilesScriptEngine.cs +++ b/src/OrchardCore/OrchardCore.Infrastructure/Scripting/Files/FilesScriptEngine.cs @@ -46,7 +46,7 @@ public object Evaluate(IScriptingScope scope, string script) } using var fileStream = fileInfo.CreateReadStream(); - using var ms = new MemoryStream(); + using var ms = MemoryStreamFactory.GetStream(); fileStream.CopyTo(ms); return Convert.ToBase64String(ms.ToArray()); } diff --git a/src/OrchardCore/OrchardCore.Infrastructure/Shells.Database/Configuration/DatabaseShellConfigurationSources.cs b/src/OrchardCore/OrchardCore.Infrastructure/Shells.Database/Configuration/DatabaseShellConfigurationSources.cs index 533c6dccad5..cb77f0352e1 100644 --- a/src/OrchardCore/OrchardCore.Infrastructure/Shells.Database/Configuration/DatabaseShellConfigurationSources.cs +++ b/src/OrchardCore/OrchardCore.Infrastructure/Shells.Database/Configuration/DatabaseShellConfigurationSources.cs @@ -74,7 +74,7 @@ public async Task AddSourcesAsync(string tenant, IConfigurationBuilder builder) if (configuration is not null) { var configurationString = configuration.ToJsonString(JOptions.Default); - builder.AddTenantJsonStream(new MemoryStream(Encoding.UTF8.GetBytes(configurationString))); + builder.AddTenantJsonStream(MemoryStreamFactory.GetStream(Encoding.UTF8.GetBytes(configurationString))); } } diff --git a/src/OrchardCore/OrchardCore.Infrastructure/Shells.Database/Configuration/DatabaseShellsSettingsSources.cs b/src/OrchardCore/OrchardCore.Infrastructure/Shells.Database/Configuration/DatabaseShellsSettingsSources.cs index f6cfc8072e8..e35d0ab0bfa 100644 --- a/src/OrchardCore/OrchardCore.Infrastructure/Shells.Database/Configuration/DatabaseShellsSettingsSources.cs +++ b/src/OrchardCore/OrchardCore.Infrastructure/Shells.Database/Configuration/DatabaseShellsSettingsSources.cs @@ -42,7 +42,7 @@ public async Task AddSourcesAsync(IConfigurationBuilder builder) if (document.ShellsSettings is not null) { var shellsSettingsString = document.ShellsSettings.ToJsonString(JOptions.Default); - builder.AddTenantJsonStream(new MemoryStream(Encoding.UTF8.GetBytes(shellsSettingsString))); + builder.AddTenantJsonStream(MemoryStreamFactory.GetStream(Encoding.UTF8.GetBytes(shellsSettingsString))); } } @@ -53,7 +53,7 @@ public async Task AddSourcesAsync(string tenant, IConfigurationBuilder builder) { var shellSettings = new JsonObject { [tenant] = document.ShellsSettings[tenant] }; var shellSettingsString = shellSettings.ToJsonString(JOptions.Default); - builder.AddTenantJsonStream(new MemoryStream(Encoding.UTF8.GetBytes(shellSettingsString))); + builder.AddTenantJsonStream(MemoryStreamFactory.GetStream(Encoding.UTF8.GetBytes(shellSettingsString))); } } diff --git a/src/OrchardCore/OrchardCore.Search.Elasticsearch.Core/Services/ElasticQueryService.cs b/src/OrchardCore/OrchardCore.Search.Elasticsearch.Core/Services/ElasticQueryService.cs index 543b41e1eec..e3058f68138 100644 --- a/src/OrchardCore/OrchardCore.Search.Elasticsearch.Core/Services/ElasticQueryService.cs +++ b/src/OrchardCore/OrchardCore.Search.Elasticsearch.Core/Services/ElasticQueryService.cs @@ -36,7 +36,7 @@ public async Task SearchAsync(string indexName, string query) try { - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(query)); + using var stream = MemoryStreamFactory.GetStream(Encoding.UTF8.GetBytes(query)); var deserializedSearchRequest = _elasticClient.RequestResponseSerializer.Deserialize(stream); var searchRequest = new SearchRequest(_elasticIndexManager.GetFullIndexName(indexName)) diff --git a/src/OrchardCore/OrchardCore.Shells.Azure/Configuration/BlobShellConfigurationSources.cs b/src/OrchardCore/OrchardCore.Shells.Azure/Configuration/BlobShellConfigurationSources.cs index 08b5e42a803..206edd82f83 100644 --- a/src/OrchardCore/OrchardCore.Shells.Azure/Configuration/BlobShellConfigurationSources.cs +++ b/src/OrchardCore/OrchardCore.Shells.Azure/Configuration/BlobShellConfigurationSources.cs @@ -84,7 +84,7 @@ public async Task SaveAsync(string tenant, IDictionary data) } var configurationString = configData.ToJsonObject().ToJsonString(JOptions.Default); - using var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(configurationString)); + using var memoryStream = MemoryStreamFactory.GetStream(Encoding.UTF8.GetBytes(configurationString)); await _shellsFileStore.CreateFileFromStreamAsync(appsettings, memoryStream); } diff --git a/src/OrchardCore/OrchardCore.Shells.Azure/Configuration/BlobShellsSettingsSources.cs b/src/OrchardCore/OrchardCore.Shells.Azure/Configuration/BlobShellsSettingsSources.cs index 99ee64b08c8..7bd658e50ed 100644 --- a/src/OrchardCore/OrchardCore.Shells.Azure/Configuration/BlobShellsSettingsSources.cs +++ b/src/OrchardCore/OrchardCore.Shells.Azure/Configuration/BlobShellsSettingsSources.cs @@ -82,7 +82,7 @@ public async Task SaveAsync(string tenant, IDictionary data) tenantsSettings[tenant] = settings; var tenantsSettingsString = tenantsSettings.ToJsonString(JOptions.Default); - using var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(tenantsSettingsString)); + using var memoryStream = MemoryStreamFactory.GetStream(Encoding.UTF8.GetBytes(tenantsSettingsString)); await _shellsFileStore.CreateFileFromStreamAsync(OrchardCoreConstants.Shell.TenantsFileName, memoryStream); } @@ -102,7 +102,7 @@ public async Task RemoveAsync(string tenant) tenantsSettings.Remove(tenant); var tenantsSettingsString = tenantsSettings.ToJsonString(JOptions.Default); - using var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(tenantsSettingsString)); + using var memoryStream = MemoryStreamFactory.GetStream(Encoding.UTF8.GetBytes(tenantsSettingsString)); await _shellsFileStore.CreateFileFromStreamAsync(OrchardCoreConstants.Shell.TenantsFileName, memoryStream); } diff --git a/src/OrchardCore/OrchardCore.Shells.Azure/OrchardCore.Shells.Azure.csproj b/src/OrchardCore/OrchardCore.Shells.Azure/OrchardCore.Shells.Azure.csproj index 502575cccc1..61ca9f82bda 100644 --- a/src/OrchardCore/OrchardCore.Shells.Azure/OrchardCore.Shells.Azure.csproj +++ b/src/OrchardCore/OrchardCore.Shells.Azure/OrchardCore.Shells.Azure.csproj @@ -16,6 +16,7 @@ + diff --git a/test/OrchardCore.Tests/Apis/Context/BlogPostDeploymentContext.cs b/test/OrchardCore.Tests/Apis/Context/BlogPostDeploymentContext.cs index 97bc5f6faa7..e1b31608e05 100644 --- a/test/OrchardCore.Tests/Apis/Context/BlogPostDeploymentContext.cs +++ b/test/OrchardCore.Tests/Apis/Context/BlogPostDeploymentContext.cs @@ -67,7 +67,7 @@ public static JsonObject GetContentStepRecipe(ContentItem contentItem, Action PostRecipeAsync(JsonObject recipe, bool ensureSuccess = true) { - using var zipStream = new MemoryStream(); + using var zipStream = MemoryStreamFactory.GetStream(); using (var zip = new ZipArchive(zipStream, ZipArchiveMode.Create, true)) { var entry = zip.CreateEntry("Recipe.json"); diff --git a/test/OrchardCore.Tests/Localization/PortableObjectStringLocalizerTests.cs b/test/OrchardCore.Tests/Localization/PortableObjectStringLocalizerTests.cs index e6fa51feb97..e3d6712c832 100644 --- a/test/OrchardCore.Tests/Localization/PortableObjectStringLocalizerTests.cs +++ b/test/OrchardCore.Tests/Localization/PortableObjectStringLocalizerTests.cs @@ -163,7 +163,7 @@ public void HtmlLocalizerDoesNotFormatTwiceIfFormattedTranslationContainsCurlyBr { var htmlLocalizer = new PortableObjectHtmlLocalizer(localizer); var unformatted = htmlLocalizer["The page (ID:{0}) was deleted.", "{1}"]; - var memStream = new MemoryStream(); + var memStream = MemoryStreamFactory.GetStream(); var textWriter = new StreamWriter(memStream); var textReader = new StreamReader(memStream); diff --git a/test/OrchardCore.Tests/Modules/OrchardCore.Media/MediaEventTests.cs b/test/OrchardCore.Tests/Modules/OrchardCore.Media/MediaEventTests.cs index e4e7b84ef26..a07e6de8b5c 100644 --- a/test/OrchardCore.Tests/Modules/OrchardCore.Media/MediaEventTests.cs +++ b/test/OrchardCore.Tests/Modules/OrchardCore.Media/MediaEventTests.cs @@ -24,7 +24,7 @@ public async Task DisposesMediaCreatingStreams() #pragma warning restore CA1859 try { - inputStream = new MemoryStream(); + inputStream = MemoryStreamFactory.GetStream(); originalStream = inputStream; // Add original stream to streams to maintain reference to test disposal. @@ -78,7 +78,7 @@ public class TestMediaEventHandler : IMediaCreatingEventHandler { public async Task MediaCreatingAsync(MediaCreatingContext context, Stream inputStream) { - var outStream = new MemoryStream(); + var outStream = MemoryStreamFactory.GetStream(); await inputStream.CopyToAsync(outStream); return outStream; diff --git a/test/OrchardCore.Tests/Modules/OrchardCore.Resources/SubResourceIntegrityTests.cs b/test/OrchardCore.Tests/Modules/OrchardCore.Resources/SubResourceIntegrityTests.cs index 4fcf01b3e13..d295e53746b 100644 --- a/test/OrchardCore.Tests/Modules/OrchardCore.Resources/SubResourceIntegrityTests.cs +++ b/test/OrchardCore.Tests/Modules/OrchardCore.Resources/SubResourceIntegrityTests.cs @@ -61,7 +61,7 @@ private static async Task GetSubResourceIntegrityAsync(HttpClient httpCl { var data = await httpClient.GetByteArrayAsync(url); - using var memoryStream = new MemoryStream(data); + using var memoryStream = MemoryStreamFactory.GetStream(data); var hash = await SHA384.HashDataAsync(memoryStream); return "sha384-" + Convert.ToBase64String(hash); diff --git a/test/OrchardCore.Tests/Stubs/MemoryFileBuilder.cs b/test/OrchardCore.Tests/Stubs/MemoryFileBuilder.cs index 1896687c859..592ecd64e86 100644 --- a/test/OrchardCore.Tests/Stubs/MemoryFileBuilder.cs +++ b/test/OrchardCore.Tests/Stubs/MemoryFileBuilder.cs @@ -13,7 +13,7 @@ public class MemoryFileBuilder public async Task SetFileAsync(string subpath, Stream stream) { - using var ms = new MemoryStream(); + using var ms = MemoryStreamFactory.GetStream(); await stream.CopyToAsync(ms); VirtualFiles[subpath] = ms.ToArray(); } From b0ad6e6faf28dc27c352bacbee726b6bf22cc591 Mon Sep 17 00:00:00 2001 From: Mike Alhayek Date: Mon, 4 Nov 2024 13:15:09 -0800 Subject: [PATCH 2/8] Remove extra overloads and property dispose --- .../RemotePublishing/MetaWeblogHandler.cs | 2 +- .../OrchardCore.Media/Recipes/MediaStep.cs | 2 +- .../Drivers/ElasticSettingsDisplayDriver.cs | 2 +- .../Services/ElasticSearchService.cs | 2 +- .../Controllers/SitemapController.cs | 2 +- .../IFileBuilder.cs | 2 +- .../FileProviders/ContentFileInfo.cs | 2 +- .../BlobFileStore.cs | 2 +- .../MemoryStreamFactory.cs | 11 +---------- .../Documents/DefaultDocumentSerializer.cs | 8 ++++---- .../Scripting/CommonGeneratorMethods.cs | 5 +++-- .../DatabaseShellConfigurationSources.cs | 4 +++- .../Configuration/DatabaseShellsSettingsSources.cs | 8 ++++++-- .../Services/ElasticQueryService.cs | 2 +- .../Configuration/BlobShellConfigurationSources.cs | 8 ++++---- .../Configuration/BlobShellsSettingsSources.cs | 4 ++-- .../Apis/Context/BlogPostDeploymentContext.cs | 2 +- .../SubResourceIntegrityTests.cs | 2 +- 18 files changed, 34 insertions(+), 36 deletions(-) diff --git a/src/OrchardCore.Modules/OrchardCore.Lists/RemotePublishing/MetaWeblogHandler.cs b/src/OrchardCore.Modules/OrchardCore.Lists/RemotePublishing/MetaWeblogHandler.cs index 2539d6c54b1..51c4a22ce94 100644 --- a/src/OrchardCore.Modules/OrchardCore.Lists/RemotePublishing/MetaWeblogHandler.cs +++ b/src/OrchardCore.Modules/OrchardCore.Lists/RemotePublishing/MetaWeblogHandler.cs @@ -156,7 +156,7 @@ private async Task MetaWeblogNewMediaObjectAsync(string userName, st Stream stream = null; try { - stream = MemoryStreamFactory.GetStream(bits); + stream = new MemoryStream(bits); filePath = await _mediaFileStore.CreateFileFromStreamAsync(filePath, stream); } finally diff --git a/src/OrchardCore.Modules/OrchardCore.Media/Recipes/MediaStep.cs b/src/OrchardCore.Modules/OrchardCore.Media/Recipes/MediaStep.cs index 027d5fc9a9a..b73f9e069af 100644 --- a/src/OrchardCore.Modules/OrchardCore.Media/Recipes/MediaStep.cs +++ b/src/OrchardCore.Modules/OrchardCore.Media/Recipes/MediaStep.cs @@ -48,7 +48,7 @@ protected override async Task HandleAsync(RecipeExecutionContext context) if (!string.IsNullOrWhiteSpace(file.Base64)) { - stream = MemoryStreamFactory.GetStream(Convert.FromBase64String(file.Base64)); + stream = new MemoryStream(Convert.FromBase64String(file.Base64)); } else if (!string.IsNullOrWhiteSpace(file.SourcePath)) { diff --git a/src/OrchardCore.Modules/OrchardCore.Search.Elasticsearch/Drivers/ElasticSettingsDisplayDriver.cs b/src/OrchardCore.Modules/OrchardCore.Search.Elasticsearch/Drivers/ElasticSettingsDisplayDriver.cs index b16ce62deb7..6ef78eec748 100644 --- a/src/OrchardCore.Modules/OrchardCore.Search.Elasticsearch/Drivers/ElasticSettingsDisplayDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Search.Elasticsearch/Drivers/ElasticSettingsDisplayDriver.cs @@ -101,7 +101,7 @@ public override async Task UpdateAsync(ISite site, ElasticSettin section.DefaultQuery = jsonObject.ToJsonString(JOptions.Indented); try { - using var stream = MemoryStreamFactory.GetStream(Encoding.UTF8.GetBytes(model.DefaultQuery)); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(model.DefaultQuery)); var searchRequest = await _elasticClient.RequestResponseSerializer.DeserializeAsync(stream); } catch diff --git a/src/OrchardCore.Modules/OrchardCore.Search.Elasticsearch/Services/ElasticSearchService.cs b/src/OrchardCore.Modules/OrchardCore.Search.Elasticsearch/Services/ElasticSearchService.cs index 823b7d8a0e5..316476f503f 100644 --- a/src/OrchardCore.Modules/OrchardCore.Search.Elasticsearch/Services/ElasticSearchService.cs +++ b/src/OrchardCore.Modules/OrchardCore.Search.Elasticsearch/Services/ElasticSearchService.cs @@ -98,7 +98,7 @@ public async Task SearchAsync(string indexName, string term, int s try { - using var stream = MemoryStreamFactory.GetStream(Encoding.UTF8.GetBytes(tokenizedContent)); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(tokenizedContent)); var searchRequest = await _elasticClient.RequestResponseSerializer.DeserializeAsync(stream); diff --git a/src/OrchardCore.Modules/OrchardCore.Sitemaps/Controllers/SitemapController.cs b/src/OrchardCore.Modules/OrchardCore.Sitemaps/Controllers/SitemapController.cs index bd00efea6f4..fb2b84d8bc2 100644 --- a/src/OrchardCore.Modules/OrchardCore.Sitemaps/Controllers/SitemapController.cs +++ b/src/OrchardCore.Modules/OrchardCore.Sitemaps/Controllers/SitemapController.cs @@ -86,7 +86,7 @@ public async Task Index(string sitemapId, CancellationToken cance document.Declaration = new XDeclaration("1.0", "utf-8", null); - var stream = MemoryStreamFactory.GetStream(); + using var stream = MemoryStreamFactory.GetStream(); await document.SaveAsync(stream, SaveOptions.None, cancellationToken); if (stream.Length >= ErrorLength) diff --git a/src/OrchardCore/OrchardCore.Deployment.Abstractions/IFileBuilder.cs b/src/OrchardCore/OrchardCore.Deployment.Abstractions/IFileBuilder.cs index 2ac4b767027..5ae90999c35 100644 --- a/src/OrchardCore/OrchardCore.Deployment.Abstractions/IFileBuilder.cs +++ b/src/OrchardCore/OrchardCore.Deployment.Abstractions/IFileBuilder.cs @@ -9,7 +9,7 @@ public static class IFileBuilderExtensions { public static async Task SetFileAsync(this IFileBuilder fileBuilder, string subpath, byte[] content) { - using var stream = MemoryStreamFactory.GetStream(content); + using var stream = new MemoryStream(content); await fileBuilder.SetFileAsync(subpath, stream); } } diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/FileProviders/ContentFileInfo.cs b/src/OrchardCore/OrchardCore.DisplayManagement/FileProviders/ContentFileInfo.cs index dfaea058c9f..af0b0bdcdad 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/FileProviders/ContentFileInfo.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/FileProviders/ContentFileInfo.cs @@ -33,6 +33,6 @@ public DateTimeOffset LastModified public Stream CreateReadStream() { - return MemoryStreamFactory.GetStream(_content); + return new MemoryStream(_content); } } diff --git a/src/OrchardCore/OrchardCore.FileStorage.AzureBlob/BlobFileStore.cs b/src/OrchardCore/OrchardCore.FileStorage.AzureBlob/BlobFileStore.cs index e4145ab31bb..067102cc3b8 100644 --- a/src/OrchardCore/OrchardCore.FileStorage.AzureBlob/BlobFileStore.cs +++ b/src/OrchardCore/OrchardCore.FileStorage.AzureBlob/BlobFileStore.cs @@ -438,7 +438,7 @@ private async Task CreateDirectoryAsync(string path) var placeholderBlob = GetBlobReference(this.Combine(path, DirectoryMarkerFileName)); // Create a directory marker file to make this directory appear when listing directories. - using var stream = MemoryStreamFactory.GetStream(MarkerFileContent); + using var stream = new MemoryStream(MarkerFileContent); await placeholderBlob.UploadAsync(stream); } diff --git a/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/MemoryStreamFactory.cs b/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/MemoryStreamFactory.cs index da16421d425..e792c6f2879 100644 --- a/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/MemoryStreamFactory.cs +++ b/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/MemoryStreamFactory.cs @@ -6,15 +6,6 @@ public static class MemoryStreamFactory { private static readonly RecyclableMemoryStreamManager _manager = new(); - public static MemoryStream GetStream(byte[] buffer, int offset, int count, string tag = null) - => _manager.GetStream(tag, buffer, offset, count); - - public static MemoryStream GetStream(byte[] buffer, string tag = null) - => _manager.GetStream(tag, buffer, 0, buffer.Length); - - public static MemoryStream GetStream() - => _manager.GetStream(); - - public static MemoryStream GetStream(string tag) + public static MemoryStream GetStream(string tag = null) => _manager.GetStream(tag); } diff --git a/src/OrchardCore/OrchardCore.Infrastructure/Documents/DefaultDocumentSerializer.cs b/src/OrchardCore/OrchardCore.Infrastructure/Documents/DefaultDocumentSerializer.cs index 0614ef69e96..915b858437b 100644 --- a/src/OrchardCore/OrchardCore.Infrastructure/Documents/DefaultDocumentSerializer.cs +++ b/src/OrchardCore/OrchardCore.Infrastructure/Documents/DefaultDocumentSerializer.cs @@ -38,9 +38,9 @@ public Task DeserializeAsync(byte[] data) data = Decompress(data); } - using var ms = MemoryStreamFactory.GetStream(data); + using var stream = new MemoryStream(data); - var document = JsonSerializer.Deserialize(ms, _serializerOptions); + var document = JsonSerializer.Deserialize(stream, _serializerOptions); return Task.FromResult(document); } @@ -59,7 +59,7 @@ internal static bool IsCompressed(byte[] data) internal static byte[] Compress(byte[] data) { - using var input = MemoryStreamFactory.GetStream(data); + using var input = new MemoryStream(data); using var output = MemoryStreamFactory.GetStream(); using (var gzip = new GZipStream(output, CompressionMode.Compress)) { @@ -76,7 +76,7 @@ internal static byte[] Compress(byte[] data) internal static byte[] Decompress(byte[] data) { - using var input = MemoryStreamFactory.GetStream(data); + using var input = new MemoryStream(data); using var output = MemoryStreamFactory.GetStream(); using (var gzip = new GZipStream(input, CompressionMode.Decompress)) { diff --git a/src/OrchardCore/OrchardCore.Infrastructure/Scripting/CommonGeneratorMethods.cs b/src/OrchardCore/OrchardCore.Infrastructure/Scripting/CommonGeneratorMethods.cs index 0761635d558..f46cd01c772 100644 --- a/src/OrchardCore/OrchardCore.Infrastructure/Scripting/CommonGeneratorMethods.cs +++ b/src/OrchardCore/OrchardCore.Infrastructure/Scripting/CommonGeneratorMethods.cs @@ -34,9 +34,10 @@ public class CommonGeneratorMethods : IGlobalMethodProvider Method = serviceProvider => (Func)(encoded => { var bytes = Convert.FromBase64String(encoded); - using var gzip = new GZipStream(MemoryStreamFactory.GetStream(bytes), CompressionMode.Decompress); + using var stream = new MemoryStream(bytes); + using var gzip = new GZipStream(stream, CompressionMode.Decompress); - var decompressed = MemoryStreamFactory.GetStream(); + using var decompressed = MemoryStreamFactory.GetStream(); var buffer = new byte[1024]; int nRead; diff --git a/src/OrchardCore/OrchardCore.Infrastructure/Shells.Database/Configuration/DatabaseShellConfigurationSources.cs b/src/OrchardCore/OrchardCore.Infrastructure/Shells.Database/Configuration/DatabaseShellConfigurationSources.cs index cb77f0352e1..04965303430 100644 --- a/src/OrchardCore/OrchardCore.Infrastructure/Shells.Database/Configuration/DatabaseShellConfigurationSources.cs +++ b/src/OrchardCore/OrchardCore.Infrastructure/Shells.Database/Configuration/DatabaseShellConfigurationSources.cs @@ -74,7 +74,9 @@ public async Task AddSourcesAsync(string tenant, IConfigurationBuilder builder) if (configuration is not null) { var configurationString = configuration.ToJsonString(JOptions.Default); - builder.AddTenantJsonStream(MemoryStreamFactory.GetStream(Encoding.UTF8.GetBytes(configurationString))); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(configurationString)); + + builder.AddTenantJsonStream(stream); } } diff --git a/src/OrchardCore/OrchardCore.Infrastructure/Shells.Database/Configuration/DatabaseShellsSettingsSources.cs b/src/OrchardCore/OrchardCore.Infrastructure/Shells.Database/Configuration/DatabaseShellsSettingsSources.cs index e35d0ab0bfa..5e73c9892da 100644 --- a/src/OrchardCore/OrchardCore.Infrastructure/Shells.Database/Configuration/DatabaseShellsSettingsSources.cs +++ b/src/OrchardCore/OrchardCore.Infrastructure/Shells.Database/Configuration/DatabaseShellsSettingsSources.cs @@ -42,7 +42,9 @@ public async Task AddSourcesAsync(IConfigurationBuilder builder) if (document.ShellsSettings is not null) { var shellsSettingsString = document.ShellsSettings.ToJsonString(JOptions.Default); - builder.AddTenantJsonStream(MemoryStreamFactory.GetStream(Encoding.UTF8.GetBytes(shellsSettingsString))); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(shellsSettingsString)); + + builder.AddTenantJsonStream(stream); } } @@ -53,7 +55,9 @@ public async Task AddSourcesAsync(string tenant, IConfigurationBuilder builder) { var shellSettings = new JsonObject { [tenant] = document.ShellsSettings[tenant] }; var shellSettingsString = shellSettings.ToJsonString(JOptions.Default); - builder.AddTenantJsonStream(MemoryStreamFactory.GetStream(Encoding.UTF8.GetBytes(shellSettingsString))); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(shellSettingsString)); + + builder.AddTenantJsonStream(stream); } } diff --git a/src/OrchardCore/OrchardCore.Search.Elasticsearch.Core/Services/ElasticQueryService.cs b/src/OrchardCore/OrchardCore.Search.Elasticsearch.Core/Services/ElasticQueryService.cs index e3058f68138..543b41e1eec 100644 --- a/src/OrchardCore/OrchardCore.Search.Elasticsearch.Core/Services/ElasticQueryService.cs +++ b/src/OrchardCore/OrchardCore.Search.Elasticsearch.Core/Services/ElasticQueryService.cs @@ -36,7 +36,7 @@ public async Task SearchAsync(string indexName, string query) try { - using var stream = MemoryStreamFactory.GetStream(Encoding.UTF8.GetBytes(query)); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(query)); var deserializedSearchRequest = _elasticClient.RequestResponseSerializer.Deserialize(stream); var searchRequest = new SearchRequest(_elasticIndexManager.GetFullIndexName(indexName)) diff --git a/src/OrchardCore/OrchardCore.Shells.Azure/Configuration/BlobShellConfigurationSources.cs b/src/OrchardCore/OrchardCore.Shells.Azure/Configuration/BlobShellConfigurationSources.cs index 206edd82f83..3497264f521 100644 --- a/src/OrchardCore/OrchardCore.Shells.Azure/Configuration/BlobShellConfigurationSources.cs +++ b/src/OrchardCore/OrchardCore.Shells.Azure/Configuration/BlobShellConfigurationSources.cs @@ -84,19 +84,19 @@ public async Task SaveAsync(string tenant, IDictionary data) } var configurationString = configData.ToJsonObject().ToJsonString(JOptions.Default); - using var memoryStream = MemoryStreamFactory.GetStream(Encoding.UTF8.GetBytes(configurationString)); + using var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(configurationString)); await _shellsFileStore.CreateFileFromStreamAsync(appsettings, memoryStream); } public async Task RemoveAsync(string tenant) { - var appsettings = IFileStoreExtensions.Combine(null, _container, tenant, OrchardCoreConstants.Configuration.ApplicationSettingsFileName); + var appSettings = IFileStoreExtensions.Combine(null, _container, tenant, OrchardCoreConstants.Configuration.ApplicationSettingsFileName); - var fileInfo = await _shellsFileStore.GetFileInfoAsync(appsettings); + var fileInfo = await _shellsFileStore.GetFileInfoAsync(appSettings); if (fileInfo != null) { - await _shellsFileStore.RemoveFileAsync(appsettings); + await _shellsFileStore.RemoveFileAsync(appSettings); } } diff --git a/src/OrchardCore/OrchardCore.Shells.Azure/Configuration/BlobShellsSettingsSources.cs b/src/OrchardCore/OrchardCore.Shells.Azure/Configuration/BlobShellsSettingsSources.cs index 7bd658e50ed..99ee64b08c8 100644 --- a/src/OrchardCore/OrchardCore.Shells.Azure/Configuration/BlobShellsSettingsSources.cs +++ b/src/OrchardCore/OrchardCore.Shells.Azure/Configuration/BlobShellsSettingsSources.cs @@ -82,7 +82,7 @@ public async Task SaveAsync(string tenant, IDictionary data) tenantsSettings[tenant] = settings; var tenantsSettingsString = tenantsSettings.ToJsonString(JOptions.Default); - using var memoryStream = MemoryStreamFactory.GetStream(Encoding.UTF8.GetBytes(tenantsSettingsString)); + using var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(tenantsSettingsString)); await _shellsFileStore.CreateFileFromStreamAsync(OrchardCoreConstants.Shell.TenantsFileName, memoryStream); } @@ -102,7 +102,7 @@ public async Task RemoveAsync(string tenant) tenantsSettings.Remove(tenant); var tenantsSettingsString = tenantsSettings.ToJsonString(JOptions.Default); - using var memoryStream = MemoryStreamFactory.GetStream(Encoding.UTF8.GetBytes(tenantsSettingsString)); + using var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(tenantsSettingsString)); await _shellsFileStore.CreateFileFromStreamAsync(OrchardCoreConstants.Shell.TenantsFileName, memoryStream); } diff --git a/test/OrchardCore.Tests/Apis/Context/BlogPostDeploymentContext.cs b/test/OrchardCore.Tests/Apis/Context/BlogPostDeploymentContext.cs index e1b31608e05..9aeafc1da9d 100644 --- a/test/OrchardCore.Tests/Apis/Context/BlogPostDeploymentContext.cs +++ b/test/OrchardCore.Tests/Apis/Context/BlogPostDeploymentContext.cs @@ -67,7 +67,7 @@ public static JsonObject GetContentStepRecipe(ContentItem contentItem, Action PostRecipeAsync(JsonObject recipe, bool ensureSuccess = true) { - using var zipStream = MemoryStreamFactory.GetStream(); + await using var zipStream = MemoryStreamFactory.GetStream(); using (var zip = new ZipArchive(zipStream, ZipArchiveMode.Create, true)) { var entry = zip.CreateEntry("Recipe.json"); diff --git a/test/OrchardCore.Tests/Modules/OrchardCore.Resources/SubResourceIntegrityTests.cs b/test/OrchardCore.Tests/Modules/OrchardCore.Resources/SubResourceIntegrityTests.cs index d295e53746b..4fcf01b3e13 100644 --- a/test/OrchardCore.Tests/Modules/OrchardCore.Resources/SubResourceIntegrityTests.cs +++ b/test/OrchardCore.Tests/Modules/OrchardCore.Resources/SubResourceIntegrityTests.cs @@ -61,7 +61,7 @@ private static async Task GetSubResourceIntegrityAsync(HttpClient httpCl { var data = await httpClient.GetByteArrayAsync(url); - using var memoryStream = MemoryStreamFactory.GetStream(data); + using var memoryStream = new MemoryStream(data); var hash = await SHA384.HashDataAsync(memoryStream); return "sha384-" + Convert.ToBase64String(hash); From bb9835763f36a01d6804f6ac6f5b393af6357ff5 Mon Sep 17 00:00:00 2001 From: Mike Alhayek Date: Mon, 4 Nov 2024 13:27:14 -0800 Subject: [PATCH 3/8] using buffer --- .../Scripting/Files/FilesScriptEngine.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/OrchardCore/OrchardCore.Infrastructure/Scripting/Files/FilesScriptEngine.cs b/src/OrchardCore/OrchardCore.Infrastructure/Scripting/Files/FilesScriptEngine.cs index cd59fca2861..b8592595aef 100644 --- a/src/OrchardCore/OrchardCore.Infrastructure/Scripting/Files/FilesScriptEngine.cs +++ b/src/OrchardCore/OrchardCore.Infrastructure/Scripting/Files/FilesScriptEngine.cs @@ -46,9 +46,15 @@ public object Evaluate(IScriptingScope scope, string script) } using var fileStream = fileInfo.CreateReadStream(); - using var ms = MemoryStreamFactory.GetStream(); - fileStream.CopyTo(ms); - return Convert.ToBase64String(ms.ToArray()); + using var memoryStream = MemoryStreamFactory.GetStream(); + fileStream.CopyTo(memoryStream); + + if (memoryStream.TryGetBuffer(out var buffer)) + { + return Convert.ToBase64String(new ReadOnlySpan(buffer.Array, buffer.Offset, buffer.Count)); + } + + return Convert.ToBase64String(memoryStream.ToArray()); } else { From 72eb01c489f0a24a42b87570e5df0cf90d9430ad Mon Sep 17 00:00:00 2001 From: Mike Alhayek Date: Mon, 4 Nov 2024 13:30:22 -0800 Subject: [PATCH 4/8] use the buffer --- .../Scripting/Files/FilesScriptEngine.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OrchardCore/OrchardCore.Infrastructure/Scripting/Files/FilesScriptEngine.cs b/src/OrchardCore/OrchardCore.Infrastructure/Scripting/Files/FilesScriptEngine.cs index b8592595aef..303a22611bf 100644 --- a/src/OrchardCore/OrchardCore.Infrastructure/Scripting/Files/FilesScriptEngine.cs +++ b/src/OrchardCore/OrchardCore.Infrastructure/Scripting/Files/FilesScriptEngine.cs @@ -51,7 +51,7 @@ public object Evaluate(IScriptingScope scope, string script) if (memoryStream.TryGetBuffer(out var buffer)) { - return Convert.ToBase64String(new ReadOnlySpan(buffer.Array, buffer.Offset, buffer.Count)); + return Convert.ToBase64String(buffer); } return Convert.ToBase64String(memoryStream.ToArray()); From dba974f90cd4401a98eeb1a49db8b2e72683d576 Mon Sep 17 00:00:00 2001 From: Mike Alhayek Date: Tue, 5 Nov 2024 12:57:03 -0800 Subject: [PATCH 5/8] remove unwanted stream --- .../Documents/DefaultDocumentSerializer.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/OrchardCore/OrchardCore.Infrastructure/Documents/DefaultDocumentSerializer.cs b/src/OrchardCore/OrchardCore.Infrastructure/Documents/DefaultDocumentSerializer.cs index 915b858437b..2658f55b5cc 100644 --- a/src/OrchardCore/OrchardCore.Infrastructure/Documents/DefaultDocumentSerializer.cs +++ b/src/OrchardCore/OrchardCore.Infrastructure/Documents/DefaultDocumentSerializer.cs @@ -38,9 +38,7 @@ public Task DeserializeAsync(byte[] data) data = Decompress(data); } - using var stream = new MemoryStream(data); - - var document = JsonSerializer.Deserialize(stream, _serializerOptions); + var document = JsonSerializer.Deserialize(data, _serializerOptions); return Task.FromResult(document); } From 9965bcfa6c52f179f7a1c5a59250fc12320ee239 Mon Sep 17 00:00:00 2001 From: Mike Alhayek Date: Tue, 5 Nov 2024 13:15:41 -0800 Subject: [PATCH 6/8] use RecyclableMemoryStream --- .../MemoryStreamFactory.cs | 2 +- .../Scripting/Files/FilesScriptEngine.cs | 8 +------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/MemoryStreamFactory.cs b/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/MemoryStreamFactory.cs index e792c6f2879..2d2443f12e0 100644 --- a/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/MemoryStreamFactory.cs +++ b/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/MemoryStreamFactory.cs @@ -6,6 +6,6 @@ public static class MemoryStreamFactory { private static readonly RecyclableMemoryStreamManager _manager = new(); - public static MemoryStream GetStream(string tag = null) + public static RecyclableMemoryStream GetStream(string tag = null) => _manager.GetStream(tag); } diff --git a/src/OrchardCore/OrchardCore.Infrastructure/Scripting/Files/FilesScriptEngine.cs b/src/OrchardCore/OrchardCore.Infrastructure/Scripting/Files/FilesScriptEngine.cs index 303a22611bf..b1071259add 100644 --- a/src/OrchardCore/OrchardCore.Infrastructure/Scripting/Files/FilesScriptEngine.cs +++ b/src/OrchardCore/OrchardCore.Infrastructure/Scripting/Files/FilesScriptEngine.cs @@ -47,14 +47,8 @@ public object Evaluate(IScriptingScope scope, string script) using var fileStream = fileInfo.CreateReadStream(); using var memoryStream = MemoryStreamFactory.GetStream(); - fileStream.CopyTo(memoryStream); - if (memoryStream.TryGetBuffer(out var buffer)) - { - return Convert.ToBase64String(buffer); - } - - return Convert.ToBase64String(memoryStream.ToArray()); + return Convert.ToBase64String(memoryStream.GetBuffer()); } else { From 1978dcda325d3ceb47fc6b0e020e968ae62aa662 Mon Sep 17 00:00:00 2001 From: Mike Alhayek Date: Tue, 5 Nov 2024 13:21:14 -0800 Subject: [PATCH 7/8] fix warning --- .../Services/PdfMediaFileTextProvider.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/OrchardCore.Modules/OrchardCore.Media.Indexing.Pdf/Services/PdfMediaFileTextProvider.cs b/src/OrchardCore.Modules/OrchardCore.Media.Indexing.Pdf/Services/PdfMediaFileTextProvider.cs index ed13a0cb407..4655ec0c294 100644 --- a/src/OrchardCore.Modules/OrchardCore.Media.Indexing.Pdf/Services/PdfMediaFileTextProvider.cs +++ b/src/OrchardCore.Modules/OrchardCore.Media.Indexing.Pdf/Services/PdfMediaFileTextProvider.cs @@ -1,4 +1,5 @@ using Cysharp.Text; +using Microsoft.IO; using UglyToad.PdfPig; namespace OrchardCore.Media.Indexing; @@ -11,7 +12,7 @@ public async Task GetTextAsync(string path, Stream fileStream) // https://github.com/UglyToad/PdfPig/blob/master/src/UglyToad.PdfPig.Core/StreamInputBytes.cs#L45. // Thus if it isn't, which is the case with e.g. Azure Blob Storage, we need to copy it to a new, seekable // Stream. - MemoryStream seekableStream = null; + RecyclableMemoryStream seekableStream = null; try { if (!fileStream.CanSeek) From 511317a386cb4cdf43d30326467a3f48f6dd17be Mon Sep 17 00:00:00 2001 From: Mike Alhayek Date: Wed, 6 Nov 2024 08:25:00 -0800 Subject: [PATCH 8/8] save --- .../Scripting/CommonGeneratorMethods.cs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/OrchardCore/OrchardCore.Infrastructure/Scripting/CommonGeneratorMethods.cs b/src/OrchardCore/OrchardCore.Infrastructure/Scripting/CommonGeneratorMethods.cs index f46cd01c772..b402ff4633d 100644 --- a/src/OrchardCore/OrchardCore.Infrastructure/Scripting/CommonGeneratorMethods.cs +++ b/src/OrchardCore/OrchardCore.Infrastructure/Scripting/CommonGeneratorMethods.cs @@ -33,8 +33,19 @@ public class CommonGeneratorMethods : IGlobalMethodProvider Name = "gzip", Method = serviceProvider => (Func)(encoded => { - var bytes = Convert.FromBase64String(encoded); - using var stream = new MemoryStream(bytes); + var bytes = new Span(); + + var stream = MemoryStreamFactory.GetStream(); + + if (Convert.TryFromBase64String(encoded, bytes, out _)) + { + stream.Write(bytes); + } + else + { + stream.Write(Convert.FromBase64String(encoded)); + } + using var gzip = new GZipStream(stream, CompressionMode.Decompress); using var decompressed = MemoryStreamFactory.GetStream(); @@ -46,7 +57,9 @@ public class CommonGeneratorMethods : IGlobalMethodProvider decompressed.Write(buffer, 0, nRead); } - return Convert.ToBase64String(decompressed.ToArray()); + stream.Dispose(); + + return Convert.ToBase64String(decompressed.GetBuffer()); }), };