using Microsoft.AspNetCore.Mvc; using System.Text.Json; namespace ImglyNanoBana.Api.Controllers { [ApiController] [Route("api/[controller]")] public class FalProxyController : ControllerBase { private readonly IHttpClientFactory _httpClientFactory; private readonly ILogger _logger; private readonly string _falApiKey = "7ef4e941-06af-400b-81ab-6e32a457712e:23ba13cc83202ead0054754d9d2ce5ff"; public FalProxyController(IHttpClientFactory httpClientFactory, ILogger logger) { _httpClientFactory = httpClientFactory; _logger = logger; } [HttpGet] [HttpPost] [HttpPut] [HttpDelete] [HttpPatch] [Route("{**catchAll}")] public async Task ProxyRequest() { try { // Get the target URL from the x-fal-target-url header if (!Request.Headers.TryGetValue("x-fal-target-url", out var targetUrlHeader)) { _logger.LogError("Missing x-fal-target-url header"); return BadRequest(new { error = "Missing x-fal-target-url header" }); } var targetUrl = targetUrlHeader.ToString(); _logger.LogInformation($"Proxying {Request.Method} request to: {targetUrl}"); // Create HTTP client var httpClient = _httpClientFactory.CreateClient(); httpClient.Timeout = TimeSpan.FromMinutes(5); // Create the forwarding request var forwardRequest = new HttpRequestMessage(new HttpMethod(Request.Method), targetUrl); // Add fal.ai authentication header forwardRequest.Headers.Add("Authorization", $"Key {_falApiKey}"); // Forward request body if present if (Request.ContentLength > 0) { var bodyStream = new MemoryStream(); await Request.Body.CopyToAsync(bodyStream); bodyStream.Position = 0; forwardRequest.Content = new StreamContent(bodyStream); // Copy Content-Type header if (Request.ContentType != null) { forwardRequest.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(Request.ContentType); } } // Forward query string parameters if (Request.QueryString.HasValue) { var uriBuilder = new UriBuilder(targetUrl) { Query = Request.QueryString.Value }; forwardRequest.RequestUri = uriBuilder.Uri; } // Send the request var response = await httpClient.SendAsync(forwardRequest, HttpCompletionOption.ResponseHeadersRead); // Read response content var responseContent = await response.Content.ReadAsStringAsync(); _logger.LogInformation($"Fal.ai response status: {response.StatusCode}"); _logger.LogInformation($"Fal.ai response: {responseContent}"); // Return the response with appropriate status code return new ContentResult { Content = responseContent, ContentType = "application/json", StatusCode = (int)response.StatusCode }; } catch (Exception ex) { _logger.LogError(ex, "Error proxying request to fal.ai"); return StatusCode(500, new { error = ex.Message }); } } } }