diff options
author | Frank Ch. Eigler <fche@redhat.com> | 2020-01-06 04:29:21 -0500 |
---|---|---|
committer | Frank Ch. Eigler <fche@redhat.com> | 2020-01-09 16:14:51 -0500 |
commit | 288c76775f2d27976eb269e568b53c742d973dbc (patch) | |
tree | df880167ce0836d4b5785559ba332781a8910edb | |
parent | fed3c3ceeaa6aef0c94932ea2636bc0070fefd00 (diff) | |
download | elfutils-288c76775f2d27976eb269e568b53c742d973dbc.tar.gz |
debuginfod: pass a distro-summary User-Agent request header
It may be useful for a debuginfod server operator to know what kinds
of clients make webapi requests. This is mainly as a
telemetry/diagnostic (though the data cannot be really trusted). It
may also be useful to automate downloading of distro packages to a
debuginfod server in the case of an unknown hex buildid. doc/testing
not affected as these are diagnostics.
Signed-off-by: Frank Ch. Eigler <fche@redhat.com>
Signed-off-by: Mark Wielaard <mjw@redhat.com>
-rw-r--r-- | debuginfod/ChangeLog | 6 | ||||
-rw-r--r-- | debuginfod/debuginfod-client.c | 86 |
2 files changed, 90 insertions, 2 deletions
diff --git a/debuginfod/ChangeLog b/debuginfod/ChangeLog index 1582eba5..6cfb4e24 100644 --- a/debuginfod/ChangeLog +++ b/debuginfod/ChangeLog @@ -1,3 +1,9 @@ +2020-01-09 Frank Ch. Eigler <fche@redhat.com> + + * debuginfod-client.c (add_extra_headers): New function, + based on mjw's draft. + (debuginfod_query_server): Call it. + 2019-12-22 Frank Ch. Eigler <fche@redhat.com> * debuginfod.cxx (*_rpm_*): Rename to *_archive_* throughout. diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c index 9a4a0e0f..66ccb21a 100644 --- a/debuginfod/debuginfod-client.c +++ b/debuginfod/debuginfod-client.c @@ -1,5 +1,5 @@ /* Retrieve ELF / DWARF / source files from the debuginfod. - Copyright (C) 2019 Red Hat, Inc. + Copyright (C) 2019-2020 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -58,6 +58,7 @@ #include <sys/syscall.h> #include <sys/types.h> #include <sys/stat.h> +#include <sys/utsname.h> #include <curl/curl.h> /* If fts.h is included before config.h, its indirect inclusions may not @@ -279,6 +280,87 @@ debuginfod_clean_cache(debuginfod_client *c, #define MAX_BUILD_ID_BYTES 64 +static void +add_extra_headers(CURL *handle) +{ + /* Compute a User-Agent: string to send. The more accurately this + describes this host, the likelier that the debuginfod servers + might be able to locate debuginfo for us. */ + + char* utspart = NULL; + struct utsname uts; + int rc = 0; + rc = uname (&uts); + if (rc == 0) + rc = asprintf(& utspart, "%s/%s", uts.sysname, uts.machine); + if (rc < 0) + utspart = NULL; + + FILE *f = fopen ("/etc/os-release", "r"); + if (f == NULL) + f = fopen ("/usr/lib/os-release", "r"); + char *id = NULL; + char *version = NULL; + if (f != NULL) + { + while (id == NULL || version == NULL) + { + char buf[128]; + char *s = &buf[0]; + if (fgets (s, sizeof(buf), f) == NULL) + break; + + int len = strlen (s); + if (len < 3) + continue; + if (s[len - 1] == '\n') + { + s[len - 1] = '\0'; + len--; + } + + char *v = strchr (s, '='); + if (v == NULL || strlen (v) < 2) + continue; + + /* Split var and value. */ + *v = '\0'; + v++; + + /* Remove optional quotes around value string. */ + if (*v == '"' || *v == '\'') + { + v++; + s[len - 1] = '\0'; + } + if (strcmp (s, "ID") == 0) + id = strdup (v); + if (strcmp (s, "VERSION_ID") == 0) + version = strdup (v); + } + fclose (f); + } + + char *ua = NULL; + rc = asprintf(& ua, "%s/%s,%s,%s/%s", + PACKAGE_NAME, PACKAGE_VERSION, + utspart ?: "", + id ?: "", + version ?: ""); + if (rc < 0) + ua = NULL; + + if (ua) + curl_easy_setopt(handle, CURLOPT_USERAGENT, (void*) ua); /* implicit strdup */ + + free (ua); + free (id); + free (version); + free (utspart); +} + + + /* Query each of the server URLs found in $DEBUGINFOD_URLS for the file with the specified build-id, type (debuginfo, executable or source) and filename. filename may be NULL. If found, return a file @@ -514,7 +596,7 @@ debuginfod_query_server (debuginfod_client *c, curl_easy_setopt(data[i].handle, CURLOPT_NOSIGNAL, (long) 1); curl_easy_setopt(data[i].handle, CURLOPT_AUTOREFERER, (long) 1); curl_easy_setopt(data[i].handle, CURLOPT_ACCEPT_ENCODING, ""); - curl_easy_setopt(data[i].handle, CURLOPT_USERAGENT, (void*) PACKAGE_STRING); + add_extra_headers(data[i].handle); curl_multi_add_handle(curlm, data[i].handle); server_url = strtok_r(NULL, url_delim, &strtok_saveptr); |