twister

HTTP fault injector for testing
Log | Files | Refs | README | LICENSE

commit 9ad1ebf8f6b126fdef9a0753305b77f30ebbfa3f
parent c27ec06b744f57189e4247410da09257b403ebbc
Author: Christian Grothoff <christian@grothoff.org>
Date:   Thu, 20 Sep 2018 20:09:45 +0200

#5337 in proxy: if Web server returns response during upload, curl aborts upload so our proxy should give up on the upload as well and just proceed with the download

Diffstat:
Msrc/twister/taler-twister-service.c | 57+++++++++++++++++++++++++++++++++++----------------------
1 file changed, 35 insertions(+), 22 deletions(-)

diff --git a/src/twister/taler-twister-service.c b/src/twister/taler-twister-service.c @@ -46,7 +46,7 @@ * easily identify what might fix the issue (until CG can actually * reproduce it nicely). */ -#define MARCELLO_FIX 1 +#define MARCELLO_FIX 0 /** * Log curl error. @@ -522,7 +522,7 @@ static size_t curl_download_cb (void *ptr, size_t size, size_t nmemb, - void* ctx) + void *ctx) { struct HttpRequest *hr = ctx; size_t total = size * nmemb; @@ -533,16 +533,22 @@ curl_download_cb (void *ptr, if ( (REQUEST_STATE_UPLOAD_STARTED == hr->state) || (REQUEST_STATE_UPLOAD_DONE == hr->state) ) { - /* we're still not done with the upload, do not yet - start the download, the IO buffer is still full - with upload data. */ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Pausing CURL download, waiting for UPLOAD to finish\n"); - hr->curl_paused = GNUNET_YES; - return CURL_WRITEFUNC_PAUSE; /* not yet ready for data download */ + /* Web server started with response before we finished + the upload. In this case, current libcurl decides + to NOT complete the upload, so we should jump in the + state machine to process the download, dropping the + rest of the upload. This should only really happen + with uploads without "Expect: 100 Continue" and + Web servers responding with an error (i.e. upload + not allowed) */ + hr->state = REQUEST_STATE_DOWNLOAD_STARTED; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Stopping %u byte upload: we are already downloading...\n", + (unsigned int) hr->io_len); + hr->io_len = 0; } - if (REQUEST_STATE_DOWNLOAD_STARTED != hr->state) + if (REQUEST_STATE_DOWNLOAD_STARTED != hr->state) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download callback goes to sleep\n"); @@ -571,6 +577,13 @@ curl_download_cb (void *ptr, /** + * Ask cURL for the select() sets and schedule cURL operations. + */ +static void +curl_download_prepare (void); + + +/** * cURL callback for uploaded (PUT/POST) data. * Copies from our `io_buf` to make it available to cURL. * @@ -592,7 +605,13 @@ curl_upload_cb (void *buf, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Upload cb is working...\n"); - + if ( (REQUEST_STATE_UPLOAD_STARTED != hr->state) && + (REQUEST_STATE_UPLOAD_DONE != hr->state) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Upload cb aborts: we are already downloading...\n"); + return CURL_READFUNC_ABORT; + } if ( (0 == hr->io_len) && (REQUEST_STATE_UPLOAD_DONE != hr->state) ) { @@ -610,16 +629,11 @@ curl_upload_cb (void *buf, curl_easy_pause (hr->curl, CURLPAUSE_CONT); } + curl_download_prepare (); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Completed CURL UPLOAD\n"); return 0; /* upload finished, can now download */ } - if ( (REQUEST_STATE_UPLOAD_STARTED != hr->state) && - (REQUEST_STATE_UPLOAD_DONE != hr->state) ) - { - GNUNET_break (0); - return CURL_READFUNC_ABORT; - } to_copy = GNUNET_MIN (hr->io_len, len); GNUNET_memcpy (buf, @@ -729,6 +743,7 @@ curl_download_prepare () } } + /** * Task that is run when we are ready to receive * more data from curl. @@ -865,6 +880,7 @@ curl_progress_cb (void *clientp, curl_easy_pause (hr->curl, CURLPAUSE_CONT); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Unpausing the download callback\n"); + curl_download_prepare (); } #endif return CURLE_OK; @@ -1362,10 +1378,9 @@ create_response (void *cls, flip_object (con, hr->json, flip_path_ul); - + /* Existing io_len is enough to accomodate this encoding. */ json_dumpb (hr->json, hr->io_buf, -/* Existing io_len is enough to accomodate this encoding. */ hr->io_len, JSON_COMPACT); @@ -1387,10 +1402,9 @@ create_response (void *cls, modify_object (con, hr->json, modify_path_ul); - + /* Existing io_len is enough to accomodate this encoding. */ json_dumpb (hr->json, hr->io_buf, -/* Existing io_len is enough to accomodate this encoding. */ hr->io_len, JSON_COMPACT); @@ -1632,7 +1646,6 @@ create_response (void *cls, curl_easy_setopt (hr->curl, CURLOPT_HTTPHEADER, hr->headers); - curl_download_prepare (); /* means (?) upload is over. */