-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
77 changed files
with
25,083 additions
and
121 deletions.
There are no files selected for viewing
34 changes: 34 additions & 0 deletions
34
src/NSwag.AspNetCore/AspNetCoreToOpenApiMiddlewareSettings.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
//----------------------------------------------------------------------- | ||
// <copyright file="AspNetCoreToOpenApiMiddlewareSettings.cs" company="NSwag"> | ||
// Copyright (c) Rico Suter. All rights reserved. | ||
// </copyright> | ||
// <license>https://github.com/NSwag/NSwag/blob/master/LICENSE.md</license> | ||
// <author>Rico Suter, mail@rsuter.com</author> | ||
//----------------------------------------------------------------------- | ||
|
||
using System; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using NSwag.AspNetCore.Middlewares; | ||
|
||
namespace NSwag.AspNetCore | ||
{ | ||
/// <summary> | ||
/// The settings for <see cref="OpenApiExtensions.UseOpenApi"/> and <see cref="AspNetCoreToOpenApiMiddleware"/>. | ||
/// </summary> | ||
/// <remarks> | ||
/// Reviewers: Is it useful to have a post-processing step i.e. PostProcess property here that all documents share? | ||
/// </remarks> | ||
public class AspNetCoreToOpenApiMiddlewareSettings | ||
{ | ||
/// <summary> | ||
/// Gets or sets the Swagger URL route. Must start with '/' and should contain a '{documentName}' route | ||
/// parameter. | ||
/// </summary> | ||
public string SwaggerRoute { get; set; } = "/swagger/{documentName}/swagger.json"; | ||
|
||
/// <summary> | ||
/// Gets or sets for how long an <see cref="Exception"/> caught during schema generation is cached. | ||
/// </summary> | ||
public TimeSpan ExceptionCacheTime { get; set; } = TimeSpan.FromSeconds(10); | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
src/NSwag.AspNetCore/DependencyInjection/IOpenApiBuilder.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
//----------------------------------------------------------------------- | ||
// <copyright file="IOpenApiBuilder.cs" company="NSwag"> | ||
// Copyright (c) Rico Suter. All rights reserved. | ||
// </copyright> | ||
// <license>https://github.com/NSwag/NSwag/blob/master/LICENSE.md</license> | ||
// <author>Rico Suter, mail@rsuter.com</author> | ||
//----------------------------------------------------------------------- | ||
|
||
using Microsoft.Extensions.DependencyInjection; | ||
|
||
namespace NSwag.AspNetCore.DependencyInjection | ||
{ | ||
/// <summary> | ||
/// An interface for configuring Open Api documents. | ||
/// </summary> | ||
public interface IOpenApiBuilder | ||
{ | ||
/// <summary> | ||
/// Gets the <see cref="IServiceCollection"/>. | ||
/// </summary> | ||
IServiceCollection Services { get; } | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
src/NSwag.AspNetCore/DependencyInjection/OpenApiBuilder.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
//----------------------------------------------------------------------- | ||
// <copyright file="OpenApiBuilder.cs" company="NSwag"> | ||
// Copyright (c) Rico Suter. All rights reserved. | ||
// </copyright> | ||
// <license>https://github.com/NSwag/NSwag/blob/master/LICENSE.md</license> | ||
// <author>Rico Suter, mail@rsuter.com</author> | ||
//----------------------------------------------------------------------- | ||
|
||
using Microsoft.Extensions.DependencyInjection; | ||
|
||
namespace NSwag.AspNetCore.DependencyInjection | ||
{ | ||
internal class OpenApiBuilder : IOpenApiBuilder | ||
{ | ||
public OpenApiBuilder(IServiceCollection services) | ||
{ | ||
Services = services; | ||
} | ||
|
||
public IServiceCollection Services { get; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
92 changes: 92 additions & 0 deletions
92
src/NSwag.AspNetCore/Middlewares/AspNetCoreToOpenApiMiddleware.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
//----------------------------------------------------------------------- | ||
// <copyright file="AspNetCoreToOpenApiMiddleware.cs" company="NSwag"> | ||
// Copyright (c) Rico Suter. All rights reserved. | ||
// </copyright> | ||
// <license>https://github.com/NSwag/NSwag/blob/master/LICENSE.md</license> | ||
// <author>Rico Suter, mail@rsuter.com</author> | ||
//----------------------------------------------------------------------- | ||
|
||
using System; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Http; | ||
using Microsoft.AspNetCore.Routing; | ||
using Microsoft.AspNetCore.Routing.Internal; | ||
using Microsoft.AspNetCore.Routing.Template; | ||
using Microsoft.Extensions.ObjectPool; | ||
|
||
namespace NSwag.AspNetCore.Middlewares | ||
{ | ||
internal class AspNetCoreToOpenApiMiddleware | ||
{ | ||
private const string DocumentNameEntry = "documentName"; | ||
private readonly NSwagDocumentProvider _documentProvider; | ||
private readonly TemplateMatcher _matcher; | ||
private readonly RequestDelegate _nextDelegate; | ||
private readonly AspNetCoreToOpenApiMiddlewareSettings _settings; | ||
|
||
private string _failedDocumentName; | ||
private Exception _documentException; | ||
private DateTimeOffset _exceptionTimestamp; | ||
|
||
public AspNetCoreToOpenApiMiddleware( | ||
RequestDelegate nextDelegate, | ||
NSwagDocumentProvider documentProvider, | ||
ObjectPool<UriBuildingContext> pool, | ||
AspNetCoreToOpenApiMiddlewareSettings settings) | ||
{ | ||
_documentProvider = documentProvider; | ||
|
||
var template = TemplateParser.Parse(settings.SwaggerRoute); | ||
_matcher = new TemplateMatcher(template, defaults: null); | ||
_nextDelegate = nextDelegate; | ||
_settings = settings; | ||
} | ||
|
||
public async Task Invoke(HttpContext context) | ||
{ | ||
var values = new RouteValueDictionary(); | ||
if (_matcher.TryMatch(context.Request.Path, values)) | ||
{ | ||
var documentName = "v1"; | ||
if (values.TryGetValue(DocumentNameEntry, out var document)) | ||
{ | ||
documentName = document as string; | ||
if (documentName == null) | ||
{ | ||
throw new InvalidOperationException($"Unexpected null '{DocumentNameEntry}' entry in " + | ||
$"{nameof(RouteValueDictionary)}."); | ||
} | ||
} | ||
|
||
var documentString = await GenerateOpenApiAsync(documentName); | ||
context.Response.StatusCode = 200; | ||
context.Response.Headers["Content-Type"] = "application/json; charset=utf-8"; | ||
await context.Response.WriteAsync(documentString); | ||
} | ||
else | ||
await _nextDelegate(context); | ||
} | ||
|
||
protected virtual async Task<string> GenerateOpenApiAsync(string documentName) | ||
{ | ||
var now = DateTimeOffset.UtcNow; | ||
if (_documentException != null && | ||
_exceptionTimestamp + _settings.ExceptionCacheTime > now && | ||
string.Equals(_failedDocumentName, documentName, StringComparison.Ordinal)) | ||
throw _documentException; | ||
|
||
try | ||
{ | ||
return await _documentProvider.GenerateAsync(documentName); | ||
} | ||
catch (Exception exception) | ||
{ | ||
_documentException = exception; | ||
_exceptionTimestamp = now; | ||
_failedDocumentName = documentName; | ||
|
||
throw _documentException; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.