44using System ;
55using System . IO ;
66using System . Linq ;
7- using System . Net . Http ;
87using System . Security ;
98using System . Text ;
109using System . Threading ;
@@ -21,13 +20,6 @@ namespace Microsoft.OpenApi.Reader
2120 /// </summary>
2221 public static class OpenApiModelFactory
2322 {
24- private static readonly HttpClient _httpClient = new ( ) ;
25-
26- static OpenApiModelFactory ( )
27- {
28- OpenApiReaderRegistry . RegisterReader ( OpenApiConstants . Json , new OpenApiJsonReader ( ) ) ;
29- }
30-
3123 /// <summary>
3224 /// Loads the input stream and parses it into an Open API document.
3325 /// </summary>
@@ -73,19 +65,21 @@ public static ReadResult Load(MemoryStream stream,
7365 public static T Load < T > ( MemoryStream input , OpenApiSpecVersion version , string format , OpenApiDocument openApiDocument , out OpenApiDiagnostic diagnostic , OpenApiReaderSettings settings = null ) where T : IOpenApiElement
7466 {
7567 format ??= InspectStreamFormat ( input ) ;
76- return OpenApiReaderRegistry . GetReader ( format ) . ReadFragment < T > ( input , version , openApiDocument , out diagnostic , settings ) ;
68+ settings ??= DefaultReaderSettings . Value ;
69+ return settings . GetReader ( format ) . ReadFragment < T > ( input , version , openApiDocument , out diagnostic , settings ) ;
7770 }
7871
7972 /// <summary>
8073 /// Loads the input URL and parses it into an Open API document.
8174 /// </summary>
8275 /// <param name="url">The path to the OpenAPI file</param>
8376 /// <param name="settings"> The OpenApi reader settings.</param>
84- /// <param name="token"></param>
77+ /// <param name="token">The cancellation token </param>
8578 /// <returns></returns>
8679 public static async Task < ReadResult > LoadAsync ( string url , OpenApiReaderSettings settings = null , CancellationToken token = default )
8780 {
88- var ( stream , format ) = await RetrieveStreamAndFormatAsync ( url , token ) . ConfigureAwait ( false ) ;
81+ settings ??= DefaultReaderSettings . Value ;
82+ var ( stream , format ) = await RetrieveStreamAndFormatAsync ( url , settings , token ) . ConfigureAwait ( false ) ;
8983 return await LoadAsync ( stream , format , settings , token ) . ConfigureAwait ( false ) ;
9084 }
9185
@@ -102,7 +96,8 @@ public static async Task<ReadResult> LoadAsync(string url, OpenApiReaderSettings
10296 /// <returns>The OpenAPI element.</returns>
10397 public static async Task < T > LoadAsync < T > ( string url , OpenApiSpecVersion version , OpenApiDocument openApiDocument , OpenApiReaderSettings settings = null , CancellationToken token = default ) where T : IOpenApiElement
10498 {
105- var ( stream , format ) = await RetrieveStreamAndFormatAsync ( url , token ) . ConfigureAwait ( false ) ;
99+ settings ??= DefaultReaderSettings . Value ;
100+ var ( stream , format ) = await RetrieveStreamAndFormatAsync ( url , settings , token ) . ConfigureAwait ( false ) ;
106101 return await LoadAsync < T > ( stream , version , openApiDocument , format , settings , token ) ;
107102 }
108103
@@ -239,14 +234,15 @@ public static T Parse<T>(string input,
239234 return Load < T > ( stream , version , format , openApiDocument , out diagnostic , settings ) ;
240235 }
241236
242- private static readonly OpenApiReaderSettings DefaultReaderSettings = new ( ) ;
237+ private static readonly Lazy < OpenApiReaderSettings > DefaultReaderSettings = new ( ( ) => new OpenApiReaderSettings ( ) ) ;
243238
244239 private static async Task < ReadResult > InternalLoadAsync ( Stream input , string format , OpenApiReaderSettings settings , CancellationToken cancellationToken = default )
245240 {
246- var reader = OpenApiReaderRegistry . GetReader ( format ) ;
241+ settings ??= DefaultReaderSettings . Value ;
242+ var reader = settings . GetReader ( format ) ;
247243 var readResult = await reader . ReadAsync ( input , settings , cancellationToken ) . ConfigureAwait ( false ) ;
248244
249- if ( settings ? . LoadExternalRefs ?? DefaultReaderSettings . LoadExternalRefs )
245+ if ( settings . LoadExternalRefs )
250246 {
251247 var diagnosticExternalRefs = await LoadExternalRefsAsync ( readResult . Document , settings , format , cancellationToken ) . ConfigureAwait ( false ) ;
252248 // Merge diagnostics of external reference
@@ -267,14 +263,15 @@ private static async Task<OpenApiDiagnostic> LoadExternalRefsAsync(OpenApiDocume
267263 var openApiWorkSpace = new OpenApiWorkspace ( baseUrl ) ;
268264
269265 // Load this root document into the workspace
270- var streamLoader = new DefaultStreamLoader ( settings . BaseUrl ) ;
266+ var streamLoader = new DefaultStreamLoader ( settings . BaseUrl , settings . HttpClient ) ;
271267 var workspaceLoader = new OpenApiWorkspaceLoader ( openApiWorkSpace , settings . CustomExternalLoader ?? streamLoader , settings ) ;
272268 return await workspaceLoader . LoadAsync ( new OpenApiReference ( ) { ExternalResource = "/" } , document , format ?? OpenApiConstants . Json , null , token ) . ConfigureAwait ( false ) ;
273269 }
274270
275271 private static ReadResult InternalLoad ( MemoryStream input , string format , OpenApiReaderSettings settings )
276272 {
277- if ( settings ? . LoadExternalRefs ?? DefaultReaderSettings . LoadExternalRefs )
273+ settings ??= DefaultReaderSettings . Value ;
274+ if ( settings . LoadExternalRefs )
278275 {
279276 throw new InvalidOperationException ( "Loading external references are not supported when using synchronous methods." ) ;
280277 }
@@ -283,12 +280,12 @@ private static ReadResult InternalLoad(MemoryStream input, string format, OpenAp
283280 throw new ArgumentException ( $ "Cannot parse the stream: { nameof ( input ) } is empty or contains no elements.") ;
284281 }
285282
286- var reader = OpenApiReaderRegistry . GetReader ( format ) ;
283+ var reader = settings . GetReader ( format ) ;
287284 var readResult = reader . Read ( input , settings ) ;
288285 return readResult ;
289286 }
290287
291- private static async Task < ( Stream , string ) > RetrieveStreamAndFormatAsync ( string url , CancellationToken token = default )
288+ private static async Task < ( Stream , string ) > RetrieveStreamAndFormatAsync ( string url , OpenApiReaderSettings settings , CancellationToken token = default )
292289 {
293290 if ( ! string . IsNullOrEmpty ( url ) )
294291 {
@@ -298,7 +295,7 @@ private static ReadResult InternalLoad(MemoryStream input, string format, OpenAp
298295 if ( url . StartsWith ( "http" , StringComparison . OrdinalIgnoreCase )
299296 || url . StartsWith ( "https" , StringComparison . OrdinalIgnoreCase ) )
300297 {
301- var response = await _httpClient . GetAsync ( url , token ) . ConfigureAwait ( false ) ;
298+ var response = await settings . HttpClient . GetAsync ( url , token ) . ConfigureAwait ( false ) ;
302299 var mediaType = response . Content . Headers . ContentType . MediaType ;
303300 var contentType = mediaType . Split ( ";" . ToCharArray ( ) , StringSplitOptions . RemoveEmptyEntries ) [ 0 ] ;
304301 format = contentType . Split ( '/' ) . Last ( ) . Split ( '+' ) . Last ( ) . Split ( '-' ) . Last ( ) ;
0 commit comments