From 60fdf129a14ef4f94d207ec1e50055c290f8fff4 Mon Sep 17 00:00:00 2001 From: "Alinson S. Xavier" Date: Tue, 11 Nov 2025 10:48:36 -0600 Subject: [PATCH] web: backend: Add CORS endpoints --- web/backend/src/server.jl | 34 +++++++++++++++++++++-------- web/backend/test/src/jobs_test.jl | 1 + web/backend/test/src/server_test.jl | 2 +- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/web/backend/src/server.jl b/web/backend/src/server.jl index c028388..9335fb3 100644 --- a/web/backend/src/server.jl +++ b/web/backend/src/server.jl @@ -9,11 +9,17 @@ struct ServerHandle processor::JobProcessor end +RESPONSE_HEADERS = [ + "Access-Control-Allow-Origin" => "*", + "Access-Control-Allow-Methods" => "GET, POST, OPTIONS", + "Access-Control-Allow-Headers" => "Content-Type", +] + function submit(req, processor::JobProcessor) # Check if request body is empty compressed_body = HTTP.payload(req) if isempty(compressed_body) - return HTTP.Response(400, "Error: No file provided") + return HTTP.Response(400, RESPONSE_HEADERS, "Error: No file provided") end # Validate compressed JSON by decompressing and parsing @@ -21,7 +27,11 @@ function submit(req, processor::JobProcessor) decompressed_data = transcode(GzipDecompressor, compressed_body) JSON.parse(String(decompressed_data)) catch e - return HTTP.Response(400, "Error: Invalid compressed JSON") + return HTTP.Response( + 400, + RESPONSE_HEADERS, + "Error: Invalid compressed JSON", + ) end # Generate random job ID (lowercase letters and numbers) @@ -40,7 +50,7 @@ function submit(req, processor::JobProcessor) # Return job ID as JSON response_body = JSON.json(Dict("job_id" => job_id)) - return HTTP.Response(200, response_body) + return HTTP.Response(200, RESPONSE_HEADERS, response_body) end function jobs_view(req) @@ -53,7 +63,7 @@ function jobs_view(req) # Check if job directory exists if !isdir(job_dir) - return HTTP.Response(404, "Job not found") + return HTTP.Response(404, RESPONSE_HEADERS, "Job not found") end # Read log file if it exists @@ -65,13 +75,10 @@ function jobs_view(req) output_content = isfile(output_path) ? read(output_path, String) : nothing # Create response JSON - response_data = Dict( - "log" => log_content, - "solution" => output_content - ) + response_data = Dict("log" => log_content, "solution" => output_content) response_body = JSON.json(response_data) - return HTTP.Response(200, response_body) + return HTTP.Response(200, RESPONSE_HEADERS, response_body) end function start_server(host, port; optimizer) @@ -95,6 +102,7 @@ function start_server(host, port; optimizer) UnitCommitment.optimize!(model) solution = UnitCommitment.solution(model) UnitCommitment.write(solution_filename, solution) + return end end end @@ -115,6 +123,14 @@ function start_server(host, port; optimizer) router = HTTP.Router() + # Register CORS preflight endpoint + HTTP.register!( + router, + "OPTIONS", + "/**", + req -> HTTP.Response(200, RESPONSE_HEADERS, ""), + ) + # Register /submit endpoint HTTP.register!(router, "POST", "/submit", req -> submit(req, processor)) diff --git a/web/backend/test/src/jobs_test.jl b/web/backend/test/src/jobs_test.jl index 4c6d076..58d5179 100644 --- a/web/backend/test/src/jobs_test.jl +++ b/web/backend/test/src/jobs_test.jl @@ -11,6 +11,7 @@ function jobs_test_usage() received_job_id = [] function work_fn(job_id) push!(received_job_id, job_id) + return end # Create processor with work function diff --git a/web/backend/test/src/server_test.jl b/web/backend/test/src/server_test.jl index 58147ef..8760bd0 100644 --- a/web/backend/test/src/server_test.jl +++ b/web/backend/test/src/server_test.jl @@ -54,7 +54,7 @@ function server_test_usage() @test view_data["solution"] !== nothing # Clean up - rm(job_dir, recursive=true) + rm(job_dir, recursive = true) finally stop(server) end