This is my first attempt at implementing CORS support in debuginfod.
I should probably add or change tests. Since debuginfod-find does not need this functionality, it would be another test done with curl. I had a look at the existing tests,
run-debuginfod-webapi-concurrency.sh looks like it would be a good template.

I have confirmed that I can use debuginfod with this patch from my web application at
https://core-explorer.github.io/cdx-type/

Signed-off-by: Henning Meyer <hmeyer...@gmail.com>

---
 debuginfod/ChangeLog      |  6 ++++++
 debuginfod/debuginfod.cxx | 35 +++++++++++++++++++++++++++++++++--
 2 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/debuginfod/ChangeLog b/debuginfod/ChangeLog
index 0e4810bb..8e2377a0 100644
--- a/debuginfod/ChangeLog
+++ b/debuginfod/ChangeLog
@@ -1,3 +1,9 @@
+2024-12-04: Henning Meyer <hmeyer...@gmail.com>
+    * debuginfod.cxx:
+    (handle_options): new_function
+    (handle_buildid, handle_metrics, handle_root, handle_metadata):
+    add Access-Control-Allow-Origin header
+    (handler_cb): handle http OPTIONS method
 2023-04-21  Frank Ch. Eigler <f...@redhat.com>

     * debuginfod.cxx (groom): Fix -r / -X logic.
diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx
index 4bb517bd..7f7d304f 100644
--- a/debuginfod/debuginfod.cxx
+++ b/debuginfod/debuginfod.cxx
@@ -3365,6 +3365,7 @@ handle_buildid (MHD_Connection* conn,
             {
               add_mhd_response_header (r, "Content-Type",
                        "application/octet-stream");
+              add_mhd_response_header (r, "Access-Control-Allow-Origin", "*");
               // Copy the incoming headers
               const char * hdrs = debuginfod_get_headers(client);
               string header_dup;
@@ -3537,6 +3538,7 @@ handle_metrics (off_t* size)
     {
       *size = os.size();
       add_mhd_response_header (r, "Content-Type", "text/plain");
+      add_mhd_response_header (r, "Access-Control-Allow-Origin", "*");
     }
   return r;
 }
@@ -3763,7 +3765,10 @@ handle_metadata (MHD_Connection* conn,
                                        MHD_RESPMEM_MUST_COPY);
   *size = strlen(metadata_str);
   if (r)
+  {
     add_mhd_response_header(r, "Content-Type", "application/json");
+    add_mhd_response_header (r, "Access-Control-Allow-Origin", "*");
+  }
   return r;
 }

@@ -3780,11 +3785,28 @@ handle_root (off_t* size)
     {
       *size = version.size ();
       add_mhd_response_header (r, "Content-Type", "text/plain");
+      add_mhd_response_header (r, "Access-Control-Allow-Origin", "*");
     }
   return r;
 }


+static struct MHD_Response*
+handle_options (off_t* size)
+{
+  static char empty_body[] = " ";
+  MHD_Response* r = MHD_create_response_from_buffer (1, empty_body,
+                             MHD_RESPMEM_PERSISTENT);
+  if (r != NULL)
+    {
+      *size = 1;
+      add_mhd_response_header (r, "Access-Control-Allow-Origin", "*");
+      add_mhd_response_header (r, "Access-Control-Allow-Methods", "GET, OPTIONS"); +      add_mhd_response_header (r, "Access-Control-Allow-Headers", "cache-control");
+    }
+  return r;
+}
+
 ////////////////////////////////////////////////////////////////////////


@@ -3838,8 +3860,17 @@ handler_cb (void * /*cls*/,

   try
     {
-      if (string(method) != "GET")
-        throw reportable_exception(400, "we support GET only");
+      if (method == string("OPTIONS"))
+        {
+          artifacttype = "OPTIONS";
+          inc_metric("http_requests_total", "type", artifacttype);
+          r = handle_options(& http_size);
+          rc = MHD_queue_response (connection, MHD_HTTP_OK, r);
+          http_code = MHD_HTTP_OK;
+          MHD_destroy_response (r);
+          return rc;
+        } else if (method != string("GET"))
+          throw reportable_exception(400, "we only support GET and OPTIONS");

       /* Start decoding the URL. */
       size_t slash1 = url_copy.find('/', 1);
--
2.43.0

Reply via email to