← Commit list

4b85e489a4

Viktor Szakats
Viktor Szakats
2025-10-31
SUCCESS Duration: 149s

Subject

examples/http2-serverpush: fix file handle leaks

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

docs/examples/http2-serverpush.c+26 -21
@@ -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;
}
tests/libtest/cli_h2_serverpush.c+10 -11
@@ -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);