From 471010c536b097e1de07c4821b21bc93dfd31b15 Mon Sep 17 00:00:00 2001 From: Michal Vrba Date: Tue, 16 Dec 2025 14:46:05 +0100 Subject: [PATCH] Improve API base URL handling for downloads and logging Refactored API and Blazor client to dynamically construct download URLs using the configured API base URL instead of hardcoded localhost addresses. Enhanced root endpoint and startup logs to reflect environment-specific URLs. Added GetBaseUrl() to ITuneRipperApiService for consistent URL generation. --- TuneRipper.Api/Program.cs | 120 ++++++++++++-------- TuneRipper/Pages/Home.razor | 24 ++-- TuneRipper/Services/TuneRipperApiService.cs | 14 +++ 3 files changed, 100 insertions(+), 58 deletions(-) diff --git a/TuneRipper.Api/Program.cs b/TuneRipper.Api/Program.cs index a8ee452..af43f5c 100644 --- a/TuneRipper.Api/Program.cs +++ b/TuneRipper.Api/Program.cs @@ -1,4 +1,4 @@ -using TuneRipper.Api.Services; +ο»Ώusing TuneRipper.Api.Services; var builder = WebApplication.CreateBuilder(args); @@ -45,60 +45,80 @@ app.UseCors("BlazorPolicy"); app.UseAuthorization(); // Add root endpoint with startup info -app.MapGet("/", (IWebHostEnvironment env) => new +app.MapGet("/", (IWebHostEnvironment env, HttpContext context) => { - service = "TuneRipper API", - version = "1.0.0", - status = "running", - timestamp = DateTime.UtcNow, - environment = env.EnvironmentName, - urls = new + // Get the current request's base URL + var request = context.Request; + var baseUrl = $"{request.Scheme}://{request.Host}"; + + // Determine URLs based on environment + var httpsUrl = app.Environment.IsDevelopment() + ? "https://localhost:7160" + : baseUrl; + + var httpUrl = app.Environment.IsDevelopment() + ? "http://localhost:5112" + : baseUrl.Replace("https://", "http://"); + + return new { - https = "https://localhost:7160", - http = "http://localhost:5112" - }, - endpoints = new - { - health = "/api/health", - video_details = "/api/video/details?url={youtubeUrl}", - process_video = "/api/video/process", - check_status = "/api/video/status/{jobId}", - get_result = "/api/video/result/{jobId}", - download = "/api/download/{jobId}", - download_by_session = "/api/download/{sessionId}/{jobId}", - download_session_zip = "/api/download/zip/{sessionId}", - session_zip_info = "/api/download/zip/info/{sessionId}", - session_create = "/api/session/create", - session_validate = "/api/session/validate/{sessionId}", - static_files = "/downloads/{fileName}", - openapi = "/openapi/v1.json" - }, - features = new - { - session_management = true, - automatic_zip_creation = true, - session_based_organization = true, - backward_compatibility = true - }, - testing = new - { - httpFile = "Use api-tests.http to test endpoints", - startWith = "GET /api/health to verify API is running" - } + service = "TuneRipper API", + version = "1.0.0", + status = "running", + timestamp = DateTime.UtcNow, + environment = env.EnvironmentName, + urls = new + { + https = httpsUrl, + http = httpUrl + }, + endpoints = new + { + health = "/api/health", + video_details = "/api/video/details?url={youtubeUrl}", + process_video = "/api/video/process", + check_status = "/api/video/status/{jobId}", + get_result = "/api/video/result/{jobId}", + download = "/api/download/{jobId}", + download_by_session = "/api/download/{sessionId}/{jobId}", + download_session_zip = "/api/download/zip/{sessionId}", + session_zip_info = "/api/download/zip/info/{sessionId}", + session_create = "/api/session/create", + session_validate = "/api/session/validate/{sessionId}", + static_files = "/downloads/{fileName}", + openapi = "/openapi/v1.json" + }, + features = new + { + session_management = true, + automatic_zip_creation = true, + session_based_organization = true, + backward_compatibility = true + }, + testing = new + { + httpFile = "Use api-tests.http to test endpoints", + startWith = "GET /api/health to verify API is running" + } + }; }); app.MapControllers(); -// Log startup information -app.Logger.LogInformation("?? TuneRipper API is starting..."); -app.Logger.LogInformation("?? Environment: {Environment}", app.Environment.EnvironmentName); -app.Logger.LogInformation("?? API will be available at:"); -app.Logger.LogInformation(" ?? HTTPS: https://localhost:7160"); -app.Logger.LogInformation(" ?? HTTP: http://localhost:5112"); -app.Logger.LogInformation("?? Health check: /api/health"); -app.Logger.LogInformation("?? API info: /"); -app.Logger.LogInformation("?? Static files served from: /downloads/*"); -app.Logger.LogInformation("?? Session-based downloads supported"); -app.Logger.LogInformation("?? Automatic ZIP file creation enabled"); +// Log startup information with dynamic URLs +var isDevelopment = app.Environment.IsDevelopment(); +var httpsLogUrl = isDevelopment ? "https://localhost:7160" : "[Production HTTPS URL]"; +var httpLogUrl = isDevelopment ? "http://localhost:5112" : "[Production HTTP URL]"; + +app.Logger.LogInformation("πŸš€ TuneRipper API is starting..."); +app.Logger.LogInformation("🌍 Environment: {Environment}", app.Environment.EnvironmentName); +app.Logger.LogInformation("🌐 API will be available at:"); +app.Logger.LogInformation(" πŸ”’ HTTPS: {HttpsUrl}", httpsLogUrl); +app.Logger.LogInformation(" πŸ”“ HTTP: {HttpUrl}", httpLogUrl); +app.Logger.LogInformation("❀️ Health check: /api/health"); +app.Logger.LogInformation("ℹ️ API info: /"); +app.Logger.LogInformation("πŸ“ Static files served from: /downloads/*"); +app.Logger.LogInformation("πŸ”— Session-based downloads supported"); +app.Logger.LogInformation("πŸ“¦ Automatic ZIP file creation enabled"); app.Run(); diff --git a/TuneRipper/Pages/Home.razor b/TuneRipper/Pages/Home.razor index 9d4c6c4..602c9aa 100644 --- a/TuneRipper/Pages/Home.razor +++ b/TuneRipper/Pages/Home.razor @@ -428,8 +428,9 @@ Logger.LogInformation("Downloading session ZIP for session: {SessionId}", currentSessionId); - // Create the download URL for the ZIP file - var zipDownloadUrl = $"https://localhost:7160/api/download/zip/{currentSessionId}"; + // Create the download URL for the ZIP file using the configured API base URL + var baseUrl = ApiService.GetBaseUrl(); + var zipDownloadUrl = $"{baseUrl}/api/download/zip/{currentSessionId}"; // Use browser to download the ZIP file await JSRuntime.InvokeVoidAsync("open", zipDownloadUrl, "_blank"); @@ -628,17 +629,24 @@ // Use the actual video title from API string title = currentVideoDetails?.Title ?? result.VideoDetails?.Title ?? ExtractTitleFromUrl(youtubeUrl); - // Create the session-aware download URL + // Create the session-aware download URL using the configured API base URL string downloadUrl; - if (!string.IsNullOrEmpty(result.DownloadUrl) && result.DownloadUrl.Contains(sessionId)) + if (!string.IsNullOrEmpty(result.DownloadUrl) && result.DownloadUrl.StartsWith("http")) { - // Server provided a session-aware download URL - downloadUrl = result.DownloadUrl.StartsWith("http") ? result.DownloadUrl : $"https://localhost:7160{result.DownloadUrl}"; + // Server provided a full download URL + downloadUrl = result.DownloadUrl; + } + else if (!string.IsNullOrEmpty(result.DownloadUrl) && result.DownloadUrl.StartsWith("/")) + { + // Server provided a relative URL, make it absolute using the API base URL + var baseUrl = ApiService.GetBaseUrl(); + downloadUrl = $"{baseUrl}{result.DownloadUrl}"; } else { - // Construct session-aware download URL - downloadUrl = $"https://localhost:7160/api/download/{sessionId}/{jobId}"; + // Construct session-aware download URL using the API base URL + var baseUrl = ApiService.GetBaseUrl(); + downloadUrl = $"{baseUrl}/api/download/{sessionId}/{jobId}"; } downloadLinks.Add(new DownloadItem diff --git a/TuneRipper/Services/TuneRipperApiService.cs b/TuneRipper/Services/TuneRipperApiService.cs index 2eb37e0..2efffbf 100644 --- a/TuneRipper/Services/TuneRipperApiService.cs +++ b/TuneRipper/Services/TuneRipperApiService.cs @@ -22,6 +22,10 @@ public interface ITuneRipperApiService Task CreateSessionAsync(); Task ValidateSessionAsync(string sessionId); Task RefreshSessionAsync(string sessionId); + + // Add methods to get base URL for constructing download URLs + string GetBaseUrl(); + Task GetHttpClientAsync(); } public class SessionZipInfo @@ -580,4 +584,14 @@ public class TuneRipperApiService : ITuneRipperApiService return false; } } + + public string GetBaseUrl() + { + return _httpClient.BaseAddress?.ToString().TrimEnd('/') ?? "https://localhost:7160"; + } + + public Task GetHttpClientAsync() + { + return Task.FromResult(_httpClient); + } } \ No newline at end of file