From: Stefan Eissing Date: Mon, 19 Jun 2023 10:11:53 +0000 (+0200) Subject: hyper: unslow X-Git-Tag: curl-8_2_0~65 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=81e6793ec96aadd780187684c0cb66aa929b4a9f;p=thirdparty%2Fcurl.git hyper: unslow - refs #11203 where hyper was reported as being slow - fixes hyper_executor_poll to loop until it is out of tasks as advised by @seanmonstar in https://github.com/hyperium/hyper/issues/3237 - added a fix in hyper io handling for detecting EAGAIN - added some debug logs to see IO results - pytest http/1.1 test cases pass - pytest h2 test cases fail on connection reuse. HTTP/2 connection reuse does not seem to work. Hyper submits a request on a reused connection, curl's IO works and thereafter hyper declares `Hyper: [1] operation was canceled: connection closed` on stderr without any error being logged before. Fixes #11203 Reported-by: Gisle Vanem Advised-by: Sean McArthur Closes #11344 --- diff --git a/lib/c-hyper.c b/lib/c-hyper.c index 756aebee21..52e07797c5 100644 --- a/lib/c-hyper.c +++ b/lib/c-hyper.c @@ -71,9 +71,13 @@ size_t Curl_hyper_recv(void *userp, hyper_context *ctx, DEBUGASSERT(conn); (void)ctx; + DEBUGF(infof(data, "Curl_hyper_recv(%zu)", buflen)); result = Curl_read(data, conn->sockfd, (char *)buf, buflen, &nread); + if(!result && !nread) + result = CURLE_AGAIN; if(result == CURLE_AGAIN) { /* would block, register interest */ + DEBUGF(infof(data, "Curl_hyper_recv(%zu) -> EAGAIN", buflen)); if(data->hyp.read_waker) hyper_waker_free(data->hyp.read_waker); data->hyp.read_waker = hyper_context_waker(ctx); @@ -87,6 +91,7 @@ size_t Curl_hyper_recv(void *userp, hyper_context *ctx, failf(data, "Curl_read failed"); return HYPER_IO_ERROR; } + DEBUGF(infof(data, "Curl_hyper_recv(%zu) -> %zd", buflen, nread)); return (size_t)nread; } @@ -98,8 +103,12 @@ size_t Curl_hyper_send(void *userp, hyper_context *ctx, CURLcode result; ssize_t nwrote; + DEBUGF(infof(data, "Curl_hyper_send(%zu)", buflen)); result = Curl_write(data, conn->sockfd, (void *)buf, buflen, &nwrote); + if(!result && !nwrote) + result = CURLE_AGAIN; if(result == CURLE_AGAIN) { + DEBUGF(infof(data, "Curl_hyper_send(%zu) -> EAGAIN", buflen)); /* would block, register interest */ if(data->hyp.write_waker) hyper_waker_free(data->hyp.write_waker); @@ -114,6 +123,7 @@ size_t Curl_hyper_send(void *userp, hyper_context *ctx, failf(data, "Curl_write failed"); return HYPER_IO_ERROR; } + DEBUGF(infof(data, "Curl_hyper_send(%zu) -> %zd", buflen, nwrote)); return (size_t)nwrote; } @@ -433,8 +443,7 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data, break; } else if(t != HYPER_TASK_RESPONSE) { - *didwhat = KEEP_RECV; - break; + continue; } /* HYPER_TASK_RESPONSE */ diff --git a/tests/http/testenv/curl.py b/tests/http/testenv/curl.py index e6da553c66..cabf1c560d 100644 --- a/tests/http/testenv/curl.py +++ b/tests/http/testenv/curl.py @@ -491,7 +491,7 @@ class CurlClient: elif self.env.verbose > 1: args.extend(['--trace', self._tracefile]) elif not self._silent: - args.extend(['-v']) + args.extend(['-v', '--trace-time', '--trace-ids']) for url in urls: u = urlparse(urls[0])