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