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

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