examples/http2-serverpush: fix file handle leaks
No binary (build failed)
—
(log yok)
| @@ -40,6 +40,8 @@ | |
| #error "too old libcurl, cannot do HTTP/2 server push!" | |
| #endif | |
| + | static FILE *out_download; |
| + | |
| static void dump(const char *text, unsigned char *ptr, size_t size, char nohex) | |
| { | |
| size_t i; | |
| @@ -127,21 +129,13 @@ static int my_trace(CURL *handle, curl_infotype type, | |
| static int setup(CURL *hnd, const char *url) | |
| { | |
| - | FILE *out = fopen(OUTPUTFILE, "wb"); |
| - | if(!out) |
| - | /* failed */ |
| - | return 1; |
| - | |
| - | /* write to this file */ |
| - | curl_easy_setopt(hnd, CURLOPT_WRITEDATA, out); |
| + | out_download = fopen(OUTPUTFILE, "wb"); |
| + | if(!out_download) |
| + | return 1; /* failed */ |
| /* set the same URL */ | |
| curl_easy_setopt(hnd, CURLOPT_URL, url); | |
| - | /* please be verbose */ |
| - | curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); |
| - | curl_easy_setopt(hnd, CURLOPT_DEBUGFUNCTION, my_trace); |
| - | |
| /* HTTP/2 please */ | |
| curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0); | |
| @@ -149,13 +143,22 @@ static int setup(CURL *hnd, const char *url) | |
| curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYPEER, 0L); | |
| curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYHOST, 0L); | |
| - | #if (CURLPIPE_MULTIPLEX > 0) |
| + | /* write to this file */ |
| + | curl_easy_setopt(hnd, CURLOPT_WRITEDATA, out_download); |
| + | |
| + | /* please be verbose */ |
| + | curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); |
| + | curl_easy_setopt(hnd, CURLOPT_DEBUGFUNCTION, my_trace); |
| + | |
| + | #if CURLPIPE_MULTIPLEX > 0 |
| /* wait for pipe connection to confirm */ | |
| curl_easy_setopt(hnd, CURLOPT_PIPEWAIT, 1L); | |
| #endif | |
| return 0; /* all is good */ | |
| } | |
| + | static FILE *out_push; |
| + | |
| /* called when there is an incoming push */ | |
| static int server_push_callback(CURL *parent, | |
| CURL *easy, | |
| @@ -167,7 +170,6 @@ static int server_push_callback(CURL *parent, | |
| size_t i; | |
| int *transfers = (int *)userp; | |
| char filename[128]; | |
| - | FILE *out; |
| static unsigned int count = 0; | |
| (void)parent; | |
| @@ -175,15 +177,15 @@ static int server_push_callback(CURL *parent, | |
| snprintf(filename, sizeof(filename), "push%u", count++); | |
| /* here's a new stream, save it in a new file for each new push */ | |
| - | out = fopen(filename, "wb"); |
| - | if(!out) { |
| + | out_push = fopen(filename, "wb"); |
| + | if(!out_push) { |
| /* if we cannot save it, deny it */ | |
| fprintf(stderr, "Failed to create output file for push\n"); | |
| return CURL_PUSH_DENY; | |
| } | |
| /* write to this file */ | |
| - | curl_easy_setopt(easy, CURLOPT_WRITEDATA, out); |
| + | curl_easy_setopt(easy, CURLOPT_WRITEDATA, out_push); |
| fprintf(stderr, "**** push callback approves stream %u, got %lu headers!\n", | |
| count, (unsigned long)num_headers); | |
| @@ -199,10 +201,10 @@ static int server_push_callback(CURL *parent, | |
| } | |
| (*transfers)++; /* one more */ | |
| + | |
| return CURL_PUSH_OK; | |
| } | |
| - | |
| /* | |
| * Download a file over HTTP/2, take care of server push. | |
| */ | |
| @@ -233,13 +235,13 @@ int main(int argc, char *argv[]) | |
| return 1; | |
| } | |
| - | /* add the easy transfer */ |
| - | curl_multi_add_handle(multi_handle, easy); |
| - | |
| curl_multi_setopt(multi_handle, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX); | |
| curl_multi_setopt(multi_handle, CURLMOPT_PUSHFUNCTION, server_push_callback); | |
| curl_multi_setopt(multi_handle, CURLMOPT_PUSHDATA, &transfers); | |
| + | /* add the easy transfer */ |
| + | curl_multi_add_handle(multi_handle, easy); |
| + | |
| do { | |
| struct CURLMsg *m; | |
| int still_running; /* keep number of running handles */ | |
| @@ -257,7 +259,6 @@ int main(int argc, char *argv[]) | |
| * created and added one or more easy handles but we need to clean them up | |
| * when we are done. | |
| */ | |
| - | |
| do { | |
| int msgq = 0; | |
| m = curl_multi_info_read(multi_handle, &msgq); | |
| @@ -274,5 +275,9 @@ int main(int argc, char *argv[]) | |
| curl_multi_cleanup(multi_handle); | |
| curl_global_cleanup(); | |
| + | fclose(out_download); |
| + | if(out_push) |
| + | fclose(out_push); |
| + | |
| return 0; | |
| } | |
| @@ -54,7 +54,7 @@ static int setup_h2_serverpush(CURL *hnd, const char *url) | |
| static FILE *out_push; | |
| - | /* called when there's an incoming push */ |
| + | /* called when there is an incoming push */ |
| static int server_push_callback(CURL *parent, | |
| CURL *easy, | |
| size_t num_headers, | |
| @@ -66,9 +66,9 @@ static int server_push_callback(CURL *parent, | |
| int *transfers = (int *)userp; | |
| char filename[128]; | |
| static unsigned int count = 0; | |
| - | int rv; |
| (void)parent; | |
| + | |
| curl_msnprintf(filename, sizeof(filename) - 1, "push%u", count++); | |
| /* here's a new stream, save it in a new file for each new push */ | |
| @@ -76,8 +76,7 @@ static int server_push_callback(CURL *parent, | |
| if(!out_push) { | |
| /* if we cannot save it, deny it */ | |
| curl_mfprintf(stderr, "Failed to create output file for push\n"); | |
| - | rv = CURL_PUSH_DENY; |
| - | goto out; |
| + | return CURL_PUSH_DENY; |
| } | |
| /* write to this file */ | |
| @@ -98,10 +97,8 @@ static int server_push_callback(CURL *parent, | |
| } | |
| (*transfers)++; /* one more */ | |
| - | rv = CURL_PUSH_OK; |
| - | out: |
| - | return rv; |
| + | return CURL_PUSH_OK; |
| } | |
| /* | |
| @@ -112,7 +109,6 @@ static CURLcode test_cli_h2_serverpush(const char *URL) | |
| CURL *easy; | |
| CURLM *multi_handle; | |
| int transfers = 1; /* we start with one */ | |
| - | struct CURLMsg *m; |
| debug_config.nohex = TRUE; | |
| debug_config.tracetime = FALSE; | |
| @@ -123,9 +119,6 @@ static CURLcode test_cli_h2_serverpush(const char *URL) | |
| } | |
| multi_handle = curl_multi_init(); | |
| - | curl_multi_setopt(multi_handle, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX); |
| - | curl_multi_setopt(multi_handle, CURLMOPT_PUSHFUNCTION, server_push_callback); |
| - | curl_multi_setopt(multi_handle, CURLMOPT_PUSHDATA, &transfers); |
| easy = curl_easy_init(); | |
| if(setup_h2_serverpush(easy, URL)) { | |
| @@ -134,8 +127,14 @@ static CURLcode test_cli_h2_serverpush(const char *URL) | |
| return (CURLcode)1; | |
| } | |
| + | curl_multi_setopt(multi_handle, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX); |
| + | curl_multi_setopt(multi_handle, CURLMOPT_PUSHFUNCTION, server_push_callback); |
| + | curl_multi_setopt(multi_handle, CURLMOPT_PUSHDATA, &transfers); |
| + | |
| curl_multi_add_handle(multi_handle, easy); | |
| + | |
| do { | |
| + | struct CURLMsg *m; |
| int still_running; /* keep number of running handles */ | |
| CURLMcode mc = curl_multi_perform(multi_handle, &still_running); | |