4
4
using System ;
5
5
using System . IO ;
6
6
using System . Linq ;
7
- using System . Net . Http ;
8
7
using System . Security ;
9
8
using System . Text ;
10
9
using System . Threading ;
@@ -21,13 +20,6 @@ namespace Microsoft.OpenApi.Reader
21
20
/// </summary>
22
21
public static class OpenApiModelFactory
23
22
{
24
- private static readonly HttpClient _httpClient = new ( ) ;
25
-
26
- static OpenApiModelFactory ( )
27
- {
28
- OpenApiReaderRegistry . RegisterReader ( OpenApiConstants . Json , new OpenApiJsonReader ( ) ) ;
29
- }
30
-
31
23
/// <summary>
32
24
/// Loads the input stream and parses it into an Open API document.
33
25
/// </summary>
@@ -73,19 +65,21 @@ public static ReadResult Load(MemoryStream stream,
73
65
public static T Load < T > ( MemoryStream input , OpenApiSpecVersion version , string format , OpenApiDocument openApiDocument , out OpenApiDiagnostic diagnostic , OpenApiReaderSettings settings = null ) where T : IOpenApiElement
74
66
{
75
67
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 ) ;
77
70
}
78
71
79
72
/// <summary>
80
73
/// Loads the input URL and parses it into an Open API document.
81
74
/// </summary>
82
75
/// <param name="url">The path to the OpenAPI file</param>
83
76
/// <param name="settings"> The OpenApi reader settings.</param>
84
- /// <param name="token"></param>
77
+ /// <param name="token">The cancellation token </param>
85
78
/// <returns></returns>
86
79
public static async Task < ReadResult > LoadAsync ( string url , OpenApiReaderSettings settings = null , CancellationToken token = default )
87
80
{
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 ) ;
89
83
return await LoadAsync ( stream , format , settings , token ) . ConfigureAwait ( false ) ;
90
84
}
91
85
@@ -102,7 +96,8 @@ public static async Task<ReadResult> LoadAsync(string url, OpenApiReaderSettings
102
96
/// <returns>The OpenAPI element.</returns>
103
97
public static async Task < T > LoadAsync < T > ( string url , OpenApiSpecVersion version , OpenApiDocument openApiDocument , OpenApiReaderSettings settings = null , CancellationToken token = default ) where T : IOpenApiElement
104
98
{
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 ) ;
106
101
return await LoadAsync < T > ( stream , version , openApiDocument , format , settings , token ) ;
107
102
}
108
103
@@ -239,14 +234,15 @@ public static T Parse<T>(string input,
239
234
return Load < T > ( stream , version , format , openApiDocument , out diagnostic , settings ) ;
240
235
}
241
236
242
- private static readonly OpenApiReaderSettings DefaultReaderSettings = new ( ) ;
237
+ private static readonly Lazy < OpenApiReaderSettings > DefaultReaderSettings = new ( ( ) => new OpenApiReaderSettings ( ) ) ;
243
238
244
239
private static async Task < ReadResult > InternalLoadAsync ( Stream input , string format , OpenApiReaderSettings settings , CancellationToken cancellationToken = default )
245
240
{
246
- var reader = OpenApiReaderRegistry . GetReader ( format ) ;
241
+ settings ??= DefaultReaderSettings . Value ;
242
+ var reader = settings . GetReader ( format ) ;
247
243
var readResult = await reader . ReadAsync ( input , settings , cancellationToken ) . ConfigureAwait ( false ) ;
248
244
249
- if ( settings ? . LoadExternalRefs ?? DefaultReaderSettings . LoadExternalRefs )
245
+ if ( settings . LoadExternalRefs )
250
246
{
251
247
var diagnosticExternalRefs = await LoadExternalRefsAsync ( readResult . Document , settings , format , cancellationToken ) . ConfigureAwait ( false ) ;
252
248
// Merge diagnostics of external reference
@@ -267,14 +263,15 @@ private static async Task<OpenApiDiagnostic> LoadExternalRefsAsync(OpenApiDocume
267
263
var openApiWorkSpace = new OpenApiWorkspace ( baseUrl ) ;
268
264
269
265
// Load this root document into the workspace
270
- var streamLoader = new DefaultStreamLoader ( settings . BaseUrl ) ;
266
+ var streamLoader = new DefaultStreamLoader ( settings . BaseUrl , settings . HttpClient ) ;
271
267
var workspaceLoader = new OpenApiWorkspaceLoader ( openApiWorkSpace , settings . CustomExternalLoader ?? streamLoader , settings ) ;
272
268
return await workspaceLoader . LoadAsync ( new OpenApiReference ( ) { ExternalResource = "/" } , document , format ?? OpenApiConstants . Json , null , token ) . ConfigureAwait ( false ) ;
273
269
}
274
270
275
271
private static ReadResult InternalLoad ( MemoryStream input , string format , OpenApiReaderSettings settings )
276
272
{
277
- if ( settings ? . LoadExternalRefs ?? DefaultReaderSettings . LoadExternalRefs )
273
+ settings ??= DefaultReaderSettings . Value ;
274
+ if ( settings . LoadExternalRefs )
278
275
{
279
276
throw new InvalidOperationException ( "Loading external references are not supported when using synchronous methods." ) ;
280
277
}
@@ -283,12 +280,12 @@ private static ReadResult InternalLoad(MemoryStream input, string format, OpenAp
283
280
throw new ArgumentException ( $ "Cannot parse the stream: { nameof ( input ) } is empty or contains no elements.") ;
284
281
}
285
282
286
- var reader = OpenApiReaderRegistry . GetReader ( format ) ;
283
+ var reader = settings . GetReader ( format ) ;
287
284
var readResult = reader . Read ( input , settings ) ;
288
285
return readResult ;
289
286
}
290
287
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 )
292
289
{
293
290
if ( ! string . IsNullOrEmpty ( url ) )
294
291
{
@@ -298,7 +295,7 @@ private static ReadResult InternalLoad(MemoryStream input, string format, OpenAp
298
295
if ( url . StartsWith ( "http" , StringComparison . OrdinalIgnoreCase )
299
296
|| url . StartsWith ( "https" , StringComparison . OrdinalIgnoreCase ) )
300
297
{
301
- var response = await _httpClient . GetAsync ( url , token ) . ConfigureAwait ( false ) ;
298
+ var response = await settings . HttpClient . GetAsync ( url , token ) . ConfigureAwait ( false ) ;
302
299
var mediaType = response . Content . Headers . ContentType . MediaType ;
303
300
var contentType = mediaType . Split ( ";" . ToCharArray ( ) , StringSplitOptions . RemoveEmptyEntries ) [ 0 ] ;
304
301
format = contentType . Split ( '/' ) . Last ( ) . Split ( '+' ) . Last ( ) . Split ( '-' ) . Last ( ) ;
0 commit comments