Blame SOURCES/elfutils-0.178-debuginfod-timeoutprogress.patch

ca9947
commit 76ad56c430f0b85c47115688c511d9bd4fa671d4
ca9947
Author: Frank Ch. Eigler <fche@redhat.com>
ca9947
Date:   Wed Dec 4 15:51:12 2019 -0500
ca9947
ca9947
    debuginfod: usability tweaks, incl. $DEBUGINFOD_PROGRESS client support
ca9947
    
ca9947
    This facility allows a default progress-printing function to be
ca9947
    installed if the given environment variable is set.  Some larger usage
ca9947
    experience (systemtap fetching kernels) indicates the default timeout
ca9947
    is too short, so forked it into a connection timeout (default short)
ca9947
    and a transfer timeout (default unlimited).
ca9947
    
ca9947
    Signed-off-by: Frank Ch. Eigler <fche@redhat.com>
ca9947
ca9947
diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c
ca9947
index ab7b4e1..9a4a0e0 100644
ca9947
--- a/debuginfod/debuginfod-client.c
ca9947
+++ b/debuginfod/debuginfod-client.c
ca9947
@@ -40,6 +40,7 @@
ca9947
 
ca9947
 #include "config.h"
ca9947
 #include "debuginfod.h"
ca9947
+#include "system.h"
ca9947
 #include <assert.h>
ca9947
 #include <dirent.h>
ca9947
 #include <stdio.h>
ca9947
@@ -98,16 +99,16 @@ static const time_t cache_default_max_unused_age_s = 604800; /* 1 week */
ca9947
 static const char *cache_default_name = ".debuginfod_client_cache";
ca9947
 static const char *cache_path_envvar = DEBUGINFOD_CACHE_PATH_ENV_VAR;
ca9947
 
ca9947
-/* URLs of debuginfods, separated by url_delim.
ca9947
-   This env var must be set for debuginfod-client to run.  */
ca9947
+/* URLs of debuginfods, separated by url_delim. */
ca9947
 static const char *server_urls_envvar = DEBUGINFOD_URLS_ENV_VAR;
ca9947
 static const char *url_delim =  " ";
ca9947
 static const char url_delim_char = ' ';
ca9947
 
ca9947
-/* Timeout for debuginfods, in seconds.
ca9947
-   This env var must be set for debuginfod-client to run.  */
ca9947
+/* Timeout for debuginfods, in seconds. */
ca9947
 static const char *server_timeout_envvar = DEBUGINFOD_TIMEOUT_ENV_VAR;
ca9947
-static int server_timeout = 5;
ca9947
+static const long default_connect_timeout = 5;
ca9947
+static const long default_transfer_timeout = -1; /* unlimited */
ca9947
+
ca9947
 
ca9947
 /* Data associated with a particular CURL easy handle. Passed to
ca9947
    the write callback.  */
ca9947
@@ -400,8 +401,18 @@ debuginfod_query_server (debuginfod_client *c,
ca9947
       return fd;
ca9947
     }
ca9947
 
