-
-
Notifications
You must be signed in to change notification settings - Fork 6.7k
libcurl: unpausing is broken for http2 requests in 7.84 #9180
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
What is the output when you run that test code? When I run with curl from git (debug-enabled) using nghttp2 1.47.0 on Linux, it shows:
|
I think that it could be because request resumes without being paused in callback.
You could run example few times, or change wait timeout (set max poll counter to 20: if (poll_counter == 20)). In my case (nghttp2 1.47 also, system is linux/macos) output is:
more stable example would be: #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/time.h>
#include <unistd.h>
#include <curl/curl.h>
#include <assert.h>
struct transfer {
CURL *easy;
int paused;
int header_callback_called;
int writed_data;
int writed_headers;
};
size_t write_header(void *ptr, size_t size, size_t nmemb, void *userdata)
{
struct transfer* tr;
tr = (struct transfer*)(userdata);
tr->header_callback_called = 1;
if (tr->paused)
{
fprintf(stderr, ">> write_header %li paused \n", nmemb);
return CURL_WRITEFUNC_PAUSE;
}
fprintf(stderr, ">> write_header %li resumed \n", nmemb);
tr->writed_headers += size * nmemb;
return size * nmemb;
}
size_t write_data(void *ptr, size_t size, size_t nmemb, void* userdata)
{
struct transfer* tr;
tr = (struct transfer*)(userdata);
if (tr->paused)
{
fprintf(stderr, ">> write_data %li paused \n", nmemb);
return CURL_WRITEFUNC_PAUSE;
}
fprintf(stderr, ">> write_data %li resumed! \n", nmemb);
tr->writed_data += size * nmemb;
return size * nmemb;
}
static void setup(struct transfer *t)
{
CURL *hnd;
hnd = t->easy = curl_easy_init();
t->paused = 1;
t->writed_data = 0;
t->writed_headers = 0;
t->header_callback_called = 0;
curl_easy_setopt(hnd, CURLOPT_HEADERFUNCTION, &write_header);
curl_easy_setopt(hnd, CURLOPT_WRITEHEADER, t);
curl_easy_setopt(hnd, CURLOPT_WRITEFUNCTION, &write_data);
curl_easy_setopt(hnd, CURLOPT_WRITEDATA, t);
curl_easy_setopt(hnd, CURLOPT_URL, "https://www.nghttp2.org/");
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
/* HTTP/2 please */
curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
/* skip verification during debugging */
curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYHOST, 0L);
}
static void resume(struct transfer *t)
{
CURL *hnd;
int resResume;
hnd = t->easy;
t->paused = 0;
resResume = curl_easy_pause(hnd, 0L);
fprintf(stderr, "curl_easy_pause result %i\n", resResume);
}
int main(int argc, char **argv)
{
struct transfer trans;
CURLM *multi_handle;
int still_running = 0; /* keep number of running handles */
int poll_counter = 0;
/* init a multi stack */
multi_handle = curl_multi_init();
setup(&trans);
/* add the individual transfer */
curl_multi_add_handle(multi_handle, trans.easy);
do {
CURLMcode mc = curl_multi_perform(multi_handle, &still_running);
if(still_running)
/* wait for activity, timeout or "nothing" */
mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL);
++poll_counter;
if(mc)
break;
//resume transfer after header callback called
if (trans.header_callback_called && trans.paused)
{
fprintf(stderr, "Resume transfers after write header callback!\n");
resume(&trans);
}
} while(still_running);
fprintf(stderr, "writed headers %i\n", trans.writed_headers);
fprintf(stderr, "writed data size %i\n", trans.writed_data);
assert(trans.writed_data > 0);
assert(trans.writed_headers > 0);
curl_multi_remove_handle(multi_handle, trans.easy);
curl_easy_cleanup(trans.easy);
curl_multi_cleanup(multi_handle);
return 0;
} |
Thanks, that reproduced for me too now. |
I did this
see test example below
I expected the following
curl/libcurl version
7.84.0
In previous version there is no problem with resuming http2 requests.
operating system
all
test example
Possible breaking commit
d1e4a67
Possible fix
I think it should be near this line:
curl/lib/sendf.c
Line 610 in 6e83e27
The text was updated successfully, but these errors were encountered: