diff options
author | Frank Ch. Eigler <fche@redhat.com> | 2022-09-02 12:41:38 -0400 |
---|---|---|
committer | Frank Ch. Eigler <fche@redhat.com> | 2022-09-07 12:57:55 -0400 |
commit | 8760e931abf33ed2b215809d5ebf653ced934152 (patch) | |
tree | 4af17d26395a11eee70bec32b005380539c013a5 /debuginfod | |
parent | bbc2ca6d553f0ce3e670303ac9a3c764cf10d779 (diff) | |
download | elfutils-8760e931abf33ed2b215809d5ebf653ced934152.tar.gz |
PR28284: add tweaks on previous debuginfod x-debuginfod* header forwarding work
Embrace case-independent headers, more fully document, handle HTTP \r.
In addition to test case, hand-tested against fedora debuginfod
instances, running federated servers under valgrind.
Signed-off-by: Frank Ch. Eigler <fche@redhat.com>
Diffstat (limited to 'debuginfod')
-rw-r--r-- | debuginfod/ChangeLog | 14 | ||||
-rw-r--r-- | debuginfod/debuginfod-client.c | 28 | ||||
-rw-r--r-- | debuginfod/debuginfod-find.c | 3 | ||||
-rw-r--r-- | debuginfod/debuginfod.cxx | 26 | ||||
-rw-r--r-- | debuginfod/debuginfod.h.in | 4 | ||||
-rw-r--r-- | debuginfod/libdebuginfod.map | 2 |
6 files changed, 47 insertions, 30 deletions
diff --git a/debuginfod/ChangeLog b/debuginfod/ChangeLog index 8c843f3a..bc6c11c9 100644 --- a/debuginfod/ChangeLog +++ b/debuginfod/ChangeLog @@ -1,11 +1,21 @@ +2022-09-06 Frank Ch. Eigler <fche@redhat.com> + + * debuginfod-client.c (header_callback): Don't copy \r in x-d headers. + Print all headers in verbose_fd mode. + * debuginfod-find.c (parse_opt): Set verbose_fd only at verbosity >= 2. + * debuginfod.cxx (handle_buildid): Clean up header forwarding + string processing. + * debuginfod.h.in: (debuginfod_get_headers): Tweak wording. + * libdebuginfod.map: Use ELFUTILS_0.188 for new function. + 2022-07-15 Noah Sanci <nsanci@redhat.com> - * debuginfod-client.c (header_callback): Handle headers without + * debuginfod-client.c (header_callback): Ignore headers without X-DEBUGINFOD prefix. (debuginfod_query_server): Removed verbose printing headers when undesired. (debuginfod_get_headers): Created. - * debuginfod-find.c (main): Verboes printing headers. + * debuginfod-find.c (main): Verbose printing headers. * debuginfod.cxx (handle_buildid): Add headers prefixed with X-DEBUGINFOD from federated servers to this server's response headers. diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c index a3565f57..54dc3f2f 100644 --- a/debuginfod/debuginfod-client.c +++ b/debuginfod/debuginfod-client.c @@ -499,33 +499,37 @@ default_progressfn (debuginfod_client *c, long a, long b) static size_t header_callback (char * buffer, size_t size, size_t numitems, void * userdata) { + struct handle_data *data = (struct handle_data *) userdata; if (size != 1) return 0; - // X-DEBUGINFOD is 11 characters long. + if (data->client && data->client->verbose_fd >= 0) + dprintf (data->client->verbose_fd, "header %.*s", (int)numitems, buffer); // Some basic checks to ensure the headers received are of the expected format - if ( strncmp(buffer, "X-DEBUGINFOD", 11) || buffer[numitems-1] != '\n' - || (buffer == strstr(buffer, ":")) ){ + if (strncasecmp(buffer, "X-DEBUGINFOD", 11) + || buffer[numitems-2] != '\r' + || buffer[numitems-1] != '\n' + || (buffer == strstr(buffer, ":")) ){ return numitems; } /* Temporary buffer for realloc */ char *temp = NULL; - struct handle_data *data = (struct handle_data *) userdata; if (data->response_data == NULL) { - temp = malloc(numitems+1); + temp = malloc(numitems); if (temp == NULL) return 0; } else { - temp = realloc(data->response_data, data->response_data_size + numitems + 1); + temp = realloc(data->response_data, data->response_data_size + numitems); if (temp == NULL) return 0; } - memcpy(temp + data->response_data_size, buffer, numitems); + memcpy(temp + data->response_data_size, buffer, numitems-1); data->response_data = temp; - data->response_data_size += numitems; + data->response_data_size += numitems-1; + data->response_data[data->response_data_size-1] = '\n'; data->response_data[data->response_data_size] = '\0'; return numitems; } @@ -1072,11 +1076,9 @@ debuginfod_query_server (debuginfod_client *c, int committed_to = -1; bool verbose_reported = false; struct timespec start_time, cur_time; - if (c->winning_headers != NULL) - { - free (c->winning_headers); - c->winning_headers = NULL; - } + + free (c->winning_headers); + c->winning_headers = NULL; if ( maxtime > 0 && clock_gettime(CLOCK_MONOTONIC_RAW, &start_time) == -1) { rc = errno; diff --git a/debuginfod/debuginfod-find.c b/debuginfod/debuginfod-find.c index fb1f294c..778fb09b 100644 --- a/debuginfod/debuginfod-find.c +++ b/debuginfod/debuginfod-find.c @@ -99,7 +99,8 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state) { case 'v': verbose++; debuginfod_set_progressfn (client, & progressfn); - debuginfod_set_verbose_fd (client, STDERR_FILENO); + if (verbose > 1) + debuginfod_set_verbose_fd (client, STDERR_FILENO); break; default: return ARGP_ERR_UNKNOWN; } diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx index 27b671d3..000a41c4 100644 --- a/debuginfod/debuginfod.cxx +++ b/debuginfod/debuginfod.cxx @@ -2093,22 +2093,26 @@ and will not query the upstream servers"); { add_mhd_response_header (r, "Content-Type", "application/octet-stream"); + // Copy the incoming headers const char * hdrs = debuginfod_get_headers(client); string header_dup; if (hdrs) header_dup = string(hdrs); - size_t pos = 0; - // Clean winning headers to add all X-DEBUGINFOD lines to the package we'll send - while( (pos = header_dup.find("X-DEBUGINFOD")) != string::npos) + // Parse the "header: value\n" lines into (h,v) tuples and pass on + while(1) { - // Focus on where X-DEBUGINFOD- begins - header_dup = header_dup.substr(pos); - size_t newline = header_dup.find('\n'); - if (newline == string::npos) - break; - add_mhd_response_header(r, header_dup.substr(0,header_dup.find(':')).c_str(), - header_dup.substr(header_dup.find(':')).c_str()); - header_dup = header_dup.substr(newline); + size_t newline = header_dup.find('\n'); + if (newline == string::npos) break; + size_t colon = header_dup.find(':'); + if (colon == string::npos) break; + string header = header_dup.substr(0,colon); + string value = header_dup.substr(colon+1,newline-colon-1); + // strip leading spaces from value + size_t nonspace = value.find_first_not_of(" "); + if (nonspace != string::npos) + value = value.substr(nonspace); + add_mhd_response_header(r, header.c_str(), value.c_str()); + header_dup = header_dup.substr(newline+1); } add_mhd_last_modified (r, s.st_mtime); diff --git a/debuginfod/debuginfod.h.in b/debuginfod/debuginfod.h.in index 6ae8b91c..40b1ea00 100644 --- a/debuginfod/debuginfod.h.in +++ b/debuginfod/debuginfod.h.in @@ -93,8 +93,8 @@ void* debuginfod_get_user_data (debuginfod_client *client); /* Get the current or last active URL, if known. */ const char* debuginfod_get_url (debuginfod_client *client); -/* Returns all headers sent to this client which were prefixed - * with X-DEBUGINFOD */ +/* Returns set of x-debuginfod* header lines received from current or + last active transfer, \n separated, if known. */ const char* debuginfod_get_headers(debuginfod_client *client); /* Add an outgoing HTTP request "Header: Value". Copies string. */ diff --git a/debuginfod/libdebuginfod.map b/debuginfod/libdebuginfod.map index f95b5b9a..93964167 100644 --- a/debuginfod/libdebuginfod.map +++ b/debuginfod/libdebuginfod.map @@ -18,6 +18,6 @@ ELFUTILS_0.179 { ELFUTILS_0.183 { debuginfod_set_verbose_fd; } ELFUTILS_0.179; -ELFUTILS_0.189 { +ELFUTILS_0.188 { debuginfod_get_headers; } ELFUTILS_0.183; |