gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnurl] 54/151: curl: fix --upload-file . hangs if delay in STDIN


From: gnunet
Subject: [gnurl] 54/151: curl: fix --upload-file . hangs if delay in STDIN
Date: Fri, 20 Dec 2019 14:26:03 +0100

This is an automated email from the git hooks/post-receive script.

ng0 pushed a commit to branch master
in repository gnurl.

commit 9a2cbf30b81a2b57149bb20e78e2e4cb5c2ff389
Author: John Schroeder <address@hidden>
AuthorDate: Tue Nov 26 09:16:19 2019 +0100

    curl: fix --upload-file . hangs if delay in STDIN
    
    Attempt to unpause a busy read in the CURLOPT_XFERINFOFUNCTION.
    
    When uploading from stdin in non-blocking mode, a delay in reading
    the stream (EAGAIN) causes curl to pause sending data
    (CURL_READFUNC_PAUSE).  Prior to this change, a busy read was
    detected and unpaused only in the CURLOPT_WRITEFUNCTION handler.
    This change performs the same busy read handling in a
    CURLOPT_XFERINFOFUNCTION handler.
    
    Fixes #2051
    Closes #4599
    Reported-by: bdry on github
---
 src/tool_cb_prg.c   | 11 ++++++++++-
 src/tool_cb_rea.c   | 26 ++++++++++++++++++++++++++
 src/tool_cb_rea.h   |  8 ++++++++
 src/tool_operate.c  | 13 ++++++++++---
 src/tool_operate.h  |  1 +
 src/tool_progress.c |  8 ++++++++
 6 files changed, 63 insertions(+), 4 deletions(-)

diff --git a/src/tool_cb_prg.c b/src/tool_cb_prg.c
index a18827c8b..505ae751f 100644
--- a/src/tool_cb_prg.c
+++ b/src/tool_cb_prg.c
@@ -32,6 +32,7 @@
 #include "tool_cfgable.h"
 #include "tool_cb_prg.h"
 #include "tool_util.h"
+#include "tool_operate.h"
 
 #include "memdebug.h" /* keep this as LAST include */
 
@@ -121,7 +122,10 @@ int tool_progress_cb(void *clientp,
      and this new edition inherits some of his concepts. */
 
   struct timeval now = tvnow();
-  struct ProgressData *bar = (struct ProgressData *)clientp;
+  struct per_transfer *per = clientp;
+  struct OutStruct *outs = &per->outs;
+  struct OperationConfig *config = outs->config;
+  struct ProgressData *bar = &per->progressbar;
   curl_off_t total;
   curl_off_t point;
 
@@ -191,6 +195,11 @@ int tool_progress_cb(void *clientp,
   bar->prev = point;
   bar->prevtime = now;
 
+  if(config->readbusy) {
+    config->readbusy = FALSE;
+    curl_easy_pause(per->curl, CURLPAUSE_CONT);
+  }
+
   return 0;
 }
 
diff --git a/src/tool_cb_rea.c b/src/tool_cb_rea.c
index 06f60eca7..03ed4a467 100644
--- a/src/tool_cb_rea.c
+++ b/src/tool_cb_rea.c
@@ -27,6 +27,7 @@
 
 #include "tool_cfgable.h"
 #include "tool_cb_rea.h"
+#include "tool_operate.h"
 
 #include "memdebug.h" /* keep this as LAST include */
 
@@ -52,3 +53,28 @@ size_t tool_read_cb(void *buffer, size_t sz, size_t nmemb, 
void *userdata)
   in->config->readbusy = FALSE;
   return (size_t)rc;
 }
