[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.
- [gnurl] 39/151: docs: fix typos, (continued)
- [gnurl] 39/151: docs: fix typos, gnunet, 2019/12/20
- [gnurl] 30/151: INSTALL.md: provide Android build instructions, gnunet, 2019/12/20
- [gnurl] 43/151: test1175: verify symbols-in-versions and libcurl-errors.3 in sync, gnunet, 2019/12/20
- [gnurl] 41/151: bump: next release will be 7.68.0, gnunet, 2019/12/20
- [gnurl] 35/151: altsvc: bump to h3-24, gnunet, 2019/12/20
- [gnurl] 36/151: ngtcp2: use overflow buffer for extra HTTP/3 data, gnunet, 2019/12/20
- [gnurl] 31/151: lib: Move lib/ssh.h -> lib/vssh/ssh.h, gnunet, 2019/12/20
- [gnurl] 46/151: RELEASE-NOTES: synced, gnunet, 2019/12/20
- [gnurl] 49/151: schannel: fix --tls-max for when min is --tlsv1 or default, gnunet, 2019/12/20
- [gnurl] 65/151: http_ntlm: Remove duplicate NSS initialisation, gnunet, 2019/12/20
- [gnurl] 54/151: curl: fix --upload-file . hangs if delay in STDIN,
gnunet <=
- [gnurl] 47/151: projects: Fix Visual Studio projects SSH builds, gnunet, 2019/12/20
- [gnurl] 56/151: travis: export the CC/CXX variables when set, gnunet, 2019/12/20
- [gnurl] 57/151: ngtcp2: fix thread-safety bug in error-handling, gnunet, 2019/12/20
- [gnurl] 60/151: mailmap: Niall O'Reilly's name, gnunet, 2019/12/20
- [gnurl] 61/151: docs: fix typos, gnunet, 2019/12/20
- [gnurl] 38/151: projects: Fix Visual Studio wolfSSL configurations, gnunet, 2019/12/20
- [gnurl] 53/151: XFERINFOFUNCTION: support CURL_PROGRESSFUNC_CONTINUE, gnunet, 2019/12/20
- [gnurl] 66/151: curl_setup_once: consistently use WHILE_FALSE in macros, gnunet, 2019/12/20
- [gnurl] 48/151: checksrc.bat: Add a check for vquic and vssh directories, gnunet, 2019/12/20
- [gnurl] 64/151: checksrc: fix regexp for ASSIGNWITHINCONDITION, gnunet, 2019/12/20