1--- 2c: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 3SPDX-License-Identifier: curl 4Title: CURLMOPT_PUSHFUNCTION 5Section: 3 6Source: libcurl 7See-also: 8 - CURLMOPT_PIPELINING (3) 9 - CURLMOPT_PUSHDATA (3) 10 - CURLOPT_PIPEWAIT (3) 11 - RFC 7540 12Protocol: 13 - HTTP 14Added-in: 7.44.0 15--- 16 17# NAME 18 19CURLMOPT_PUSHFUNCTION - callback that approves or denies server pushes 20 21# SYNOPSIS 22 23~~~c 24#include <curl/curl.h> 25 26int curl_push_callback(CURL *parent, 27 CURL *easy, 28 size_t num_headers, 29 struct curl_pushheaders *headers, 30 void *clientp); 31 32CURLMcode curl_multi_setopt(CURLM *handle, CURLMOPT_PUSHFUNCTION, 33 curl_push_callback func); 34~~~ 35 36# DESCRIPTION 37 38This callback gets called when a new HTTP/2 stream is being pushed by the 39server (using the PUSH_PROMISE frame). If no push callback is set, all offered 40pushes are denied automatically. 41 42# CALLBACK DESCRIPTION 43 44The callback gets its arguments like this: 45 46*parent* is the handle of the stream on which this push arrives. The new 47handle has been duplicated from the parent, meaning that it has gotten all its 48options inherited. It is then up to the application to alter any options if 49desired. 50 51*easy* is a newly created handle that represents this upcoming transfer. 52 53*num_headers* is the number of name+value pairs that was received and can 54be accessed 55 56*headers* is a handle used to access push headers using the accessor 57functions described below. This only accesses and provides the PUSH_PROMISE 58headers, the normal response headers are provided in the header callback as 59usual. 60 61*clientp* is the pointer set with CURLMOPT_PUSHDATA(3) 62 63If the callback returns CURL_PUSH_OK, the new easy handle is added to the 64multi handle, the callback must not do that by itself. 65 66The callback can access PUSH_PROMISE headers with two accessor 67functions. These functions can only be used from within this callback and they 68can only access the PUSH_PROMISE headers: curl_pushheader_byname(3) and 69curl_pushheader_bynum(3). The normal response headers are passed to the 70header callback for pushed streams just as for normal streams. 71 72The header fields can also be accessed with curl_easy_header(3), 73introduced in later libcurl versions. 74 75# CALLBACK RETURN VALUE 76 77## CURL_PUSH_OK (0) 78 79The application has accepted the stream and it can now start receiving data, 80the ownership of the CURL handle has been taken over by the application. 81 82## CURL_PUSH_DENY (1) 83 84The callback denies the stream and no data reaches the application, the easy 85handle is destroyed by libcurl. 86 87## CURL_PUSH_ERROROUT (2) 88 89Returning this code rejects the pushed stream and returns an error back on the 90parent stream making it get closed with an error. (Added in 7.72.0) 91 92## * 93 94All other return codes are reserved for future use. 95 96# DEFAULT 97 98NULL, no callback 99 100# %PROTOCOLS% 101 102# EXAMPLE 103 104~~~c 105#include <string.h> 106 107/* only allow pushes for filenames starting with "push-" */ 108int push_callback(CURL *parent, 109 CURL *easy, 110 size_t num_headers, 111 struct curl_pushheaders *headers, 112 void *clientp) 113{ 114 char *headp; 115 int *transfers = (int *)clientp; 116 FILE *out; 117 headp = curl_pushheader_byname(headers, ":path"); 118 if(headp && !strncmp(headp, "/push-", 6)) { 119 fprintf(stderr, "The PATH is %s\n", headp); 120 121 /* save the push here */ 122 out = fopen("pushed-stream", "wb"); 123 124 /* write to this file */ 125 curl_easy_setopt(easy, CURLOPT_WRITEDATA, out); 126 127 (*transfers)++; /* one more */ 128 129 return CURL_PUSH_OK; 130 } 131 return CURL_PUSH_DENY; 132} 133 134int main(void) 135{ 136 int counter; 137 CURLM *multi = curl_multi_init(); 138 curl_multi_setopt(multi, CURLMOPT_PUSHFUNCTION, push_callback); 139 curl_multi_setopt(multi, CURLMOPT_PUSHDATA, &counter); 140} 141~~~ 142 143# %AVAILABILITY% 144 145# RETURN VALUE 146 147Returns CURLM_OK if the option is supported, and CURLM_UNKNOWN_OPTION if not. 148