ca9947
-  if (getenv(server_timeout_envvar))
ca9947
-    server_timeout = atoi (getenv(server_timeout_envvar));
ca9947
+  long connect_timeout = default_connect_timeout;
ca9947
+  long transfer_timeout = default_transfer_timeout;
ca9947
+  const char* timeout_envvar = getenv(server_timeout_envvar);
ca9947
+  if (timeout_envvar != NULL)
ca9947
+    {
ca9947
+      long ct, tt;
ca9947
+      rc = sscanf(timeout_envvar, "%ld,%ld", &ct, &tt;;
ca9947
+      if (rc >= 1)
ca9947
+        connect_timeout = ct;
ca9947
+      if (rc >= 2)
ca9947
+        transfer_timeout = tt;
ca9947
+    }
ca9947
 
ca9947
   /* make a copy of the envvar so it can be safely modified.  */
ca9947
   server_urls = strdup(urls_envvar);
ca9947
@@ -493,7 +504,10 @@ debuginfod_query_server (debuginfod_client *c,
ca9947
                        CURLOPT_WRITEFUNCTION,
ca9947
                        debuginfod_write_callback);
ca9947
       curl_easy_setopt(data[i].handle, CURLOPT_WRITEDATA, (void*)&data[i]);
ca9947
-      curl_easy_setopt(data[i].handle, CURLOPT_TIMEOUT, (long) server_timeout);
ca9947
+      if (connect_timeout >= 0)
ca9947
+        curl_easy_setopt(data[i].handle, CURLOPT_CONNECTTIMEOUT, connect_timeout);
ca9947
+      if (transfer_timeout >= 0)
ca9947
+        curl_easy_setopt(data[i].handle, CURLOPT_TIMEOUT, transfer_timeout);
ca9947
       curl_easy_setopt(data[i].handle, CURLOPT_FILETIME, (long) 1);
ca9947
       curl_easy_setopt(data[i].handle, CURLOPT_FOLLOWLOCATION, (long) 1);
ca9947
       curl_easy_setopt(data[i].handle, CURLOPT_FAILONERROR, (long) 1);
ca9947
@@ -511,11 +525,32 @@ debuginfod_query_server (debuginfod_client *c,
ca9947
   long loops = 0;
ca9947
   do
ca9947
     {
ca9947
+      /* Wait 1 second, the minimum DEBUGINFOD_TIMEOUT.  */
ca9947
+      curl_multi_wait(curlm, NULL, 0, 1000, NULL);
ca9947
+
ca9947
+      /* If the target file has been found, abort the other queries.  */
ca9947
+      if (target_handle != NULL)
ca9947
+        for (int i = 0; i < num_urls; i++)
ca9947
+          if (data[i].handle != target_handle)
ca9947
+            curl_multi_remove_handle(curlm, data[i].handle);
ca9947
+
ca9947
+      CURLMcode curlm_res = curl_multi_perform(curlm, &still_running);
ca9947
+      if (curlm_res != CURLM_OK)
ca9947
+        {
ca9947
+          switch (curlm_res)
ca9947
+            {
ca9947
+            case CURLM_CALL_MULTI_PERFORM: continue;
ca9947
+            case CURLM_OUT_OF_MEMORY: rc = -ENOMEM; break;
ca9947
+            default: rc = -ENETUNREACH; break;
ca9947
+            }
ca9947
+          goto out1;
ca9947
+        }
ca9947
+
ca9947
       if (c->progressfn) /* inform/check progress callback */
ca9947
         {
ca9947
           loops ++;
ca9947
           long pa = loops; /* default params for progress callback */
ca9947
-          long pb = 0;
ca9947
+          long pb = 0; /* transfer_timeout tempting, but loops != elapsed-time */
ca9947
           if (target_handle) /* we've committed to a server; report its download progress */
ca9947
             {
ca9947
               CURLcode curl_res;
ca9947
@@ -535,6 +570,8 @@ debuginfod_query_server (debuginfod_client *c,
ca9947
                 pa = (dl > LONG_MAX ? LONG_MAX : (long)dl);
ca9947
 #endif
ca9947
 
ca9947
+              /* NB: If going through deflate-compressing proxies, this
ca9947
+                 number is likely to be unavailable, so -1 may show. */
ca9947
 #ifdef CURLINFO_CURLINFO_CONTENT_LENGTH_DOWNLOAD_T
ca9947
               curl_off_t cl;
ca9947
               curl_res = curl_easy_getinfo(target_handle,
ca9947
@@ -555,27 +592,6 @@ debuginfod_query_server (debuginfod_client *c,
ca9947
           if ((*c->progressfn) (c, pa, pb))
ca9947
             break;
ca9947
         }
ca9947
-
ca9947
-      /* Wait 1 second, the minimum DEBUGINFOD_TIMEOUT.  */
ca9947
-      curl_multi_wait(curlm, NULL, 0, 1000, NULL);
ca9947
-
ca9947
-      /* If the target file has been found, abort the other queries.  */
ca9947
-      if (target_handle != NULL)
ca9947
-        for (int i = 0; i < num_urls; i++)
ca9947
-          if (data[i].handle != target_handle)
ca9947
-            curl_multi_remove_handle(curlm, data[i].handle);
ca9947
-
ca9947
-      CURLMcode curlm_res = curl_multi_perform(curlm, &still_running);
ca9947
-      if (curlm_res != CURLM_OK)
ca9947
-        {
ca9947
-          switch (curlm_res)
ca9947
-            {
ca9947
-            case CURLM_CALL_MULTI_PERFORM: continue;
ca9947
-            case CURLM_OUT_OF_MEMORY: rc = -ENOMEM; break;
ca9947
-            default: rc = -ENETUNREACH; break;
ca9947
-            }
ca9947
-          goto out1;
ca9947
-        }
ca9947
     } while (still_running);
ca9947
 
ca9947
   /* Check whether a query was successful. If so, assign its handle
ca9947
@@ -674,9 +690,9 @@ debuginfod_query_server (debuginfod_client *c,
ca9947
 
ca9947
   curl_multi_cleanup(curlm);
ca9947
   unlink (target_cache_tmppath);
ca9947
+  close (fd); /* before the rmdir, otherwise it'll fail */
ca9947
   (void) rmdir (target_cache_dir); /* nop if not empty */
ca9947
   free(data);
ca9947
-  close (fd);
ca9947
 
ca9947
  out0:
ca9947
   free (server_urls);
ca9947
@@ -685,6 +701,22 @@ debuginfod_query_server (debuginfod_client *c,
ca9947
   return rc;
ca9947
 }
ca9947
 
ca9947
+
ca9947
+/* Activate a basic form of progress tracing */
ca9947
+static int
ca9947
+default_progressfn (debuginfod_client *c, long a, long b)
ca9947
+{
ca9947
+  (void) c;
ca9947
+
ca9947
+  dprintf(STDERR_FILENO,
ca9947
+          "Downloading from debuginfod %ld/%ld%s", a, b,
ca9947
+          ((a == b) ? "\n" : "\r"));
ca9947
+  /* XXX: include URL - stateful */
ca9947
+
ca9947
+  return 0;
ca9947
+}
ca9947
+
ca9947
+
ca9947
 /* See debuginfod.h  */
ca9947
 debuginfod_client  *
ca9947
 debuginfod_begin (void)
ca9947
@@ -693,7 +725,12 @@ debuginfod_begin (void)
ca9947
   size_t size = sizeof (struct debuginfod_client);
ca9947
   client = (debuginfod_client *) malloc (size);
ca9947
   if (client != NULL)
ca9947
-    client->progressfn = NULL;
ca9947
+    {
ca9947
+      if (getenv(DEBUGINFOD_PROGRESS_ENV_VAR))
ca9947
+	client->progressfn = default_progressfn;
ca9947
+      else
ca9947
+	client->progressfn = NULL;
ca9947
+    }
ca9947
   return client;
ca9947
 }
ca9947
 
ca9947
diff --git a/debuginfod/debuginfod.h b/debuginfod/debuginfod.h
ca9947
index 6b1b1cc..33fae86 100644
ca9947
--- a/debuginfod/debuginfod.h
ca9947
+++ b/debuginfod/debuginfod.h
ca9947
@@ -33,6 +33,7 @@
ca9947
 #define DEBUGINFOD_URLS_ENV_VAR "DEBUGINFOD_URLS"
ca9947
 #define DEBUGINFOD_CACHE_PATH_ENV_VAR "DEBUGINFOD_CACHE_PATH"
ca9947
 #define DEBUGINFOD_TIMEOUT_ENV_VAR "DEBUGINFOD_TIMEOUT"
ca9947
+#define DEBUGINFOD_PROGRESS_ENV_VAR "DEBUGINFOD_PROGRESS"
ca9947
 
ca9947
 /* Handle for debuginfod-client connection.  */
ca9947
 typedef struct debuginfod_client debuginfod_client;
ca9947
diff --git a/doc/debuginfod-find.1 b/doc/debuginfod-find.1
ca9947
index a759ecb..023acbb 100644
ca9947
--- a/doc/debuginfod-find.1
ca9947
+++ b/doc/debuginfod-find.1
ca9947
@@ -119,9 +119,13 @@ debuginfod instances.  Alternate URL prefixes are separated by space.
ca9947
 
ca9947
 .TP 21
ca9947
 .B DEBUGINFOD_TIMEOUT
ca9947
-This environment variable governs the timeout for each debuginfod HTTP
ca9947
-connection.  A server that fails to respond within this many seconds
ca9947
-is skipped.  The default is 5.
ca9947
+This environment variable governs the timeouts for each debuginfod
ca9947
+HTTP connection.  One or two comma-separated numbers may be given.
ca9947
+The first is the number of seconds for the connection establishment
ca9947
+(CURLOPT_CONNECTTIMEOUT), and the default is 5.  The second is the
ca9947
+number of seconds for the transfer completion (CURLOPT_TIMEOUT), and
ca9947
+the default is no timeout.  (Zero or negative also means "no
ca9947
+timeout".)
ca9947
 
ca9947
 .TP 21
ca9947
 .B DEBUGINFOD_CACHE_PATH
ca9947
diff --git a/doc/debuginfod_find_debuginfo.3 b/doc/debuginfod_find_debuginfo.3
ca9947
index be8eed0..ea8c616 100644
ca9947
--- a/doc/debuginfod_find_debuginfo.3
ca9947
+++ b/doc/debuginfod_find_debuginfo.3
ca9947
@@ -163,9 +163,21 @@ debuginfod instances.  Alternate URL prefixes are separated by space.
ca9947
 
ca9947
 .TP 21
ca9947
 .B DEBUGINFOD_TIMEOUT
ca9947
-This environment variable governs the timeout for each debuginfod HTTP
ca9947
-connection.  A server that fails to respond within this many seconds
ca9947
-is skipped.  The default is 5.
ca9947
+This environment variable governs the timeouts for each debuginfod
ca9947
+HTTP connection.  One or two comma-separated numbers may be given.
ca9947
+The first is the number of seconds for the connection establishment
ca9947
+(CURLOPT_CONNECTTIMEOUT), and the default is 5.  The second is the
ca9947
+number of seconds for the transfer completion (CURLOPT_TIMEOUT), and
ca9947
+the default is no timeout.  (Zero or negative also means "no
ca9947
+timeout".)
ca9947
+
ca9947
+.TP 21
ca9947
+.B DEBUGINFOD_PROGRESS
ca9947
+This environment variable governs the default progress function.  If
ca9947
+set, and if a progressfn is not explicitly set, then the library will
ca9947
+configure a default progressfn.  This function will append a simple
ca9947
+progress message periodically to the given file.  Consider using
ca9947
+"/dev/stderr" on platforms that support it.  The default is nothing.
ca9947
 
ca9947
 .TP 21
ca9947
 .B DEBUGINFOD_CACHE_PATH
ca9947
diff --git a/tests/run-debuginfod-find.sh b/tests/run-debuginfod-find.sh
ca9947
index 6533996..4cf6138 100755
ca9947
--- a/tests/run-debuginfod-find.sh
ca9947
+++ b/tests/run-debuginfod-find.sh
ca9947
@@ -89,7 +89,7 @@ wait_ready $PORT1 'ready' 1
ca9947
 export DEBUGINFOD_URLS=http://127.0.0.1:$PORT1/   # or without trailing /
ca9947
 
ca9947
 # Be patient when run on a busy machine things might take a bit.
ca9947
-export DEBUGINFOD_TIMEOUT=10
ca9947
+export DEBUGINFOD_TIMEOUT=1,10
ca9947
 
ca9947
 # We use -t0 and -g0 here to turn off time-based scanning & grooming.
ca9947
 # For testing purposes, we just sic SIGUSR1 / SIGUSR2 at the process.
ca9947
@@ -153,8 +153,11 @@ cmp $filename F/prog2
ca9947
 cat vlog
ca9947
 grep -q Progress vlog
ca9947
 tempfiles vlog
ca9947
-filename=`testrun ${abs_top_builddir}/debuginfod/debuginfod-find executable $BUILDID2`
ca9947
+filename=`testrun env DEBUGINFOD_PROGRESS=1 ${abs_top_builddir}/debuginfod/debuginfod-find executable $BUILDID2 2>vlog2`
ca9947
 cmp $filename F/prog2
ca9947
+cat vlog2
ca9947
+grep -q Downloading vlog2
ca9947
+tempfiles vlog2
ca9947
 filename=`testrun ${abs_top_builddir}/debuginfod/debuginfod-find source $BUILDID2 ${PWD}/prog2.c`
ca9947
 cmp $filename ${PWD}/prog2.c
ca9947
 
ca9947
ca9947
commit 288c76775f2d27976eb269e568b53c742d973dbc
ca9947
Author: Frank Ch. Eigler <fche@redhat.com>
ca9947
Date:   Mon Jan 6 04:29:21 2020 -0500
ca9947
ca9947
    debuginfod: pass a distro-summary User-Agent request header
ca9947
    
ca9947
    It may be useful for a debuginfod server operator to know what kinds
ca9947
    of clients make webapi requests.  This is mainly as a
ca9947
    telemetry/diagnostic (though the data cannot be really trusted).  It
ca9947
    may also be useful to automate downloading of distro packages to a
ca9947
    debuginfod server in the case of an unknown hex buildid.  doc/testing
ca9947
    not affected as these are diagnostics.
ca9947
    
ca9947
    Signed-off-by: Frank Ch. Eigler <fche@redhat.com>
ca9947
    Signed-off-by: Mark Wielaard <mjw@redhat.com>
ca9947
ca9947
diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c
ca9947
index 9a4a0e0..66ccb21 100644
ca9947
--- a/debuginfod/debuginfod-client.c
ca9947
+++ b/debuginfod/debuginfod-client.c
ca9947
@@ -1,5 +1,5 @@
ca9947
 /* Retrieve ELF / DWARF / source files from the debuginfod.
ca9947
-   Copyright (C) 2019 Red Hat, Inc.
ca9947
+   Copyright (C) 2019-2020 Red Hat, Inc.
ca9947
    This file is part of elfutils.
ca9947
 
ca9947
    This file is free software; you can redistribute it and/or modify
ca9947
@@ -58,6 +58,7 @@
ca9947
 #include <sys/syscall.h>
ca9947
 #include <sys/types.h>
ca9947
 #include <sys/stat.h>
ca9947
+#include <sys/utsname.h>
ca9947
 #include <curl/curl.h>
ca9947
 
ca9947
 /* If fts.h is included before config.h, its indirect inclusions may not
ca9947
@@ -279,6 +280,87 @@ debuginfod_clean_cache(debuginfod_client *c,
ca9947
 #define MAX_BUILD_ID_BYTES 64
ca9947
 
ca9947
 
ca9947
+static void
ca9947
+add_extra_headers(CURL *handle)
ca9947
+{
ca9947
+  /* Compute a User-Agent: string to send.  The more accurately this
ca9947
+     describes this host, the likelier that the debuginfod servers
ca9947
+     might be able to locate debuginfo for us. */
ca9947
+
ca9947
+  char* utspart = NULL;
ca9947
+  struct utsname uts;
ca9947
+  int rc = 0;
ca9947
+  rc = uname (&uts;;
ca9947
+  if (rc == 0)
ca9947
+    rc = asprintf(& utspart, "%s/%s", uts.sysname, uts.machine);
ca9947
+  if (rc < 0)
ca9947
+    utspart = NULL;
ca9947
+
ca9947
+  FILE *f = fopen ("/etc/os-release", "r");
ca9947
+  if (f == NULL)
ca9947
+    f = fopen ("/usr/lib/os-release", "r");
ca9947
+  char *id = NULL;
ca9947
+  char *version = NULL;
ca9947
+  if (f != NULL)
ca9947
+    {
ca9947
+      while (id == NULL || version == NULL)
ca9947
+        {
ca9947
+          char buf[128];
ca9947
+          char *s = &buf[0];
ca9947
+          if (fgets (s, sizeof(buf), f) == NULL)
ca9947
+            break;
ca9947
+
ca9947
+          int len = strlen (s);
ca9947
+          if (len < 3)
ca9947
+            continue;
ca9947
+          if (s[len - 1] == '\n')
ca9947
+            {
ca9947
+              s[len - 1] = '\0';
ca9947
+              len--;
ca9947
+            }
ca9947
+
ca9947
+          char *v = strchr (s, '=');
ca9947
+          if (v == NULL || strlen (v) < 2)
ca9947
+            continue;
ca9947
+
ca9947
+          /* Split var and value. */
ca9947
+          *v = '\0';
ca9947
+          v++;
ca9947
+
ca9947
+          /* Remove optional quotes around value string. */
ca9947
+          if (*v == '"' || *v == '\'')
ca9947
+            {
ca9947
+              v++;
ca9947
+              s[len - 1] = '\0';
ca9947
+            }
ca9947
+          if (strcmp (s, "ID") == 0)
ca9947
+            id = strdup (v);
ca9947
+          if (strcmp (s, "VERSION_ID") == 0)
ca9947
+            version = strdup (v);
ca9947
+        }
ca9947
+      fclose (f);
ca9947
+    }
ca9947
+
ca9947
+  char *ua = NULL;
ca9947
+  rc = asprintf(& ua, "%s/%s,%s,%s/%s",
ca9947
+                PACKAGE_NAME, PACKAGE_VERSION,
ca9947
+                utspart ?: "",
ca9947
+                id ?: "",
ca9947
+                version ?: "");
ca9947
+  if (rc < 0)
ca9947
+    ua = NULL;
ca9947
+
ca9947
+  if (ua)
ca9947
+    curl_easy_setopt(handle, CURLOPT_USERAGENT, (void*) ua); /* implicit strdup */
ca9947
+
ca9947
+  free (ua);
ca9947
+  free (id);
ca9947
+  free (version);
ca9947
+  free (utspart);
ca9947
+}
ca9947
+
ca9947
+
ca9947
+
ca9947
 /* Query each of the server URLs found in $DEBUGINFOD_URLS for the file
ca9947
    with the specified build-id, type (debuginfo, executable or source)
ca9947
    and filename. filename may be NULL. If found, return a file
ca9947
@@ -514,7 +596,7 @@ debuginfod_query_server (debuginfod_client *c,
ca9947
       curl_easy_setopt(data[i].handle, CURLOPT_NOSIGNAL, (long) 1);
ca9947
       curl_easy_setopt(data[i].handle, CURLOPT_AUTOREFERER, (long) 1);
ca9947
       curl_easy_setopt(data[i].handle, CURLOPT_ACCEPT_ENCODING, "");
ca9947
-      curl_easy_setopt(data[i].handle, CURLOPT_USERAGENT, (void*) PACKAGE_STRING);
ca9947
+      add_extra_headers(data[i].handle);
ca9947
 
ca9947
       curl_multi_add_handle(curlm, data[i].handle);
ca9947
       server_url = strtok_r(NULL, url_delim, &strtok_saveptr);
ca9947
ca9947
commit b8d85ed024a745cff05e56c6337d95d654d5294a
ca9947
Author: Mark Wielaard <mark@klomp.org>
ca9947
Date:   Thu Jan 2 17:02:42 2020 +0100
ca9947
ca9947
    debuginfod: Use DEBUGINFOD_TIMEOUT as seconds to get at least 100K.
ca9947
    
ca9947
    Use just one timeout using CURLOPT_LOW_SPEED_TIME (default 90 seconds)
ca9947
    and CURLOPT_LOW_SPEED_LIMIT (100K).
ca9947
    
ca9947
    Signed-off-by: Mark Wielaard <mark@klomp.org>
ca9947
ca9947
diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c
ca9947
index 66ccb21..e5a2e82 100644
ca9947
--- a/debuginfod/debuginfod-client.c
ca9947
+++ b/debuginfod/debuginfod-client.c
ca9947
@@ -105,10 +105,9 @@ static const char *server_urls_envvar = DEBUGINFOD_URLS_ENV_VAR;
ca9947
 static const char *url_delim =  " ";
ca9947
 static const char url_delim_char = ' ';
ca9947
 
ca9947
-/* Timeout for debuginfods, in seconds. */
ca9947
+/* Timeout for debuginfods, in seconds (to get at least 100K). */
ca9947
 static const char *server_timeout_envvar = DEBUGINFOD_TIMEOUT_ENV_VAR;
ca9947
-static const long default_connect_timeout = 5;
ca9947
-static const long default_transfer_timeout = -1; /* unlimited */
ca9947
+static const long default_timeout = 90;
ca9947
 
ca9947
 
ca9947
 /* Data associated with a particular CURL easy handle. Passed to
ca9947
@@ -483,18 +482,10 @@ debuginfod_query_server (debuginfod_client *c,
ca9947
       return fd;
ca9947
     }
ca9947
 
ca9947
-  long connect_timeout = default_connect_timeout;
ca9947
-  long transfer_timeout = default_transfer_timeout;
ca9947
+  long timeout = default_timeout;
ca9947
   const char* timeout_envvar = getenv(server_timeout_envvar);
ca9947
   if (timeout_envvar != NULL)
ca9947
-    {
ca9947
-      long ct, tt;
ca9947
-      rc = sscanf(timeout_envvar, "%ld,%ld", &ct, &tt;;
ca9947
-      if (rc >= 1)
ca9947
-        connect_timeout = ct;
ca9947
-      if (rc >= 2)
ca9947
-        transfer_timeout = tt;
ca9947
-    }
ca9947
+    timeout = atoi (timeout_envvar);
ca9947
 
ca9947
   /* make a copy of the envvar so it can be safely modified.  */
ca9947
   server_urls = strdup(urls_envvar);
ca9947
@@ -586,10 +577,15 @@ debuginfod_query_server (debuginfod_client *c,
ca9947
                        CURLOPT_WRITEFUNCTION,
ca9947
                        debuginfod_write_callback);
ca9947
       curl_easy_setopt(data[i].handle, CURLOPT_WRITEDATA, (void*)&data[i]);
ca9947
-      if (connect_timeout >= 0)
ca9947
-        curl_easy_setopt(data[i].handle, CURLOPT_CONNECTTIMEOUT, connect_timeout);
ca9947
-      if (transfer_timeout >= 0)
ca9947
-        curl_easy_setopt(data[i].handle, CURLOPT_TIMEOUT, transfer_timeout);
ca9947
+      if (timeout > 0)
ca9947
+	{
ca9947
+	  /* Make sure there is at least some progress,
ca9947
+	     try to get at least 100K per timeout seconds.  */
ca9947
+	  curl_easy_setopt (data[i].handle, CURLOPT_LOW_SPEED_TIME,
ca9947
+			    timeout);
ca9947
+	  curl_easy_setopt (data[i].handle, CURLOPT_LOW_SPEED_LIMIT,
ca9947
+			    100 * 1024L);
ca9947
+	}
ca9947
       curl_easy_setopt(data[i].handle, CURLOPT_FILETIME, (long) 1);
ca9947
       curl_easy_setopt(data[i].handle, CURLOPT_FOLLOWLOCATION, (long) 1);
ca9947
       curl_easy_setopt(data[i].handle, CURLOPT_FAILONERROR, (long) 1);
ca9947
diff --git a/doc/debuginfod-find.1 b/doc/debuginfod-find.1
ca9947
index 023acbb..e71ca29 100644
ca9947
--- a/doc/debuginfod-find.1
ca9947
+++ b/doc/debuginfod-find.1
ca9947
@@ -119,13 +119,10 @@ debuginfod instances.  Alternate URL prefixes are separated by space.
ca9947
 
ca9947
 .TP 21
ca9947
 .B DEBUGINFOD_TIMEOUT
ca9947
-This environment variable governs the timeouts for each debuginfod
ca9947
-HTTP connection.  One or two comma-separated numbers may be given.
ca9947
-The first is the number of seconds for the connection establishment
ca9947
-(CURLOPT_CONNECTTIMEOUT), and the default is 5.  The second is the
ca9947
-number of seconds for the transfer completion (CURLOPT_TIMEOUT), and
ca9947
-the default is no timeout.  (Zero or negative also means "no
ca9947
-timeout".)
ca9947
+This environment variable governs the timeout for each debuginfod HTTP
ca9947
+connection.  A server that fails to provide at least 100K of data
ca9947
+within this many seconds is skipped. The default is 90 seconds.  (Zero
ca9947
+or negative means "no timeout".)
ca9947
 
ca9947
 .TP 21
ca9947
 .B DEBUGINFOD_CACHE_PATH
ca9947
diff --git a/doc/debuginfod.8 b/doc/debuginfod.8
ca9947
index 342f524..6184bcc 100644
ca9947
--- a/doc/debuginfod.8
ca9947
+++ b/doc/debuginfod.8
ca9947
@@ -366,8 +366,10 @@ or indirectly - the results would be hilarious.
ca9947
 .TP 21
ca9947
 .B DEBUGINFOD_TIMEOUT
ca9947
 This environment variable governs the timeout for each debuginfod HTTP
ca9947
-connection.  A server that fails to respond within this many seconds
ca9947
-is skipped.  The default is 5.
ca9947
+connection.  A server that fails to provide at least 100K of data
ca9947
+within this many seconds is skipped. The default is 90 seconds.  (Zero
ca9947
+or negative means "no timeout".)
ca9947
+
ca9947
 
ca9947
 .TP 21
ca9947
 .B DEBUGINFOD_CACHE_PATH
ca9947
diff --git a/doc/debuginfod_find_debuginfo.3 b/doc/debuginfod_find_debuginfo.3
ca9947
index ea8c616..f6ea7a4 100644
ca9947
--- a/doc/debuginfod_find_debuginfo.3
ca9947
+++ b/doc/debuginfod_find_debuginfo.3
ca9947
@@ -163,13 +163,10 @@ debuginfod instances.  Alternate URL prefixes are separated by space.
ca9947
 
ca9947
 .TP 21
ca9947
 .B DEBUGINFOD_TIMEOUT
ca9947
-This environment variable governs the timeouts for each debuginfod
ca9947
-HTTP connection.  One or two comma-separated numbers may be given.
ca9947
-The first is the number of seconds for the connection establishment
ca9947
-(CURLOPT_CONNECTTIMEOUT), and the default is 5.  The second is the
ca9947
-number of seconds for the transfer completion (CURLOPT_TIMEOUT), and
ca9947
-the default is no timeout.  (Zero or negative also means "no
ca9947
-timeout".)
ca9947
+This environment variable governs the timeout for each debuginfod HTTP
ca9947
+connection.  A server that fails to provide at least 100K of data
ca9947
+within this many seconds is skipped. The default is 90 seconds.  (Zero
ca9947
+or negative means "no timeout".)
ca9947
 
ca9947
 .TP 21
ca9947
 .B DEBUGINFOD_PROGRESS
ca9947
diff --git a/tests/run-debuginfod-find.sh b/tests/run-debuginfod-find.sh
ca9947
index 90dafe0..4ab47a3 100755
ca9947
--- a/tests/run-debuginfod-find.sh
ca9947
+++ b/tests/run-debuginfod-find.sh
ca9947
@@ -94,7 +94,7 @@ wait_ready $PORT1 'ready' 1
ca9947
 export DEBUGINFOD_URLS=http://127.0.0.1:$PORT1/   # or without trailing /
ca9947
 
ca9947
 # Be patient when run on a busy machine things might take a bit.
ca9947
-export DEBUGINFOD_TIMEOUT=1,10
ca9947
+export DEBUGINFOD_TIMEOUT=10
ca9947
 
ca9947
 # We use -t0 and -g0 here to turn off time-based scanning & grooming.
ca9947
 # For testing purposes, we just sic SIGUSR1 / SIGUSR2 at the process.
ca9947
ca9947
commit 6f2098114a1acbd5e320a1c5fabfa07df02b14fd
ca9947
Author: Mark Wielaard <mark@klomp.org>
ca9947
Date:   Fri Jan 10 15:46:29 2020 +0100
ca9947
ca9947
    doc: Fix DEBUGINFOD_PROGRESS description to just mention output on stderr.
ca9947
    
ca9947
    An earlier variant of the default progress function could write to any
ca9947
    file. Which is still in the documentation. But the actual implementation
ca9947
    just uses stderr. Fix the documentation to match.
ca9947
    
ca9947
    Signed-off-by: Mark Wielaard <mark@klomp.org>
ca9947
ca9947
diff --git a/doc/debuginfod_find_debuginfo.3 b/doc/debuginfod_find_debuginfo.3
ca9947
index f6ea7a4..7e5060f 100644
ca9947
--- a/doc/debuginfod_find_debuginfo.3
ca9947
+++ b/doc/debuginfod_find_debuginfo.3
ca9947
@@ -173,8 +173,8 @@ or negative means "no timeout".)
ca9947
 This environment variable governs the default progress function.  If
ca9947
 set, and if a progressfn is not explicitly set, then the library will
ca9947
 configure a default progressfn.  This function will append a simple
ca9947
-progress message periodically to the given file.  Consider using
ca9947
-"/dev/stderr" on platforms that support it.  The default is nothing.
ca9947
+progress message periodically to stderr.  The default is no progress
ca9947
+function output.
ca9947
 
ca9947
 .TP 21
ca9947
 .B DEBUGINFOD_CACHE_PATH