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