Hello guys, thank-you for your thorough review. With Mark's help I've dropped the original patch from patchwork, and am submitting an updated one, hopefully addressing your comments.
Martin
>From 1c94f69c4602d7e2df31f03cc503f0c53d173bad Mon Sep 17 00:00:00 2001 From: Martin Cermak <[email protected]> Date: Fri, 5 Dec 2025 10:42:07 +0100 Subject: [PATCH] PR33635: Introduce debuginfod --home-redirect and --home-html NEWS: New entry debuginfod/debuginfod.cxx: Feature implementation doc/debuginfod.8: Doc text tests/Makefile.am: New testcase tests/run-debuginfod-homesite.sh: New testcase Signed-off-by: Martin Cermak <[email protected]> --- NEWS | 4 ++ debuginfod/debuginfod.cxx | 57 ++++++++++++++++++++++++--- doc/debuginfod.8 | 10 +++++ tests/Makefile.am | 4 +- tests/run-debuginfod-homesite.sh | 67 ++++++++++++++++++++++++++++++++ 5 files changed, 135 insertions(+), 7 deletions(-) create mode 100644 tests/run-debuginfod-homesite.sh diff --git a/NEWS b/NEWS index 922a15cc..587f7b61 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +debuginfod: Introduce --home-redirect and --home-html switches allowing + for redirecting to custom URL and/or serving a custom html + file, if document root is requested. Related: PR33635. + Version 0.194 "Manual Labour" debuginfod-find: Fixed caching bug preventing user-cancelled downloads diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx index 8fc9426e..9796d312 100644 --- a/debuginfod/debuginfod.cxx +++ b/debuginfod/debuginfod.cxx @@ -484,6 +484,8 @@ static const struct argp_option options[] = "Number of seconds to limit metadata query run time, 0=unlimited.", 0 }, #define ARGP_KEY_HTTP_ADDR 0x100D { "listen-address", ARGP_KEY_HTTP_ADDR, "ADDR", 0, "HTTP address to listen on.", 0 }, + { "home-redirect", 'h', "URL", 0, "Custom homepage - redirect.", 0 }, + { "home-html", 'H', "FILE", 0, "Custom homepage - htmlfile.", 0 }, { NULL, 0, NULL, 0, NULL, 0 }, }; @@ -543,6 +545,8 @@ static long scan_checkpoint = 256; static bool requires_koji_sigcache_mapping = false; #endif static unsigned metadata_maxtime_s = 5; +static string cust_homepage_redirect = ""; +static string cust_homepage_file = ""; static void set_metric(const string& key, double value); static void inc_metric(const string& key); @@ -769,6 +773,12 @@ parse_opt (int key, char *arg, addr_info = arg; break; // case 'h': argp_state_help (state, stderr, ARGP_HELP_LONG|ARGP_HELP_EXIT_OK); + case 'h': + cust_homepage_redirect = arg; + break; + case 'H': + cust_homepage_file = arg; + break; default: return ARGP_ERR_UNKNOWN; } @@ -3793,11 +3803,36 @@ handle_metadata (MHD_Connection* conn, static struct MHD_Response* handle_root (off_t* size) { + MHD_Response* r; + if (cust_homepage_file != "") + try + { + int fd = open (cust_homepage_file.c_str(), O_RDONLY); + if (fd != -1) { + struct stat buf; + stat (cust_homepage_file.c_str(), &buf); + r = MHD_create_response_from_fd(buf.st_size, fd); + // NB: MHD owns and handles the fd from now. Must not close()! + if (r != NULL) + { + *size = buf.st_size; + add_mhd_response_header (r, "Content-Type", "text/html"); + } + } else { + throw libc_exception (errno, "cannot open file " + cust_homepage_file); + } + return r; + } + catch (const reportable_exception& e) + { + e.report(clog); + } + static string version = "debuginfod (" + string (PACKAGE_NAME) + ") " - + string (PACKAGE_VERSION); - MHD_Response* r = MHD_create_response_from_buffer (version.size (), - (void *) version.c_str (), - MHD_RESPMEM_PERSISTENT); + + string (PACKAGE_VERSION); + r = MHD_create_response_from_buffer (version.size (), + (void *) version.c_str (), + MHD_RESPMEM_PERSISTENT); if (r != NULL) { *size = version.size (); @@ -3985,8 +4020,18 @@ handler_cb (void * /*cls*/, if (webapi_cors) // add ACAO header for all successful requests add_mhd_response_header (r, "Access-Control-Allow-Origin", "*"); - rc = MHD_queue_response (connection, MHD_HTTP_OK, r); - http_code = MHD_HTTP_OK; + if ((cust_homepage_redirect) != "" && (url1 == "/")) + { + // redirect to given custom --homepage + MHD_add_response_header(r, "Location", cust_homepage_redirect.c_str()); + rc = MHD_queue_response (connection, MHD_HTTP_FOUND, r); + http_code = MHD_HTTP_FOUND; + } + else + { + rc = MHD_queue_response (connection, MHD_HTTP_OK, r); + http_code = MHD_HTTP_OK; + } MHD_destroy_response (r); } catch (const reportable_exception& e) diff --git a/doc/debuginfod.8 b/doc/debuginfod.8 index d7744db1..ead3d3b1 100644 --- a/doc/debuginfod.8 +++ b/doc/debuginfod.8 @@ -312,6 +312,16 @@ from the Fedora koji sigcache rpm.sig files as opposed to the original RPM heade If a signature cannot be found in the sigcache rpm.sig file, the RPM will be tried as a fallback. +.TP +.B "\-\-home\-redirect" +Allow for redirecting to a custom URL in case client requests the +document root. + +.TP +.B "\-\-home\-html" +Allow for serving a custom text/html FILE in case client requests +the document root. + .TP .B "\-v" Increase verbosity of logging to the standard error file descriptor. diff --git a/tests/Makefile.am b/tests/Makefile.am index 15c32a85..3702444d 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -296,7 +296,8 @@ TESTS += run-srcfiles-self.sh \ run-debuginfod-IXr.sh \ run-debuginfod-client-profile.sh \ run-debuginfod-find-metadata.sh \ - run-debuginfod-longsource.sh + run-debuginfod-longsource.sh \ + run-debuginfod-homesite.sh if LZMA TESTS += run-debuginfod-seekable.sh endif @@ -636,6 +637,7 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \ run-debuginfod-ima-verification.sh \ run-debuginfod-find-metadata.sh \ run-debuginfod-longsource.sh \ + run-debuginfod-homesite.sh \ debuginfod-rpms/fedora30/hello2-1.0-2.src.rpm \ debuginfod-rpms/fedora30/hello2-1.0-2.x86_64.rpm \ debuginfod-rpms/fedora30/hello2-debuginfo-1.0-2.x86_64.rpm \ diff --git a/tests/run-debuginfod-homesite.sh b/tests/run-debuginfod-homesite.sh new file mode 100644 index 00000000..d107dddc --- /dev/null +++ b/tests/run-debuginfod-homesite.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2022 Red Hat, Inc. +# This file is part of elfutils. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# elfutils is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +type socat 2>/dev/null || exit 77 + +. $srcdir/debuginfod-subr.sh # includes set -e + +set -x + +# This variable is essential and ensures no time-race for claiming ports occurs +# set base to a unique multiple of 100 not used in any other 'run-debuginfod-*' test +base=10200 +get_ports + +tempfiles vlog$PORT1 +errfiles vlog$PORT1 + +# Test 1: Make sure attempt to open non-existent --home-html is handled gracefully +rurl="https://sourceware.org/elfutils/Debuginfod.html" +env LD_LIBRARY_PATH=$ldpath DEBUGINFOD_URLS= ${abs_builddir}/../debuginfod/debuginfod \ + $VERBOSE -p $PORT1 --home-html=non-existent.html --home-redirect=$rurl > vlog$PORT1 2>&1 & +PID1=$! +# Server must become ready +wait_ready $PORT1 'ready' 1 +echo -e 'GET / HTTP/1.1\nHost: localhost\n' | socat - TCP:127.0.0.1:$PORT1 > response.txt +tempfiles response.txt +# If non-existent --home-html is passed, server should only send headers +# incl. the --home-redirect in this case ... +grep -F "Location: $rurl" response.txt +# ... followed by the version id. +tail -1 response.txt | grep -F 'debuginfod' +kill $PID1 +wait $PID1 + +# Test 2: Test valid --home-redirect +echo "<html><body>hiya from debuginfod</body></html>" > home.html +tempfiles home.html +rurl="https://sourceware.org/elfutils/Debuginfod.html" +env LD_LIBRARY_PATH=$ldpath DEBUGINFOD_URLS= ${abs_builddir}/../debuginfod/debuginfod \ + $VERBOSE -p $PORT1 --home-html=home.html --home-redirect=$rurl > vlog$PORT1 2>&1 & +PID1=$! +# Server must become ready +wait_ready $PORT1 'ready' 1 +echo -e 'GET / HTTP/1.1\nHost: localhost\n' | socat - TCP:127.0.0.1:$PORT1 > response.txt +tempfiles response.txt +grep -F 'hiya from debuginfod' response.txt +grep -F "Location: $rurl" response.txt +kill $PID1 +wait $PID1 + +PID1=0 +exit 0 -- 2.51.1