+
+/*
+** callback for CURLOPT_XFERINFOFUNCTION used to unpause busy reads
+*/
+
+int tool_readbusy_cb(void *clientp,
+                     curl_off_t dltotal, curl_off_t dlnow,
+                     curl_off_t ultotal, curl_off_t ulnow)
+{
+  struct per_transfer *per = clientp;
+  struct OutStruct *outs = &per->outs;
+  struct OperationConfig *config = outs->config;
+
+  (void)dltotal;  /* unused */
+  (void)dlnow;  /* unused */
+  (void)ultotal;  /* unused */
+  (void)ulnow;  /* unused */
+
+  if(config->readbusy) {
+    config->readbusy = FALSE;
+    curl_easy_pause(per->curl, CURLPAUSE_CONT);
+  }
+
+  return per->noprogress? 0 : CURL_PROGRESSFUNC_CONTINUE;
+}
diff --git a/src/tool_cb_rea.h b/src/tool_cb_rea.h
index fe744e8f7..5f7e483a3 100644
--- a/src/tool_cb_rea.h
+++ b/src/tool_cb_rea.h
@@ -29,4 +29,12 @@
 
 size_t tool_read_cb(void *buffer, size_t sz, size_t nmemb, void *userdata);
 
+/*
+** callback for CURLOPT_XFERINFOFUNCTION used to unpause busy reads
+*/
+
+int tool_readbusy_cb(void *clientp,
+                     curl_off_t dltotal, curl_off_t dlnow,
+                     curl_off_t ultotal, curl_off_t ulnow);
+
 #endif /* HEADER_CURL_TOOL_CB_REA_H */
diff --git a/src/tool_operate.c b/src/tool_operate.c
index 0de81cd49..4b2ffb55b 100644
--- a/src/tool_operate.c
+++ b/src/tool_operate.c
@@ -1080,11 +1080,11 @@ static CURLcode single_transfer(struct GlobalConfig 
*global,
            isatty(fileno(outs->stream)))
           /* we send the output to a tty, therefore we switch off the progress
              meter */
-          global->noprogress = global->isatty = TRUE;
+          per->noprogress = global->noprogress = global->isatty = TRUE;
         else {
           /* progress meter is per download, so restore config
              values */
-          global->noprogress = orig_noprogress;
+          per->noprogress = global->noprogress = orig_noprogress;
           global->isatty = orig_isatty;
         }
 
@@ -1573,7 +1573,14 @@ static CURLcode single_transfer(struct GlobalConfig 
*global,
           /* we want the alternative style, then we have to implement it
              ourselves! */
           my_setopt(curl, CURLOPT_XFERINFOFUNCTION, tool_progress_cb);
-          my_setopt(curl, CURLOPT_XFERINFODATA, &per->progressbar);
+          my_setopt(curl, CURLOPT_XFERINFODATA, per);
+        }
+        else if(per->uploadfile && !strcmp(per->uploadfile, ".")) {
+          /* when reading from stdin in non-blocking mode, we use the progress
+             function to unpause a busy read */
+          my_setopt(curl, CURLOPT_NOPROGRESS, 0L);
+          my_setopt(curl, CURLOPT_XFERINFOFUNCTION, tool_readbusy_cb);
+          my_setopt(curl, CURLOPT_XFERINFODATA, per);
         }
 
         /* new in libcurl 7.24.0: */
diff --git a/src/tool_operate.h b/src/tool_operate.h
index 60257fc60..7223db767 100644
--- a/src/tool_operate.h
+++ b/src/tool_operate.h
@@ -44,6 +44,7 @@ struct per_transfer {
   char *outfile;
   bool infdopen; /* TRUE if infd needs closing */
   int infd;
+  bool noprogress;
   struct ProgressData progressbar;
   struct OutStruct outs;
   struct OutStruct heads;
diff --git a/src/tool_progress.c b/src/tool_progress.c
index a2667f38e..ac4f58f41 100644
--- a/src/tool_progress.c
+++ b/src/tool_progress.c
@@ -95,10 +95,18 @@ int xferinfo_cb(void *clientp,
                 curl_off_t ulnow)
 {
   struct per_transfer *per = clientp;
+  struct OutStruct *outs = &per->outs;
+  struct OperationConfig *config = outs->config;
   per->dltotal = dltotal;
   per->dlnow = dlnow;
   per->ultotal = ultotal;
   per->ulnow = ulnow;
+
+  if(config->readbusy) {
+    config->readbusy = FALSE;
+    curl_easy_pause(per->curl, CURLPAUSE_CONT);
+  }
+
   return 0;
 }
 

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]