diff --git a/src/Microsoft.OpenApi.Readers/OpenApiStreamReader.cs b/src/Microsoft.OpenApi.Readers/OpenApiStreamReader.cs index c9431de98..c6c8add2f 100644 --- a/src/Microsoft.OpenApi.Readers/OpenApiStreamReader.cs +++ b/src/Microsoft.OpenApi.Readers/OpenApiStreamReader.cs @@ -3,6 +3,7 @@ using System; using System.IO; +using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.OpenApi.Interfaces; @@ -41,7 +42,7 @@ public OpenApiStreamReader(OpenApiReaderSettings settings = null) /// Instance of newly created OpenApiDocument. public OpenApiDocument Read(Stream input, out OpenApiDiagnostic diagnostic) { - using var reader = new StreamReader(input, default, true, -1, _settings.LeaveStreamOpen); + using var reader = new StreamReader(input, Encoding.UTF8, true, 4096, _settings.LeaveStreamOpen); return new OpenApiTextReaderReader(_settings).Read(reader, out diagnostic); } @@ -54,6 +55,7 @@ public OpenApiDocument Read(Stream input, out OpenApiDiagnostic diagnostic) public async Task ReadAsync(Stream input, CancellationToken cancellationToken = default) { MemoryStream bufferedStream; + int bufferSize = 4096; if (input is MemoryStream stream) { bufferedStream = stream; @@ -63,11 +65,12 @@ public async Task ReadAsync(Stream input, CancellationToken cancella // Buffer stream so that OpenApiTextReaderReader can process it synchronously // YamlDocument doesn't support async reading. bufferedStream = new(); - await input.CopyToAsync(bufferedStream, 81920, cancellationToken); + bufferSize = 81920; + await input.CopyToAsync(bufferedStream, bufferSize, cancellationToken); bufferedStream.Position = 0; } - using var reader = new StreamReader(bufferedStream, default, true, -1, _settings.LeaveStreamOpen); + using var reader = new StreamReader(bufferedStream, Encoding.UTF8, true, bufferSize, _settings.LeaveStreamOpen); return await new OpenApiTextReaderReader(_settings).ReadAsync(reader, cancellationToken); } @@ -80,7 +83,7 @@ public async Task ReadAsync(Stream input, CancellationToken cancella /// Instance of newly created OpenApiDocument public T ReadFragment(Stream input, OpenApiSpecVersion version, out OpenApiDiagnostic diagnostic) where T : IOpenApiReferenceable { - using var reader = new StreamReader(input, default, true, -1, _settings.LeaveStreamOpen); + using var reader = new StreamReader(input, Encoding.UTF8, true, 4096, _settings.LeaveStreamOpen); return new OpenApiTextReaderReader(_settings).ReadFragment(reader, version, out diagnostic); } } diff --git a/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/OpenApiStreamReaderTests.cs b/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/OpenApiStreamReaderTests.cs index 856d5ada7..7bb0fe922 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/OpenApiStreamReaderTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/OpenApiStreamReaderTests.cs @@ -1,7 +1,9 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System; using System.IO; +using System.Net.Http; using System.Threading.Tasks; using Xunit; @@ -44,5 +46,20 @@ public async Task StreamShouldNotBeDisposedIfLeaveStreamOpenSettingIsTrue() stream.Seek(0, SeekOrigin.Begin); // does not throw an object disposed exception Assert.True(stream.CanRead); } + + [Fact] + public async Task StreamShouldReadWhenInitialized() + { + var httpClient = new HttpClient + { + BaseAddress = new Uri("https://raw.githubusercontent.com/OAI/OpenAPI-Specification/") + }; + + var stream = await httpClient.GetStreamAsync("master/examples/v3.0/petstore.yaml"); + + // Read V3 as YAML + var openApiDocument = new OpenApiStreamReader().Read(stream, out var diagnostic); + Assert.NotNull(openApiDocument); + } } }