From 8a7e4cd639be24eb58385dc7b36b466c3d6aed92 Mon Sep 17 00:00:00 2001 From: crobibero Date: Sun, 19 Apr 2020 10:51:51 -0600 Subject: add redoc --- .../Extensions/ApiApplicationBuilderExtensions.cs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs') diff --git a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs index db06eb455..2ab9b0ba5 100644 --- a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs +++ b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs @@ -14,14 +14,18 @@ namespace Jellyfin.Server.Extensions /// The updated application builder. public static IApplicationBuilder UseJellyfinApiSwagger(this IApplicationBuilder applicationBuilder) { - applicationBuilder.UseSwagger(); - // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), // specifying the Swagger JSON endpoint. - return applicationBuilder.UseSwaggerUI(c => - { - c.SwaggerEndpoint("/swagger/v1/swagger.json", "Jellyfin API V1"); - }); + const string specEndpoint = "/swagger/v1/swagger.json"; + return applicationBuilder.UseSwagger() + .UseSwaggerUI(c => + { + c.SwaggerEndpoint(specEndpoint, "Jellyfin API V1"); + }) + .UseReDoc(c => + { + c.SpecUrl(specEndpoint); + }); } } } -- cgit v1.2.3 From e72a543570b59df61f48cb9a4049ab3dc9675250 Mon Sep 17 00:00:00 2001 From: crobibero Date: Sun, 19 Apr 2020 11:24:03 -0600 Subject: Add Redoc, move docs to api-docs/ --- Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs') diff --git a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs index 2ab9b0ba5..766243f20 100644 --- a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs +++ b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs @@ -21,10 +21,12 @@ namespace Jellyfin.Server.Extensions .UseSwaggerUI(c => { c.SwaggerEndpoint(specEndpoint, "Jellyfin API V1"); + c.RoutePrefix = "api-docs/swagger"; }) .UseReDoc(c => { c.SpecUrl(specEndpoint); + c.RoutePrefix = "api-docs/redoc"; }); } } -- cgit v1.2.3 From 72745f47225a5b1071660acc4dcde618d938eaa0 Mon Sep 17 00:00:00 2001 From: crobibero Date: Sun, 19 Apr 2020 11:28:56 -0600 Subject: fix formatting --- Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs') diff --git a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs index 766243f20..43c49307d 100644 --- a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs +++ b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs @@ -17,7 +17,8 @@ namespace Jellyfin.Server.Extensions // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), // specifying the Swagger JSON endpoint. const string specEndpoint = "/swagger/v1/swagger.json"; - return applicationBuilder.UseSwagger() + return applicationBuilder + .UseSwagger() .UseSwaggerUI(c => { c.SwaggerEndpoint(specEndpoint, "Jellyfin API V1"); -- cgit v1.2.3 From 1175ce3f97fdebc6fdb489ce65deaac59c7b7f87 Mon Sep 17 00:00:00 2001 From: crobibero Date: Tue, 21 Apr 2020 07:36:22 -0600 Subject: Add Exception Middleware --- Jellyfin.Api/Models/ExceptionDtos/ExceptionDto.cs | 14 +++++ .../Extensions/ApiApplicationBuilderExtensions.cs | 11 ++++ Jellyfin.Server/Middleware/ExceptionMiddleware.cs | 60 ++++++++++++++++++++++ Jellyfin.Server/Startup.cs | 2 + 4 files changed, 87 insertions(+) create mode 100644 Jellyfin.Api/Models/ExceptionDtos/ExceptionDto.cs create mode 100644 Jellyfin.Server/Middleware/ExceptionMiddleware.cs (limited to 'Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs') diff --git a/Jellyfin.Api/Models/ExceptionDtos/ExceptionDto.cs b/Jellyfin.Api/Models/ExceptionDtos/ExceptionDto.cs new file mode 100644 index 000000000..d2b48d4ae --- /dev/null +++ b/Jellyfin.Api/Models/ExceptionDtos/ExceptionDto.cs @@ -0,0 +1,14 @@ +namespace Jellyfin.Api.Models.ExceptionDtos +{ + /// + /// Exception Dto. + /// Used for graceful handling of API exceptions. + /// + public class ExceptionDto + { + /// + /// Gets or sets exception message. + /// + public string Message { get; set; } + } +} diff --git a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs index db06eb455..6c105ab65 100644 --- a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs +++ b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs @@ -1,3 +1,4 @@ +using Jellyfin.Server.Middleware; using Microsoft.AspNetCore.Builder; namespace Jellyfin.Server.Extensions @@ -23,5 +24,15 @@ namespace Jellyfin.Server.Extensions c.SwaggerEndpoint("/swagger/v1/swagger.json", "Jellyfin API V1"); }); } + + /// + /// Adds exception middleware to the application pipeline. + /// + /// The application builder. + /// The updated application builder. + public static IApplicationBuilder UseExceptionMiddleware(this IApplicationBuilder applicationBuilder) + { + return applicationBuilder.UseMiddleware(); + } } } diff --git a/Jellyfin.Server/Middleware/ExceptionMiddleware.cs b/Jellyfin.Server/Middleware/ExceptionMiddleware.cs new file mode 100644 index 000000000..39aace95d --- /dev/null +++ b/Jellyfin.Server/Middleware/ExceptionMiddleware.cs @@ -0,0 +1,60 @@ +using System; +using System.Text.Json; +using System.Threading.Tasks; +using Jellyfin.Api.Models.ExceptionDtos; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Logging; + +namespace Jellyfin.Server.Middleware +{ + /// + /// Exception Middleware. + /// + public class ExceptionMiddleware + { + private readonly RequestDelegate _next; + private readonly ILogger _logger; + + /// + /// Initializes a new instance of the class. + /// + /// Next request delegate. + /// Instance of the interface. + public ExceptionMiddleware(RequestDelegate next, ILoggerFactory loggerFactory) + { + _next = next ?? throw new ArgumentNullException(nameof(next)); + _logger = loggerFactory.CreateLogger() ?? + throw new ArgumentNullException(nameof(loggerFactory)); + } + + /// + /// Invoke request. + /// + /// Request context. + /// Task. + public async Task Invoke(HttpContext context) + { + try + { + await _next(context).ConfigureAwait(false); + } + catch (Exception ex) + { + if (context.Response.HasStarted) + { + _logger.LogWarning("The response has already started, the exception middleware will not be executed."); + throw; + } + + var exceptionBody = new ExceptionDto { Message = ex.Message }; + var exceptionJson = JsonSerializer.Serialize(exceptionBody); + + context.Response.Clear(); + context.Response.StatusCode = StatusCodes.Status500InternalServerError; + // TODO switch between PascalCase and camelCase + context.Response.ContentType = "application/json"; + await context.Response.WriteAsync(exceptionJson).ConfigureAwait(false); + } + } + } +} diff --git a/Jellyfin.Server/Startup.cs b/Jellyfin.Server/Startup.cs index 4d7d56e9d..7a632f6c4 100644 --- a/Jellyfin.Server/Startup.cs +++ b/Jellyfin.Server/Startup.cs @@ -58,6 +58,8 @@ namespace Jellyfin.Server app.UseDeveloperExceptionPage(); } + app.UseExceptionMiddleware(); + app.UseWebSockets(); app.UseResponseCompression(); -- cgit v1.2.3 From 2542a27bd5f79ccfbc2547ddd877ddb0423ae296 Mon Sep 17 00:00:00 2001 From: crobibero Date: Tue, 21 Apr 2020 16:15:31 -0600 Subject: Fix documentation endpoint for use with baseUrl --- .../Extensions/ApiApplicationBuilderExtensions.cs | 28 ++++++++++++++++------ Jellyfin.Server/Startup.cs | 2 +- 2 files changed, 22 insertions(+), 8 deletions(-) (limited to 'Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs') diff --git a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs index 43c49307d..df3bab931 100644 --- a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs +++ b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs @@ -1,3 +1,4 @@ +using MediaBrowser.Controller.Configuration; using Microsoft.AspNetCore.Builder; namespace Jellyfin.Server.Extensions @@ -11,23 +12,36 @@ namespace Jellyfin.Server.Extensions /// Adds swagger and swagger UI to the application pipeline. /// /// The application builder. + /// The server configuration. /// The updated application builder. - public static IApplicationBuilder UseJellyfinApiSwagger(this IApplicationBuilder applicationBuilder) + public static IApplicationBuilder UseJellyfinApiSwagger( + this IApplicationBuilder applicationBuilder, + IServerConfigurationManager serverConfigurationManager) { // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), // specifying the Swagger JSON endpoint. - const string specEndpoint = "/swagger/v1/swagger.json"; + + var baseUrl = serverConfigurationManager.Configuration.BaseUrl.Trim('/'); + if (!string.IsNullOrEmpty(baseUrl)) + { + baseUrl += '/'; + } + return applicationBuilder - .UseSwagger() + .UseSwagger(c => + { + c.RouteTemplate = $"/{baseUrl}api-docs/{{documentName}}/openapi.json"; + }) .UseSwaggerUI(c => { - c.SwaggerEndpoint(specEndpoint, "Jellyfin API V1"); - c.RoutePrefix = "api-docs/swagger"; + c.SwaggerEndpoint($"/{baseUrl}api-docs/v1/openapi.json", "Jellyfin API v1"); + c.RoutePrefix = $"{baseUrl}api-docs/v1/swagger"; }) .UseReDoc(c => { - c.SpecUrl(specEndpoint); - c.RoutePrefix = "api-docs/redoc"; + c.DocumentTitle = "Jellyfin API v1"; + c.SpecUrl($"/{baseUrl}api-docs/v1/openapi.json"); + c.RoutePrefix = $"{baseUrl}api-docs/v1/redoc"; }); } } diff --git a/Jellyfin.Server/Startup.cs b/Jellyfin.Server/Startup.cs index 4d7d56e9d..ee08d2580 100644 --- a/Jellyfin.Server/Startup.cs +++ b/Jellyfin.Server/Startup.cs @@ -66,7 +66,7 @@ namespace Jellyfin.Server app.Use(serverApplicationHost.ExecuteWebsocketHandlerAsync); // TODO use when old API is removed: app.UseAuthentication(); - app.UseJellyfinApiSwagger(); + app.UseJellyfinApiSwagger(_serverConfigurationManager); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => -- cgit v1.2.3 From 041d674eb6e4a675b68406ed5c2d7018d61e870a Mon Sep 17 00:00:00 2001 From: crobibero Date: Tue, 21 Apr 2020 16:19:26 -0600 Subject: Fix swagger ui Document Title --- Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs') diff --git a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs index df3bab931..d09424225 100644 --- a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs +++ b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs @@ -34,6 +34,7 @@ namespace Jellyfin.Server.Extensions }) .UseSwaggerUI(c => { + c.DocumentTitle = "Jellyfin API v1"; c.SwaggerEndpoint($"/{baseUrl}api-docs/v1/openapi.json", "Jellyfin API v1"); c.RoutePrefix = $"{baseUrl}api-docs/v1/swagger"; }) -- cgit v1.2.3 From be50fae38a27878cb520e20ed7956a72d7b05a84 Mon Sep 17 00:00:00 2001 From: crobibero Date: Thu, 23 Apr 2020 21:24:40 -0600 Subject: Address comments --- Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs | 10 ---------- Jellyfin.Server/Startup.cs | 3 ++- 2 files changed, 2 insertions(+), 11 deletions(-) (limited to 'Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs') diff --git a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs index 6c105ab65..0bd654c7d 100644 --- a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs +++ b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs @@ -24,15 +24,5 @@ namespace Jellyfin.Server.Extensions c.SwaggerEndpoint("/swagger/v1/swagger.json", "Jellyfin API V1"); }); } - - /// - /// Adds exception middleware to the application pipeline. - /// - /// The application builder. - /// The updated application builder. - public static IApplicationBuilder UseExceptionMiddleware(this IApplicationBuilder applicationBuilder) - { - return applicationBuilder.UseMiddleware(); - } } } diff --git a/Jellyfin.Server/Startup.cs b/Jellyfin.Server/Startup.cs index 7a632f6c4..b17357fc3 100644 --- a/Jellyfin.Server/Startup.cs +++ b/Jellyfin.Server/Startup.cs @@ -1,4 +1,5 @@ using Jellyfin.Server.Extensions; +using Jellyfin.Server.Middleware; using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; using Microsoft.AspNetCore.Builder; @@ -58,7 +59,7 @@ namespace Jellyfin.Server app.UseDeveloperExceptionPage(); } - app.UseExceptionMiddleware(); + app.UseMiddleware(); app.UseWebSockets(); -- cgit v1.2.3 From 806ae1bc07e715c6109a3e8ec96c6d3dd6a802ef Mon Sep 17 00:00:00 2001 From: crobibero Date: Wed, 29 Apr 2020 08:04:05 -0600 Subject: Remove versioned API --- Emby.Server.Implementations/Browser/BrowserLauncher.cs | 2 +- .../Extensions/ApiApplicationBuilderExtensions.cs | 16 ++++++++-------- .../Extensions/ApiServiceCollectionExtensions.cs | 2 +- Jellyfin.Server/Program.cs | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) (limited to 'Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs') diff --git a/Emby.Server.Implementations/Browser/BrowserLauncher.cs b/Emby.Server.Implementations/Browser/BrowserLauncher.cs index 384cb049f..e706401fd 100644 --- a/Emby.Server.Implementations/Browser/BrowserLauncher.cs +++ b/Emby.Server.Implementations/Browser/BrowserLauncher.cs @@ -26,7 +26,7 @@ namespace Emby.Server.Implementations.Browser /// The app host. public static void OpenSwaggerPage(IServerApplicationHost appHost) { - TryOpenUrl(appHost, "/api-docs/v1/swagger"); + TryOpenUrl(appHost, "/api-docs/swagger"); } /// diff --git a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs index 33fd77d9c..745567703 100644 --- a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs +++ b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs @@ -1,5 +1,4 @@ using MediaBrowser.Controller.Configuration; -using Jellyfin.Server.Middleware; using Microsoft.AspNetCore.Builder; namespace Jellyfin.Server.Extensions @@ -31,19 +30,20 @@ namespace Jellyfin.Server.Extensions return applicationBuilder .UseSwagger(c => { - c.RouteTemplate = $"/{baseUrl}api-docs/{{documentName}}/openapi.json"; + // Custom path requires {documentName}, SwaggerDoc documentName is 'api-docs' + c.RouteTemplate = $"/{baseUrl}{{documentName}}/openapi.json"; }) .UseSwaggerUI(c => { - c.DocumentTitle = "Jellyfin API v1"; - c.SwaggerEndpoint($"/{baseUrl}api-docs/v1/openapi.json", "Jellyfin API v1"); - c.RoutePrefix = $"{baseUrl}api-docs/v1/swagger"; + c.DocumentTitle = "Jellyfin API"; + c.SwaggerEndpoint($"/{baseUrl}api-docs/openapi.json", "Jellyfin API"); + c.RoutePrefix = $"{baseUrl}api-docs/swagger"; }) .UseReDoc(c => { - c.DocumentTitle = "Jellyfin API v1"; - c.SpecUrl($"/{baseUrl}api-docs/v1/openapi.json"); - c.RoutePrefix = $"{baseUrl}api-docs/v1/redoc"; + c.DocumentTitle = "Jellyfin API"; + c.SpecUrl($"/{baseUrl}api-docs/openapi.json"); + c.RoutePrefix = $"{baseUrl}api-docs/redoc"; }); } } diff --git a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs index a24785d57..a354f45aa 100644 --- a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs +++ b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs @@ -96,7 +96,7 @@ namespace Jellyfin.Server.Extensions { return serviceCollection.AddSwaggerGen(c => { - c.SwaggerDoc("v1", new OpenApiInfo { Title = "Jellyfin API", Version = "v1" }); + c.SwaggerDoc("api-docs", new OpenApiInfo { Title = "Jellyfin API" }); // Add all xml doc files to swagger generator. var xmlFiles = Directory.GetFiles( diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 23ddcf159..713580080 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -529,7 +529,7 @@ namespace Jellyfin.Server var inMemoryDefaultConfig = ConfigurationOptions.DefaultConfiguration; if (startupConfig != null && !startupConfig.HostWebClient()) { - inMemoryDefaultConfig[HttpListenerHost.DefaultRedirectKey] = "api-docs/v1/swagger"; + inMemoryDefaultConfig[HttpListenerHost.DefaultRedirectKey] = "api-docs/swagger"; } return config -- cgit v1.2.3