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