Last active
September 8, 2022 13:41
-
-
Save lockie/3c8386c68fe24ca188589c48646505f2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <stdbool.h> | |
#include "curl/curl.h" | |
#define OUTPUTFILE "download" | |
#define URL "https://http2-server-push-demo.keksi.io" | |
static bool setup(CURL* hnd) | |
{ | |
FILE* out = fopen(OUTPUTFILE, "wb"); | |
if(!out) | |
return false; | |
// write to this file | |
curl_easy_setopt(hnd, CURLOPT_WRITEDATA, out); | |
// set URL | |
curl_easy_setopt(hnd, CURLOPT_URL, URL); | |
// be verbose | |
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1); | |
// enable HTTP/2 | |
curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0); | |
// wait for pipe connection to confirm | |
curl_easy_setopt(hnd, CURLOPT_PIPEWAIT, 1); | |
return true; | |
} | |
#define UNUSED __attribute__ ((unused)) | |
// called when there's an incoming server push | |
static int server_push_callback(UNUSED CURL* parent, | |
UNUSED CURL* easy, | |
UNUSED size_t num_headers, | |
UNUSED struct curl_pushheaders* headers, | |
UNUSED void* userp) | |
{ | |
puts("Got incoming HTTP/2 server push"); | |
return CURL_PUSH_DENY; | |
} | |
#define TIMEOUT 1000 | |
int main(void) | |
{ | |
CURLM* multi_handle = curl_multi_init(); | |
CURL* easy = curl_easy_init(); | |
if(!setup(easy)) | |
{ | |
fprintf(stderr, "failed\n"); | |
return EXIT_FAILURE; | |
} | |
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); | |
int transfers = 1; // we start with one | |
do | |
{ | |
int still_running; // keep number of running handles | |
CURLMcode mc = curl_multi_perform(multi_handle, &still_running); | |
int numfds; | |
if(still_running) | |
// wait for activity, timeout or "nothing" | |
mc = curl_multi_wait(multi_handle, NULL, 0, TIMEOUT, &numfds); | |
if(mc) | |
break; | |
struct CURLMsg* m; | |
do | |
{ | |
int msgq = 0; | |
m = curl_multi_info_read(multi_handle, &msgq); | |
if(m && (m->msg == CURLMSG_DONE)) | |
{ | |
CURL* e = m->easy_handle; | |
transfers--; | |
curl_multi_remove_handle(multi_handle, e); | |
curl_easy_cleanup(e); | |
} | |
} while(m); | |
} while(transfers); | |
curl_multi_cleanup(multi_handle); | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment