summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNoah Sanci <nsanci@redhat.com>2022-06-15 10:07:29 -0400
committerFrank Ch. Eigler <fche@redhat.com>2022-09-06 11:32:13 -0400
commitbbc2ca6d553f0ce3e670303ac9a3c764cf10d779 (patch)
treeb08f81afb310c8c46cffdbeeb8e7881f7401573f
parentdebuginfod: Use auto-sized connection pool when -C is not given with arg (diff)
downloadelfutils-bbc2ca6d553f0ce3e670303ac9a3c764cf10d779.tar.gz
elfutils-bbc2ca6d553f0ce3e670303ac9a3c764cf10d779.tar.bz2
elfutils-bbc2ca6d553f0ce3e670303ac9a3c764cf10d779.tar.xz
PR28284 - Debuginfod header functionality implemented
Debuginfod and debuginfod clients are now equipped to send and receive http headers prefixed with X-DEBUGINFOD and print them in verbose mode for more context Signed-off-by: Noah Sanci <nsanci@redhat.com>
-rw-r--r--debuginfod/ChangeLog14
-rw-r--r--debuginfod/debuginfod-client.c14
-rw-r--r--debuginfod/debuginfod-find.c3
-rw-r--r--debuginfod/debuginfod.cxx18
-rw-r--r--debuginfod/debuginfod.h.in4
-rw-r--r--debuginfod/libdebuginfod.map3
-rw-r--r--doc/ChangeLog5
-rw-r--r--doc/debuginfod_find_debuginfo.313
-rw-r--r--doc/debuginfod_get_headers.32
-rw-r--r--tests/ChangeLog6
-rwxr-xr-xtests/run-debuginfod-response-headers.sh48
11 files changed, 122 insertions, 8 deletions
diff --git a/debuginfod/ChangeLog b/debuginfod/ChangeLog
index c692a389..8c843f3a 100644
--- a/debuginfod/ChangeLog
+++ b/debuginfod/ChangeLog
@@ -1,3 +1,17 @@
12022-07-15 Noah Sanci <nsanci@redhat.com>
2
3 * debuginfod-client.c (header_callback): Handle headers without
4 X-DEBUGINFOD prefix.
5 (debuginfod_query_server): Removed verbose printing headers when
6 undesired.
7 (debuginfod_get_headers): Created.
8 * debuginfod-find.c (main): Verboes printing headers.
9 * debuginfod.cxx (handle_buildid): Add headers prefixed with
10 X-DEBUGINFOD from federated servers to this server's response
11 headers.
12 * debuginfod.h.in (debuginfod_get_headers): Created.
13 * libdebuginfod.map: New elfutils version added.
14
12022-09-02 Aaron Merey <amerey@redhat.com> 152022-09-02 Aaron Merey <amerey@redhat.com>
2 16
3 * debuginfod.cxx (parse_opt): If '-C' is given with no arg, do not 17 * debuginfod.cxx (parse_opt): If '-C' is given with no arg, do not
diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c
index b7b65aff..a3565f57 100644
--- a/debuginfod/debuginfod-client.c
+++ b/debuginfod/debuginfod-client.c
@@ -501,6 +501,12 @@ header_callback (char * buffer, size_t size, size_t numitems, void * userdata)
501{ 501{
502 if (size != 1) 502 if (size != 1)
503 return 0; 503 return 0;
504 // X-DEBUGINFOD is 11 characters long.
505 // Some basic checks to ensure the headers received are of the expected format
506 if ( strncmp(buffer, "X-DEBUGINFOD", 11) || buffer[numitems-1] != '\n'
507 || (buffer == strstr(buffer, ":")) ){
508 return numitems;
509 }
504 /* Temporary buffer for realloc */ 510 /* Temporary buffer for realloc */
505 char *temp = NULL; 511 char *temp = NULL;
506 struct handle_data *data = (struct handle_data *) userdata; 512 struct handle_data *data = (struct handle_data *) userdata;
@@ -1111,8 +1117,6 @@ debuginfod_query_server (debuginfod_client *c,
1111 if (c->winning_headers == NULL) 1117 if (c->winning_headers == NULL)
1112 { 1118 {
1113 c->winning_headers = data[committed_to].response_data; 1119 c->winning_headers = data[committed_to].response_data;
1114 if (vfd >= 0 && c->winning_headers != NULL)
1115 dprintf(vfd, "\n%s", c->winning_headers);
1116 data[committed_to].response_data = NULL; 1120 data[committed_to].response_data = NULL;
1117 data[committed_to].response_data_size = 0; 1121 data[committed_to].response_data_size = 0;
1118 } 1122 }
@@ -1542,6 +1546,12 @@ debuginfod_get_url(debuginfod_client *client)
1542 return client->url; 1546 return client->url;
1543} 1547}
1544 1548
1549const char *
1550debuginfod_get_headers(debuginfod_client *client)
1551{
1552 return client->winning_headers;
1553}
1554
1545void 1555void
1546debuginfod_end (debuginfod_client *client) 1556debuginfod_end (debuginfod_client *client)
1547{ 1557{
diff --git a/debuginfod/debuginfod-find.c b/debuginfod/debuginfod-find.c
index f60b5463..fb1f294c 100644
--- a/debuginfod/debuginfod-find.c
+++ b/debuginfod/debuginfod-find.c
@@ -215,6 +215,9 @@ main(int argc, char** argv)
215 215
216 if (verbose) 216 if (verbose)
217 { 217 {
218 const char* headers = debuginfod_get_headers(client);
219 if (headers)
220 fprintf(stderr, "Headers:\n%s", headers);
218 const char* url = debuginfod_get_url (client); 221 const char* url = debuginfod_get_url (client);
219 if (url != NULL) 222 if (url != NULL)
220 fprintf(stderr, "Downloaded from %s\n", url); 223 fprintf(stderr, "Downloaded from %s\n", url);
diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx
index 8680c048..27b671d3 100644
--- a/debuginfod/debuginfod.cxx
+++ b/debuginfod/debuginfod.cxx
@@ -2093,6 +2093,24 @@ and will not query the upstream servers");
2093 { 2093 {
2094 add_mhd_response_header (r, "Content-Type", 2094 add_mhd_response_header (r, "Content-Type",
2095 "application/octet-stream"); 2095 "application/octet-stream");
2096 const char * hdrs = debuginfod_get_headers(client);
2097 string header_dup;
2098 if (hdrs)
2099 header_dup = string(hdrs);
2100 size_t pos = 0;
2101 // Clean winning headers to add all X-DEBUGINFOD lines to the package we'll send
2102 while( (pos = header_dup.find("X-DEBUGINFOD")) != string::npos)
2103 {
2104 // Focus on where X-DEBUGINFOD- begins
2105 header_dup = header_dup.substr(pos);
2106 size_t newline = header_dup.find('\n');
2107 if (newline == string::npos)
2108 break;
2109 add_mhd_response_header(r, header_dup.substr(0,header_dup.find(':')).c_str(),
2110 header_dup.substr(header_dup.find(':')).c_str());
2111 header_dup = header_dup.substr(newline);
2112 }
2113
2096 add_mhd_last_modified (r, s.st_mtime); 2114 add_mhd_last_modified (r, s.st_mtime);
2097 if (verbose > 1) 2115 if (verbose > 1)
2098 obatched(clog) << "serving file from upstream debuginfod/cache" << endl; 2116 obatched(clog) << "serving file from upstream debuginfod/cache" << endl;
diff --git a/debuginfod/debuginfod.h.in b/debuginfod/debuginfod.h.in
index c358df4d..6ae8b91c 100644
--- a/debuginfod/debuginfod.h.in
+++ b/debuginfod/debuginfod.h.in
@@ -93,6 +93,10 @@ void* debuginfod_get_user_data (debuginfod_client *client);
93/* Get the current or last active URL, if known. */ 93/* Get the current or last active URL, if known. */
94const char* debuginfod_get_url (debuginfod_client *client); 94const char* debuginfod_get_url (debuginfod_client *client);
95 95
96/* Returns all headers sent to this client which were prefixed
97 * with X-DEBUGINFOD */
98const char* debuginfod_get_headers(debuginfod_client *client);
99
96/* Add an outgoing HTTP request "Header: Value". Copies string. */ 100/* Add an outgoing HTTP request "Header: Value". Copies string. */
97int debuginfod_add_http_header (debuginfod_client *client, const char* header); 101int debuginfod_add_http_header (debuginfod_client *client, const char* header);
98 102
diff --git a/debuginfod/libdebuginfod.map b/debuginfod/libdebuginfod.map
index 7d2f5882..f95b5b9a 100644
--- a/debuginfod/libdebuginfod.map
+++ b/debuginfod/libdebuginfod.map
@@ -18,3 +18,6 @@ ELFUTILS_0.179 {
18ELFUTILS_0.183 { 18ELFUTILS_0.183 {
19 debuginfod_set_verbose_fd; 19 debuginfod_set_verbose_fd;
20} ELFUTILS_0.179; 20} ELFUTILS_0.179;
21ELFUTILS_0.189 {
22 debuginfod_get_headers;
23} ELFUTILS_0.183;
diff --git a/doc/ChangeLog b/doc/ChangeLog
index 3fff1a84..c2a01a04 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,8 @@
12022-07-15 Noah Sanci <nsanci@redhat.com>
2 * debuginfod_find_debuginfo.3: Explained debuginfod_get_headers
3 usage.
4 * debuginfod_get_headers.3: Created.
5
12022-09-02 Aaron Merey <amerey@redhat.com> 62022-09-02 Aaron Merey <amerey@redhat.com>
2 7
3 * debuginfod.8 (-C): Update description. 8 * debuginfod.8 (-C): Update description.
diff --git a/doc/debuginfod_find_debuginfo.3 b/doc/debuginfod_find_debuginfo.3
index 30cef3c1..984fda12 100644
--- a/doc/debuginfod_find_debuginfo.3
+++ b/doc/debuginfod_find_debuginfo.3
@@ -58,6 +58,7 @@ OPTIONAL FUNCTIONS
58.BI "const char* debuginfod_get_url(debuginfod_client *" client ");" 58.BI "const char* debuginfod_get_url(debuginfod_client *" client ");"
59.BI "int debuginfod_add_http_header(debuginfod_client *" client "," 59.BI "int debuginfod_add_http_header(debuginfod_client *" client ","
60.BI " const char* " header ");" 60.BI " const char* " header ");"
61.BI "const char* debuginfod_get_headers(debuginfod_client *" client ");"
61 62
62.SH DESCRIPTION 63.SH DESCRIPTION
63 64
@@ -198,6 +199,18 @@ By default, the library adds a descriptive \fIUser-Agent:\fP
198header to outgoing requests. If the client application adds 199header to outgoing requests. If the client application adds
199a header with the same name, this default is suppressed. 200a header with the same name, this default is suppressed.
200 201
202.BR \%debuginfod_get_headers ()
203may be called with a debuginfod client. This function will return the
204http response headers prefixed with
205.BR X-DEBUGINFOD
206received from the first handle to get a response from a debuginfod server.
207Note that all other http headers aren't stored in the libcurl header
208callback function since they aren't of as much interest. The caller should
209copy the returned string if it is needed beyond the release of the client object.
210The returned string may be NULL if no headers are prefixed with
211.BR X-DEBUGINFOD
212\.
213
201.SH "MACROS" 214.SH "MACROS"
202 215
203.SS "DEBUGINFOD_SONAME" 216.SS "DEBUGINFOD_SONAME"
diff --git a/doc/debuginfod_get_headers.3 b/doc/debuginfod_get_headers.3
new file mode 100644
index 00000000..1db55982
--- /dev/null
+++ b/doc/debuginfod_get_headers.3
@@ -0,0 +1,2 @@
1.so man3/debuginfod_find_debuginfo.3
2
diff --git a/tests/ChangeLog b/tests/ChangeLog
index d2952cc9..659bfa19 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,9 @@
12022-07-15 Noah Sanci <nsanci@redhat.com>
2
3 * run-debuginfod-response-headers.sh: Added test
4 to ensure that federated servers pass headers down to
5 queried server.
6
12022-08-04 Sergei Trofimovich <slyich@gmail.com> 72022-08-04 Sergei Trofimovich <slyich@gmail.com>
2 8
3 * low_high_pc.c (handle_die): Drop redundant 'lx' suffix. 9 * low_high_pc.c (handle_die): Drop redundant 'lx' suffix.
diff --git a/tests/run-debuginfod-response-headers.sh b/tests/run-debuginfod-response-headers.sh
index 62c43887..e5698cc9 100755
--- a/tests/run-debuginfod-response-headers.sh
+++ b/tests/run-debuginfod-response-headers.sh
@@ -73,17 +73,21 @@ rm -rf $DEBUGINFOD_CACHE_PATH
73env DEBUGINFOD_URLS="http://127.0.0.1:"$PORT1 LD_LIBRARY_PATH=$ldpath ${abs_top_builddir}/debuginfod/debuginfod-find\ 73env DEBUGINFOD_URLS="http://127.0.0.1:"$PORT1 LD_LIBRARY_PATH=$ldpath ${abs_top_builddir}/debuginfod/debuginfod-find\
74 -vvv executable F/prog > vlog-find$PORT1.1 2>&1 74 -vvv executable F/prog > vlog-find$PORT1.1 2>&1
75tempfiles vlog-find$PORT1.1 75tempfiles vlog-find$PORT1.1
76grep 'Content-Length: ' vlog-find$PORT1.1 76errfiles vlog-find$PORT1.1
77grep 'X-DEBUGINFOD-FILE: ' vlog-find$PORT1.1 77cat vlog-find$PORT1.1
78grep 'X-DEBUGINFOD-SIZE: ' vlog-find$PORT1.1 78grep 'Headers:' vlog-find$PORT1.1
79grep 'X-DEBUGINFOD-FILE: prog' vlog-find$PORT1.1
80grep 'X-DEBUGINFOD-SIZE: ' vlog-find$PORT1.1
79 81
80# Check to see if an executable file located in an archive prints the file's description and archive 82# Check to see if an executable file located in an archive prints the file's description and archive
81env DEBUGINFOD_URLS="http://127.0.0.1:"$PORT1 LD_LIBRARY_PATH=$ldpath ${abs_top_builddir}/debuginfod/debuginfod-find\ 83env DEBUGINFOD_URLS="http://127.0.0.1:"$PORT1 LD_LIBRARY_PATH=$ldpath ${abs_top_builddir}/debuginfod/debuginfod-find\
82 -vvv executable c36708a78618d597dee15d0dc989f093ca5f9120 > vlog-find$PORT1.2 2>&1 84 -vvv executable c36708a78618d597dee15d0dc989f093ca5f9120 > vlog-find$PORT1.2 2>&1
83tempfiles vlog-find$PORT1.2 85tempfiles vlog-find$PORT1.2
84grep 'Content-Length: ' vlog-find$PORT1.2 86errfiles vlog-find$PORT1.2
85grep 'X-DEBUGINFOD-FILE: ' vlog-find$PORT1.2 87cat vlog-find$PORT1.2
86grep 'X-DEBUGINFOD-SIZE: ' vlog-find$PORT1.2 88grep 'Headers:' vlog-find$PORT1.2
89grep 'X-DEBUGINFOD-FILE: ' vlog-find$PORT1.2
90grep 'X-DEBUGINFOD-SIZE: ' vlog-find$PORT1.2
87grep 'X-DEBUGINFOD-ARCHIVE: ' vlog-find$PORT1.2 91grep 'X-DEBUGINFOD-ARCHIVE: ' vlog-find$PORT1.2
88 92
89# Check that X-DEBUGINFOD-SIZE matches the size of each file 93# Check that X-DEBUGINFOD-SIZE matches the size of each file
@@ -94,6 +98,38 @@ do
94 test $st_size -eq $x_debuginfod_size 98 test $st_size -eq $x_debuginfod_size
95done 99done
96 100
101rm -rf $DEBUGINFOD_CACHE_PATH
102BUILDID=`env LD_LIBRARY_PATH=$ldpath ${abs_builddir}/../src/readelf \
103 -a F/prog | grep 'Build ID' | cut -d ' ' -f 7`
104netcat_dir="buildid/$BUILDID/"
105mkdir -p ${PWD}/$netcat_dir
106cp F/prog ${PWD}/$netcat_dir/executable
107tempfiles F/prog
108
109# Netcat dies after answering the request
110nc -l -p $PORT2 -c 'echo -e "HTTP/1.1 200 OK\nX-DEBUGINFOD-SIZE: ba:d_size\nX-DEBUGINFOD-\rFILE:\=\+ \r213\n\n $(date)"' & < ${PWD}/$netcat_dir"executable" &
111# Wait until the netcat port is in use. Otherwise debuginfod-find can query
112# before netcat is ready.
113SECONDS=0
114nc_start=$SECONDS
115while [ ! $(lsof -i -P -n | grep LISTEN | grep "nc.*$PORT2") ]
116do
117 # If it takes longer than 5 seconds for netcat to start up, then fail
118 duration=$(( SECONDS - nc_start ))
119 if [ $SECONDS -gt 5 ]
120 then
121 err
122 fi
123done
124
125env DEBUGINFOD_URLS="http://127.0.0.1:"$PORT2 LD_LIBRARY_PATH=$ldpath ${abs_top_builddir}/debuginfod/debuginfod-find\
126 -vvv executable $BUILDID > vlog-find$PORT2 2>&1
127errfiles vlog-find$PORT2
128tempfiles vlog-find$PORT2
129cat vlog-find$PORT2 | grep "X-DEBUGINFOD-"
130rm -f "$netcat_dir"executable
131rmdir -p $netcat_dir
132
97kill $PID1 133kill $PID1
98wait $PID1 134wait $PID1
99PID1=0 135PID1=0