0120b86311ca9b528f07e21ed473edc82650cb2f
[platform/upstream/cmake.git] / Utilities / cmcurl / lib / http2.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * This software is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution. The terms
12  * are also available at https://curl.se/docs/copyright.html.
13  *
14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15  * copies of the Software, and permit persons to whom the Software is
16  * furnished to do so, under the terms of the COPYING file.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  ***************************************************************************/
22
23 #include "curl_setup.h"
24
25 #ifdef USE_NGHTTP2
26 #include <nghttp2/nghttp2.h>
27 #include "urldata.h"
28 #include "http2.h"
29 #include "http.h"
30 #include "sendf.h"
31 #include "select.h"
32 #include "curl_base64.h"
33 #include "strcase.h"
34 #include "multiif.h"
35 #include "url.h"
36 #include "connect.h"
37 #include "strtoofft.h"
38 #include "strdup.h"
39 #include "transfer.h"
40 #include "dynbuf.h"
41 #include "h2h3.h"
42 #include "headers.h"
43 /* The last 3 #include files should be in this order */
44 #include "curl_printf.h"
45 #include "curl_memory.h"
46 #include "memdebug.h"
47
48 #define H2_BUFSIZE 32768
49
50 #if (NGHTTP2_VERSION_NUM < 0x010c00)
51 #error too old nghttp2 version, upgrade!
52 #endif
53
54 #ifdef CURL_DISABLE_VERBOSE_STRINGS
55 #define nghttp2_session_callbacks_set_error_callback(x,y)
56 #endif
57
58 #if (NGHTTP2_VERSION_NUM >= 0x010c00)
59 #define NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE 1
60 #endif
61
62 #define HTTP2_HUGE_WINDOW_SIZE (32 * 1024 * 1024) /* 32 MB */
63
64 #ifdef DEBUG_HTTP2
65 #define H2BUGF(x) x
66 #else
67 #define H2BUGF(x) do { } while(0)
68 #endif
69
70 static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
71                           char *mem, size_t len, CURLcode *err);
72 static bool http2_connisdead(struct Curl_easy *data,
73                              struct connectdata *conn);
74 static int h2_session_send(struct Curl_easy *data,
75                            nghttp2_session *h2);
76 static int h2_process_pending_input(struct Curl_easy *data,
77                                     struct http_conn *httpc,
78                                     CURLcode *err);
79
80 /*
81  * Curl_http2_init_state() is called when the easy handle is created and
82  * allows for HTTP/2 specific init of state.
83  */
84 void Curl_http2_init_state(struct UrlState *state)
85 {
86   state->stream_weight = NGHTTP2_DEFAULT_WEIGHT;
87 }
88
89 /*
90  * Curl_http2_init_userset() is called when the easy handle is created and
91  * allows for HTTP/2 specific user-set fields.
92  */
93 void Curl_http2_init_userset(struct UserDefined *set)
94 {
95   set->stream_weight = NGHTTP2_DEFAULT_WEIGHT;
96 }
97
98 static int http2_getsock(struct Curl_easy *data,
99                          struct connectdata *conn,
100                          curl_socket_t *sock)
101 {
102   const struct http_conn *c = &conn->proto.httpc;
103   struct SingleRequest *k = &data->req;
104   int bitmap = GETSOCK_BLANK;
105   struct HTTP *stream = data->req.p.http;
106
107   sock[0] = conn->sock[FIRSTSOCKET];
108
109   if(!(k->keepon & KEEP_RECV_PAUSE))
110     /* Unless paused - in a HTTP/2 connection we can basically always get a
111        frame so we should always be ready for one */
112     bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
113
114   /* we're (still uploading OR the HTTP/2 layer wants to send data) AND
115      there's a window to send data in */
116   if((((k->keepon & (KEEP_SEND|KEEP_SEND_PAUSE)) == KEEP_SEND) ||
117       nghttp2_session_want_write(c->h2)) &&
118      (nghttp2_session_get_remote_window_size(c->h2) &&
119       nghttp2_session_get_stream_remote_window_size(c->h2,
120                                                     stream->stream_id)))
121     bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
122
123   return bitmap;
124 }
125
126 /*
127  * http2_stream_free() free HTTP2 stream related data
128  */
129 static void http2_stream_free(struct HTTP *http)
130 {
131   if(http) {
132     Curl_dyn_free(&http->header_recvbuf);
133     for(; http->push_headers_used > 0; --http->push_headers_used) {
134       free(http->push_headers[http->push_headers_used - 1]);
135     }
136     free(http->push_headers);
137     http->push_headers = NULL;
138   }
139 }
140
141 /*
142  * Disconnects *a* connection used for HTTP/2. It might be an old one from the
143  * connection cache and not the "main" one. Don't touch the easy handle!
144  */
145
146 static CURLcode http2_disconnect(struct Curl_easy *data,
147                                  struct connectdata *conn,
148                                  bool dead_connection)
149 {
150   struct http_conn *c = &conn->proto.httpc;
151   (void)dead_connection;
152 #ifndef DEBUG_HTTP2
153   (void)data;
154 #endif
155
156   H2BUGF(infof(data, "HTTP/2 DISCONNECT starts now"));
157
158   nghttp2_session_del(c->h2);
159   Curl_safefree(c->inbuf);
160
161   H2BUGF(infof(data, "HTTP/2 DISCONNECT done"));
162
163   return CURLE_OK;
164 }
165
166 /*
167  * The server may send us data at any point (e.g. PING frames). Therefore,
168  * we cannot assume that an HTTP/2 socket is dead just because it is readable.
169  *
170  * Instead, if it is readable, run Curl_connalive() to peek at the socket
171  * and distinguish between closed and data.
172  */
173 static bool http2_connisdead(struct Curl_easy *data, struct connectdata *conn)
174 {
175   int sval;
176   bool dead = TRUE;
177
178   if(conn->bits.close)
179     return TRUE;
180
181   sval = SOCKET_READABLE(conn->sock[FIRSTSOCKET], 0);
182   if(sval == 0) {
183     /* timeout */
184     dead = FALSE;
185   }
186   else if(sval & CURL_CSELECT_ERR) {
187     /* socket is in an error state */
188     dead = TRUE;
189   }
190   else if(sval & CURL_CSELECT_IN) {
191     /* readable with no error. could still be closed */
192     dead = !Curl_connalive(conn);
193     if(!dead) {
194       /* This happens before we've sent off a request and the connection is
195          not in use by any other transfer, there shouldn't be any data here,
196          only "protocol frames" */
197       CURLcode result;
198       struct http_conn *httpc = &conn->proto.httpc;
199       ssize_t nread = -1;
200       if(httpc->recv_underlying)
201         /* if called "too early", this pointer isn't setup yet! */
202         nread = ((Curl_recv *)httpc->recv_underlying)(
203           data, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, &result);
204       if(nread != -1) {
205         H2BUGF(infof(data,
206                      "%d bytes stray data read before trying h2 connection",
207                      (int)nread));
208         httpc->nread_inbuf = 0;
209         httpc->inbuflen = nread;
210         if(h2_process_pending_input(data, httpc, &result) < 0)
211           /* immediate error, considered dead */
212           dead = TRUE;
213       }
214       else
215         /* the read failed so let's say this is dead anyway */
216         dead = TRUE;
217     }
218   }
219
220   return dead;
221 }
222
223 /*
224  * Set the transfer that is currently using this HTTP/2 connection.
225  */
226 static void set_transfer(struct http_conn *c,
227                          struct Curl_easy *data)
228 {
229   c->trnsfr = data;
230 }
231
232 /*
233  * Get the transfer that is currently using this HTTP/2 connection.
234  */
235 static struct Curl_easy *get_transfer(struct http_conn *c)
236 {
237   DEBUGASSERT(c && c->trnsfr);
238   return c->trnsfr;
239 }
240
241 static unsigned int http2_conncheck(struct Curl_easy *data,
242                                     struct connectdata *conn,
243                                     unsigned int checks_to_perform)
244 {
245   unsigned int ret_val = CONNRESULT_NONE;
246   struct http_conn *c = &conn->proto.httpc;
247   int rc;
248   bool send_frames = false;
249
250   if(checks_to_perform & CONNCHECK_ISDEAD) {
251     if(http2_connisdead(data, conn))
252       ret_val |= CONNRESULT_DEAD;
253   }
254
255   if(checks_to_perform & CONNCHECK_KEEPALIVE) {
256     struct curltime now = Curl_now();
257     timediff_t elapsed = Curl_timediff(now, conn->keepalive);
258
259     if(elapsed > data->set.upkeep_interval_ms) {
260       /* Perform an HTTP/2 PING */
261       rc = nghttp2_submit_ping(c->h2, 0, ZERO_NULL);
262       if(!rc) {
263         /* Successfully added a PING frame to the session. Need to flag this
264            so the frame is sent. */
265         send_frames = true;
266       }
267       else {
268        failf(data, "nghttp2_submit_ping() failed: %s(%d)",
269              nghttp2_strerror(rc), rc);
270       }
271
272       conn->keepalive = now;
273     }
274   }
275
276   if(send_frames) {
277     set_transfer(c, data); /* set the transfer */
278     rc = nghttp2_session_send(c->h2);
279     if(rc)
280       failf(data, "nghttp2_session_send() failed: %s(%d)",
281             nghttp2_strerror(rc), rc);
282   }
283
284   return ret_val;
285 }
286
287 /* called from http_setup_conn */
288 void Curl_http2_setup_req(struct Curl_easy *data)
289 {
290   struct HTTP *http = data->req.p.http;
291   http->bodystarted = FALSE;
292   http->status_code = -1;
293   http->pausedata = NULL;
294   http->pauselen = 0;
295   http->closed = FALSE;
296   http->close_handled = FALSE;
297   http->mem = NULL;
298   http->len = 0;
299   http->memlen = 0;
300   http->error = NGHTTP2_NO_ERROR;
301 }
302
303 /* called from http_setup_conn */
304 void Curl_http2_setup_conn(struct connectdata *conn)
305 {
306   conn->proto.httpc.settings.max_concurrent_streams =
307     DEFAULT_MAX_CONCURRENT_STREAMS;
308 }
309
310 /*
311  * HTTP2 handler interface. This isn't added to the general list of protocols
312  * but will be used at run-time when the protocol is dynamically switched from
313  * HTTP to HTTP2.
314  */
315 static const struct Curl_handler Curl_handler_http2 = {
316   "HTTP",                               /* scheme */
317   ZERO_NULL,                            /* setup_connection */
318   Curl_http,                            /* do_it */
319   Curl_http_done,                       /* done */
320   ZERO_NULL,                            /* do_more */
321   ZERO_NULL,                            /* connect_it */
322   ZERO_NULL,                            /* connecting */
323   ZERO_NULL,                            /* doing */
324   http2_getsock,                        /* proto_getsock */
325   http2_getsock,                        /* doing_getsock */
326   ZERO_NULL,                            /* domore_getsock */
327   http2_getsock,                        /* perform_getsock */
328   http2_disconnect,                     /* disconnect */
329   ZERO_NULL,                            /* readwrite */
330   http2_conncheck,                      /* connection_check */
331   ZERO_NULL,                            /* attach connection */
332   PORT_HTTP,                            /* defport */
333   CURLPROTO_HTTP,                       /* protocol */
334   CURLPROTO_HTTP,                       /* family */
335   PROTOPT_STREAM                        /* flags */
336 };
337
338 static const struct Curl_handler Curl_handler_http2_ssl = {
339   "HTTPS",                              /* scheme */
340   ZERO_NULL,                            /* setup_connection */
341   Curl_http,                            /* do_it */
342   Curl_http_done,                       /* done */
343   ZERO_NULL,                            /* do_more */
344   ZERO_NULL,                            /* connect_it */
345   ZERO_NULL,                            /* connecting */
346   ZERO_NULL,                            /* doing */
347   http2_getsock,                        /* proto_getsock */
348   http2_getsock,                        /* doing_getsock */
349   ZERO_NULL,                            /* domore_getsock */
350   http2_getsock,                        /* perform_getsock */
351   http2_disconnect,                     /* disconnect */
352   ZERO_NULL,                            /* readwrite */
353   http2_conncheck,                      /* connection_check */
354   ZERO_NULL,                            /* attach connection */
355   PORT_HTTP,                            /* defport */
356   CURLPROTO_HTTPS,                      /* protocol */
357   CURLPROTO_HTTP,                       /* family */
358   PROTOPT_SSL | PROTOPT_STREAM          /* flags */
359 };
360
361 /*
362  * Store nghttp2 version info in this buffer.
363  */
364 void Curl_http2_ver(char *p, size_t len)
365 {
366   nghttp2_info *h2 = nghttp2_version(0);
367   (void)msnprintf(p, len, "nghttp2/%s", h2->version_str);
368 }
369
370 /*
371  * The implementation of nghttp2_send_callback type. Here we write |data| with
372  * size |length| to the network and return the number of bytes actually
373  * written. See the documentation of nghttp2_send_callback for the details.
374  */
375 static ssize_t send_callback(nghttp2_session *h2,
376                              const uint8_t *mem, size_t length, int flags,
377                              void *userp)
378 {
379   struct connectdata *conn = (struct connectdata *)userp;
380   struct http_conn *c = &conn->proto.httpc;
381   struct Curl_easy *data = get_transfer(c);
382   ssize_t written;
383   CURLcode result = CURLE_OK;
384
385   (void)h2;
386   (void)flags;
387
388   if(!c->send_underlying)
389     /* called before setup properly! */
390     return NGHTTP2_ERR_CALLBACK_FAILURE;
391
392   written = ((Curl_send*)c->send_underlying)(data, FIRSTSOCKET,
393                                              mem, length, &result);
394
395   if(result == CURLE_AGAIN) {
396     return NGHTTP2_ERR_WOULDBLOCK;
397   }
398
399   if(written == -1) {
400     failf(data, "Failed sending HTTP2 data");
401     return NGHTTP2_ERR_CALLBACK_FAILURE;
402   }
403
404   if(!written)
405     return NGHTTP2_ERR_WOULDBLOCK;
406
407   return written;
408 }
409
410
411 /* We pass a pointer to this struct in the push callback, but the contents of
412    the struct are hidden from the user. */
413 struct curl_pushheaders {
414   struct Curl_easy *data;
415   const nghttp2_push_promise *frame;
416 };
417
418 /*
419  * push header access function. Only to be used from within the push callback
420  */
421 char *curl_pushheader_bynum(struct curl_pushheaders *h, size_t num)
422 {
423   /* Verify that we got a good easy handle in the push header struct, mostly to
424      detect rubbish input fast(er). */
425   if(!h || !GOOD_EASY_HANDLE(h->data))
426     return NULL;
427   else {
428     struct HTTP *stream = h->data->req.p.http;
429     if(num < stream->push_headers_used)
430       return stream->push_headers[num];
431   }
432   return NULL;
433 }
434
435 /*
436  * push header access function. Only to be used from within the push callback
437  */
438 char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header)
439 {
440   /* Verify that we got a good easy handle in the push header struct,
441      mostly to detect rubbish input fast(er). Also empty header name
442      is just a rubbish too. We have to allow ":" at the beginning of
443      the header, but header == ":" must be rejected. If we have ':' in
444      the middle of header, it could be matched in middle of the value,
445      this is because we do prefix match.*/
446   if(!h || !GOOD_EASY_HANDLE(h->data) || !header || !header[0] ||
447      !strcmp(header, ":") || strchr(header + 1, ':'))
448     return NULL;
449   else {
450     struct HTTP *stream = h->data->req.p.http;
451     size_t len = strlen(header);
452     size_t i;
453     for(i = 0; i<stream->push_headers_used; i++) {
454       if(!strncmp(header, stream->push_headers[i], len)) {
455         /* sub-match, make sure that it is followed by a colon */
456         if(stream->push_headers[i][len] != ':')
457           continue;
458         return &stream->push_headers[i][len + 1];
459       }
460     }
461   }
462   return NULL;
463 }
464
465 /*
466  * This specific transfer on this connection has been "drained".
467  */
468 static void drained_transfer(struct Curl_easy *data,
469                              struct http_conn *httpc)
470 {
471   DEBUGASSERT(httpc->drain_total >= data->state.drain);
472   httpc->drain_total -= data->state.drain;
473   data->state.drain = 0;
474 }
475
476 /*
477  * Mark this transfer to get "drained".
478  */
479 static void drain_this(struct Curl_easy *data,
480                        struct http_conn *httpc)
481 {
482   data->state.drain++;
483   httpc->drain_total++;
484   DEBUGASSERT(httpc->drain_total >= data->state.drain);
485 }
486
487 static struct Curl_easy *duphandle(struct Curl_easy *data)
488 {
489   struct Curl_easy *second = curl_easy_duphandle(data);
490   if(second) {
491     /* setup the request struct */
492     struct HTTP *http = calloc(1, sizeof(struct HTTP));
493     if(!http) {
494       (void)Curl_close(&second);
495     }
496     else {
497       second->req.p.http = http;
498       Curl_dyn_init(&http->header_recvbuf, DYN_H2_HEADERS);
499       Curl_http2_setup_req(second);
500       second->state.stream_weight = data->state.stream_weight;
501     }
502   }
503   return second;
504 }
505
506 static int set_transfer_url(struct Curl_easy *data,
507                             struct curl_pushheaders *hp)
508 {
509   const char *v;
510   CURLUcode uc;
511   char *url = NULL;
512   int rc = 0;
513   CURLU *u = curl_url();
514
515   if(!u)
516     return 5;
517
518   v = curl_pushheader_byname(hp, H2H3_PSEUDO_SCHEME);
519   if(v) {
520     uc = curl_url_set(u, CURLUPART_SCHEME, v, 0);
521     if(uc) {
522       rc = 1;
523       goto fail;
524     }
525   }
526
527   v = curl_pushheader_byname(hp, H2H3_PSEUDO_AUTHORITY);
528   if(v) {
529     uc = curl_url_set(u, CURLUPART_HOST, v, 0);
530     if(uc) {
531       rc = 2;
532       goto fail;
533     }
534   }
535
536   v = curl_pushheader_byname(hp, H2H3_PSEUDO_PATH);
537   if(v) {
538     uc = curl_url_set(u, CURLUPART_PATH, v, 0);
539     if(uc) {
540       rc = 3;
541       goto fail;
542     }
543   }
544
545   uc = curl_url_get(u, CURLUPART_URL, &url, 0);
546   if(uc)
547     rc = 4;
548   fail:
549   curl_url_cleanup(u);
550   if(rc)
551     return rc;
552
553   if(data->state.url_alloc)
554     free(data->state.url);
555   data->state.url_alloc = TRUE;
556   data->state.url = url;
557   return 0;
558 }
559
560 static int push_promise(struct Curl_easy *data,
561                         struct connectdata *conn,
562                         const nghttp2_push_promise *frame)
563 {
564   int rv; /* one of the CURL_PUSH_* defines */
565   H2BUGF(infof(data, "PUSH_PROMISE received, stream %u",
566                frame->promised_stream_id));
567   if(data->multi->push_cb) {
568     struct HTTP *stream;
569     struct HTTP *newstream;
570     struct curl_pushheaders heads;
571     CURLMcode rc;
572     struct http_conn *httpc;
573     size_t i;
574     /* clone the parent */
575     struct Curl_easy *newhandle = duphandle(data);
576     if(!newhandle) {
577       infof(data, "failed to duplicate handle");
578       rv = CURL_PUSH_DENY; /* FAIL HARD */
579       goto fail;
580     }
581
582     heads.data = data;
583     heads.frame = frame;
584     /* ask the application */
585     H2BUGF(infof(data, "Got PUSH_PROMISE, ask application"));
586
587     stream = data->req.p.http;
588     if(!stream) {
589       failf(data, "Internal NULL stream");
590       (void)Curl_close(&newhandle);
591       rv = CURL_PUSH_DENY;
592       goto fail;
593     }
594
595     rv = set_transfer_url(newhandle, &heads);
596     if(rv) {
597       (void)Curl_close(&newhandle);
598       rv = CURL_PUSH_DENY;
599       goto fail;
600     }
601
602     Curl_set_in_callback(data, true);
603     rv = data->multi->push_cb(data, newhandle,
604                               stream->push_headers_used, &heads,
605                               data->multi->push_userp);
606     Curl_set_in_callback(data, false);
607
608     /* free the headers again */
609     for(i = 0; i<stream->push_headers_used; i++)
610       free(stream->push_headers[i]);
611     free(stream->push_headers);
612     stream->push_headers = NULL;
613     stream->push_headers_used = 0;
614
615     if(rv) {
616       DEBUGASSERT((rv > CURL_PUSH_OK) && (rv <= CURL_PUSH_ERROROUT));
617       /* denied, kill off the new handle again */
618       http2_stream_free(newhandle->req.p.http);
619       newhandle->req.p.http = NULL;
620       (void)Curl_close(&newhandle);
621       goto fail;
622     }
623
624     newstream = newhandle->req.p.http;
625     newstream->stream_id = frame->promised_stream_id;
626     newhandle->req.maxdownload = -1;
627     newhandle->req.size = -1;
628
629     /* approved, add to the multi handle and immediately switch to PERFORM
630        state with the given connection !*/
631     rc = Curl_multi_add_perform(data->multi, newhandle, conn);
632     if(rc) {
633       infof(data, "failed to add handle to multi");
634       http2_stream_free(newhandle->req.p.http);
635       newhandle->req.p.http = NULL;
636       Curl_close(&newhandle);
637       rv = CURL_PUSH_DENY;
638       goto fail;
639     }
640
641     httpc = &conn->proto.httpc;
642     rv = nghttp2_session_set_stream_user_data(httpc->h2,
643                                               frame->promised_stream_id,
644                                               newhandle);
645     if(rv) {
646       infof(data, "failed to set user_data for stream %d",
647             frame->promised_stream_id);
648       DEBUGASSERT(0);
649       rv = CURL_PUSH_DENY;
650       goto fail;
651     }
652     Curl_dyn_init(&newstream->header_recvbuf, DYN_H2_HEADERS);
653     Curl_dyn_init(&newstream->trailer_recvbuf, DYN_H2_TRAILERS);
654   }
655   else {
656     H2BUGF(infof(data, "Got PUSH_PROMISE, ignore it"));
657     rv = CURL_PUSH_DENY;
658   }
659   fail:
660   return rv;
661 }
662
663 /*
664  * multi_connchanged() is called to tell that there is a connection in
665  * this multi handle that has changed state (multiplexing become possible, the
666  * number of allowed streams changed or similar), and a subsequent use of this
667  * multi handle should move CONNECT_PEND handles back to CONNECT to have them
668  * retry.
669  */
670 static void multi_connchanged(struct Curl_multi *multi)
671 {
672   multi->recheckstate = TRUE;
673 }
674
675 static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
676                          void *userp)
677 {
678   struct connectdata *conn = (struct connectdata *)userp;
679   struct http_conn *httpc = &conn->proto.httpc;
680   struct Curl_easy *data_s = NULL;
681   struct HTTP *stream = NULL;
682   struct Curl_easy *data = get_transfer(httpc);
683   int rv;
684   size_t left, ncopy;
685   int32_t stream_id = frame->hd.stream_id;
686   CURLcode result;
687
688   if(!stream_id) {
689     /* stream ID zero is for connection-oriented stuff */
690     if(frame->hd.type == NGHTTP2_SETTINGS) {
691       uint32_t max_conn = httpc->settings.max_concurrent_streams;
692       H2BUGF(infof(data, "Got SETTINGS"));
693       httpc->settings.max_concurrent_streams =
694         nghttp2_session_get_remote_settings(
695           session, NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS);
696       httpc->settings.enable_push =
697         nghttp2_session_get_remote_settings(
698           session, NGHTTP2_SETTINGS_ENABLE_PUSH);
699       H2BUGF(infof(data, "MAX_CONCURRENT_STREAMS == %d",
700                    httpc->settings.max_concurrent_streams));
701       H2BUGF(infof(data, "ENABLE_PUSH == %s",
702                    httpc->settings.enable_push?"TRUE":"false"));
703       if(max_conn != httpc->settings.max_concurrent_streams) {
704         /* only signal change if the value actually changed */
705         infof(data,
706               "Connection state changed (MAX_CONCURRENT_STREAMS == %u)!",
707               httpc->settings.max_concurrent_streams);
708         multi_connchanged(data->multi);
709       }
710     }
711     return 0;
712   }
713   data_s = nghttp2_session_get_stream_user_data(session, stream_id);
714   if(!data_s) {
715     H2BUGF(infof(data,
716                  "No Curl_easy associated with stream: %x",
717                  stream_id));
718     return 0;
719   }
720
721   stream = data_s->req.p.http;
722   if(!stream) {
723     H2BUGF(infof(data_s, "No proto pointer for stream: %x",
724                  stream_id));
725     return NGHTTP2_ERR_CALLBACK_FAILURE;
726   }
727
728   H2BUGF(infof(data_s, "on_frame_recv() header %x stream %x",
729                frame->hd.type, stream_id));
730
731   switch(frame->hd.type) {
732   case NGHTTP2_DATA:
733     /* If body started on this stream, then receiving DATA is illegal. */
734     if(!stream->bodystarted) {
735       rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
736                                      stream_id, NGHTTP2_PROTOCOL_ERROR);
737
738       if(nghttp2_is_fatal(rv)) {
739         return NGHTTP2_ERR_CALLBACK_FAILURE;
740       }
741     }
742     break;
743   case NGHTTP2_HEADERS:
744     if(stream->bodystarted) {
745       /* Only valid HEADERS after body started is trailer HEADERS.  We
746          buffer them in on_header callback. */
747       break;
748     }
749
750     /* nghttp2 guarantees that :status is received, and we store it to
751        stream->status_code. Fuzzing has proven this can still be reached
752        without status code having been set. */
753     if(stream->status_code == -1)
754       return NGHTTP2_ERR_CALLBACK_FAILURE;
755
756     /* Only final status code signals the end of header */
757     if(stream->status_code / 100 != 1) {
758       stream->bodystarted = TRUE;
759       stream->status_code = -1;
760     }
761
762     result = Curl_dyn_addn(&stream->header_recvbuf, STRCONST("\r\n"));
763     if(result)
764       return NGHTTP2_ERR_CALLBACK_FAILURE;
765
766     left = Curl_dyn_len(&stream->header_recvbuf) -
767       stream->nread_header_recvbuf;
768     ncopy = CURLMIN(stream->len, left);
769
770     memcpy(&stream->mem[stream->memlen],
771            Curl_dyn_ptr(&stream->header_recvbuf) +
772            stream->nread_header_recvbuf,
773            ncopy);
774     stream->nread_header_recvbuf += ncopy;
775
776     DEBUGASSERT(stream->mem);
777     H2BUGF(infof(data_s, "Store %zu bytes headers from stream %u at %p",
778                  ncopy, stream_id, stream->mem));
779
780     stream->len -= ncopy;
781     stream->memlen += ncopy;
782
783     drain_this(data_s, httpc);
784     /* if we receive data for another handle, wake that up */
785     if(get_transfer(httpc) != data_s)
786       Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
787     break;
788   case NGHTTP2_PUSH_PROMISE:
789     rv = push_promise(data_s, conn, &frame->push_promise);
790     if(rv) { /* deny! */
791       int h2;
792       DEBUGASSERT((rv > CURL_PUSH_OK) && (rv <= CURL_PUSH_ERROROUT));
793       h2 = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
794                                      frame->push_promise.promised_stream_id,
795                                      NGHTTP2_CANCEL);
796       if(nghttp2_is_fatal(h2))
797         return NGHTTP2_ERR_CALLBACK_FAILURE;
798       else if(rv == CURL_PUSH_ERROROUT) {
799         DEBUGF(infof(data_s, "Fail the parent stream (too)"));
800         return NGHTTP2_ERR_CALLBACK_FAILURE;
801       }
802     }
803     break;
804   default:
805     H2BUGF(infof(data_s, "Got frame type %x for stream %u",
806                  frame->hd.type, stream_id));
807     break;
808   }
809   return 0;
810 }
811
812 static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
813                               int32_t stream_id,
814                               const uint8_t *mem, size_t len, void *userp)
815 {
816   struct HTTP *stream;
817   struct Curl_easy *data_s;
818   size_t nread;
819   struct connectdata *conn = (struct connectdata *)userp;
820   struct http_conn *httpc = &conn->proto.httpc;
821   (void)session;
822   (void)flags;
823
824   DEBUGASSERT(stream_id); /* should never be a zero stream ID here */
825
826   /* get the stream from the hash based on Stream ID */
827   data_s = nghttp2_session_get_stream_user_data(session, stream_id);
828   if(!data_s) {
829     /* Receiving a Stream ID not in the hash should not happen - unless
830        we have aborted a transfer artificially and there were more data
831        in the pipeline. Silently ignore. */
832     H2BUGF(fprintf(stderr, "Data for stream %u but it doesn't exist\n",
833                    stream_id));
834     return 0;
835   }
836
837   stream = data_s->req.p.http;
838   if(!stream)
839     return NGHTTP2_ERR_CALLBACK_FAILURE;
840
841   nread = CURLMIN(stream->len, len);
842   memcpy(&stream->mem[stream->memlen], mem, nread);
843
844   stream->len -= nread;
845   stream->memlen += nread;
846
847   drain_this(data_s, &conn->proto.httpc);
848
849   /* if we receive data for another handle, wake that up */
850   if(get_transfer(httpc) != data_s)
851     Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
852
853   H2BUGF(infof(data_s, "%zu data received for stream %u "
854                "(%zu left in buffer %p, total %zu)",
855                nread, stream_id,
856                stream->len, stream->mem,
857                stream->memlen));
858
859   if(nread < len) {
860     stream->pausedata = mem + nread;
861     stream->pauselen = len - nread;
862     H2BUGF(infof(data_s, "NGHTTP2_ERR_PAUSE - %zu bytes out of buffer"
863                  ", stream %u",
864                  len - nread, stream_id));
865     data_s->conn->proto.httpc.pause_stream_id = stream_id;
866
867     return NGHTTP2_ERR_PAUSE;
868   }
869
870   /* pause execution of nghttp2 if we received data for another handle
871      in order to process them first. */
872   if(get_transfer(httpc) != data_s) {
873     data_s->conn->proto.httpc.pause_stream_id = stream_id;
874
875     return NGHTTP2_ERR_PAUSE;
876   }
877
878   return 0;
879 }
880
881 static int on_stream_close(nghttp2_session *session, int32_t stream_id,
882                            uint32_t error_code, void *userp)
883 {
884   struct Curl_easy *data_s;
885   struct HTTP *stream;
886   struct connectdata *conn = (struct connectdata *)userp;
887   int rv;
888   (void)session;
889   (void)stream_id;
890
891   if(stream_id) {
892     struct http_conn *httpc;
893     /* get the stream from the hash based on Stream ID, stream ID zero is for
894        connection-oriented stuff */
895     data_s = nghttp2_session_get_stream_user_data(session, stream_id);
896     if(!data_s) {
897       /* We could get stream ID not in the hash.  For example, if we
898          decided to reject stream (e.g., PUSH_PROMISE). */
899       return 0;
900     }
901     H2BUGF(infof(data_s, "on_stream_close(), %s (err %d), stream %u",
902                  nghttp2_http2_strerror(error_code), error_code, stream_id));
903     stream = data_s->req.p.http;
904     if(!stream)
905       return NGHTTP2_ERR_CALLBACK_FAILURE;
906
907     stream->closed = TRUE;
908     httpc = &conn->proto.httpc;
909     drain_this(data_s, httpc);
910     Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
911     stream->error = error_code;
912
913     /* remove the entry from the hash as the stream is now gone */
914     rv = nghttp2_session_set_stream_user_data(session, stream_id, 0);
915     if(rv) {
916       infof(data_s, "http/2: failed to clear user_data for stream %d",
917             stream_id);
918       DEBUGASSERT(0);
919     }
920     if(stream_id == httpc->pause_stream_id) {
921       H2BUGF(infof(data_s, "Stopped the pause stream"));
922       httpc->pause_stream_id = 0;
923     }
924     H2BUGF(infof(data_s, "Removed stream %u hash", stream_id));
925     stream->stream_id = 0; /* cleared */
926   }
927   return 0;
928 }
929
930 static int on_begin_headers(nghttp2_session *session,
931                             const nghttp2_frame *frame, void *userp)
932 {
933   struct HTTP *stream;
934   struct Curl_easy *data_s = NULL;
935   (void)userp;
936
937   data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
938   if(!data_s) {
939     return 0;
940   }
941
942   H2BUGF(infof(data_s, "on_begin_headers() was called"));
943
944   if(frame->hd.type != NGHTTP2_HEADERS) {
945     return 0;
946   }
947
948   stream = data_s->req.p.http;
949   if(!stream || !stream->bodystarted) {
950     return 0;
951   }
952
953   return 0;
954 }
955
956 /* Decode HTTP status code.  Returns -1 if no valid status code was
957    decoded. */
958 static int decode_status_code(const uint8_t *value, size_t len)
959 {
960   int i;
961   int res;
962
963   if(len != 3) {
964     return -1;
965   }
966
967   res = 0;
968
969   for(i = 0; i < 3; ++i) {
970     char c = value[i];
971
972     if(c < '0' || c > '9') {
973       return -1;
974     }
975
976     res *= 10;
977     res += c - '0';
978   }
979
980   return res;
981 }
982
983 /* frame->hd.type is either NGHTTP2_HEADERS or NGHTTP2_PUSH_PROMISE */
984 static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
985                      const uint8_t *name, size_t namelen,
986                      const uint8_t *value, size_t valuelen,
987                      uint8_t flags,
988                      void *userp)
989 {
990   struct HTTP *stream;
991   struct Curl_easy *data_s;
992   int32_t stream_id = frame->hd.stream_id;
993   struct connectdata *conn = (struct connectdata *)userp;
994   struct http_conn *httpc = &conn->proto.httpc;
995   CURLcode result;
996   (void)flags;
997
998   DEBUGASSERT(stream_id); /* should never be a zero stream ID here */
999
1000   /* get the stream from the hash based on Stream ID */
1001   data_s = nghttp2_session_get_stream_user_data(session, stream_id);
1002   if(!data_s)
1003     /* Receiving a Stream ID not in the hash should not happen, this is an
1004        internal error more than anything else! */
1005     return NGHTTP2_ERR_CALLBACK_FAILURE;
1006
1007   stream = data_s->req.p.http;
1008   if(!stream) {
1009     failf(data_s, "Internal NULL stream");
1010     return NGHTTP2_ERR_CALLBACK_FAILURE;
1011   }
1012
1013   /* Store received PUSH_PROMISE headers to be used when the subsequent
1014      PUSH_PROMISE callback comes */
1015   if(frame->hd.type == NGHTTP2_PUSH_PROMISE) {
1016     char *h;
1017
1018     if(!strcmp(H2H3_PSEUDO_AUTHORITY, (const char *)name)) {
1019       /* pseudo headers are lower case */
1020       int rc = 0;
1021       char *check = aprintf("%s:%d", conn->host.name, conn->remote_port);
1022       if(!check)
1023         /* no memory */
1024         return NGHTTP2_ERR_CALLBACK_FAILURE;
1025       if(!Curl_strcasecompare(check, (const char *)value) &&
1026          ((conn->remote_port != conn->given->defport) ||
1027           !Curl_strcasecompare(conn->host.name, (const char *)value))) {
1028         /* This is push is not for the same authority that was asked for in
1029          * the URL. RFC 7540 section 8.2 says: "A client MUST treat a
1030          * PUSH_PROMISE for which the server is not authoritative as a stream
1031          * error of type PROTOCOL_ERROR."
1032          */
1033         (void)nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
1034                                         stream_id, NGHTTP2_PROTOCOL_ERROR);
1035         rc = NGHTTP2_ERR_CALLBACK_FAILURE;
1036       }
1037       free(check);
1038       if(rc)
1039         return rc;
1040     }
1041
1042     if(!stream->push_headers) {
1043       stream->push_headers_alloc = 10;
1044       stream->push_headers = malloc(stream->push_headers_alloc *
1045                                     sizeof(char *));
1046       if(!stream->push_headers)
1047         return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
1048       stream->push_headers_used = 0;
1049     }
1050     else if(stream->push_headers_used ==
1051             stream->push_headers_alloc) {
1052       char **headp;
1053       stream->push_headers_alloc *= 2;
1054       headp = Curl_saferealloc(stream->push_headers,
1055                                stream->push_headers_alloc * sizeof(char *));
1056       if(!headp) {
1057         stream->push_headers = NULL;
1058         return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
1059       }
1060       stream->push_headers = headp;
1061     }
1062     h = aprintf("%s:%s", name, value);
1063     if(h)
1064       stream->push_headers[stream->push_headers_used++] = h;
1065     return 0;
1066   }
1067
1068   if(stream->bodystarted) {
1069     /* This is a trailer */
1070     H2BUGF(infof(data_s, "h2 trailer: %.*s: %.*s", namelen, name, valuelen,
1071                  value));
1072     result = Curl_dyn_addf(&stream->trailer_recvbuf,
1073                            "%.*s: %.*s\r\n", namelen, name,
1074                            valuelen, value);
1075     if(result)
1076       return NGHTTP2_ERR_CALLBACK_FAILURE;
1077
1078     return 0;
1079   }
1080
1081   if(namelen == sizeof(H2H3_PSEUDO_STATUS) - 1 &&
1082      memcmp(H2H3_PSEUDO_STATUS, name, namelen) == 0) {
1083     /* nghttp2 guarantees :status is received first and only once, and
1084        value is 3 digits status code, and decode_status_code always
1085        succeeds. */
1086     char buffer[32];
1087     stream->status_code = decode_status_code(value, valuelen);
1088     DEBUGASSERT(stream->status_code != -1);
1089     msnprintf(buffer, sizeof(buffer), H2H3_PSEUDO_STATUS ":%u\r",
1090               stream->status_code);
1091     result = Curl_headers_push(data_s, buffer, CURLH_PSEUDO);
1092     if(result)
1093       return NGHTTP2_ERR_CALLBACK_FAILURE;
1094     result = Curl_dyn_addn(&stream->header_recvbuf, STRCONST("HTTP/2 "));
1095     if(result)
1096       return NGHTTP2_ERR_CALLBACK_FAILURE;
1097     result = Curl_dyn_addn(&stream->header_recvbuf, value, valuelen);
1098     if(result)
1099       return NGHTTP2_ERR_CALLBACK_FAILURE;
1100     /* the space character after the status code is mandatory */
1101     result = Curl_dyn_addn(&stream->header_recvbuf, STRCONST(" \r\n"));
1102     if(result)
1103       return NGHTTP2_ERR_CALLBACK_FAILURE;
1104     /* if we receive data for another handle, wake that up */
1105     if(get_transfer(httpc) != data_s)
1106       Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
1107
1108     H2BUGF(infof(data_s, "h2 status: HTTP/2 %03d (easy %p)",
1109                  stream->status_code, data_s));
1110     return 0;
1111   }
1112
1113   /* nghttp2 guarantees that namelen > 0, and :status was already
1114      received, and this is not pseudo-header field . */
1115   /* convert to a HTTP1-style header */
1116   result = Curl_dyn_addn(&stream->header_recvbuf, name, namelen);
1117   if(result)
1118     return NGHTTP2_ERR_CALLBACK_FAILURE;
1119   result = Curl_dyn_addn(&stream->header_recvbuf, STRCONST(": "));
1120   if(result)
1121     return NGHTTP2_ERR_CALLBACK_FAILURE;
1122   result = Curl_dyn_addn(&stream->header_recvbuf, value, valuelen);
1123   if(result)
1124     return NGHTTP2_ERR_CALLBACK_FAILURE;
1125   result = Curl_dyn_addn(&stream->header_recvbuf, STRCONST("\r\n"));
1126   if(result)
1127     return NGHTTP2_ERR_CALLBACK_FAILURE;
1128   /* if we receive data for another handle, wake that up */
1129   if(get_transfer(httpc) != data_s)
1130     Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
1131
1132   H2BUGF(infof(data_s, "h2 header: %.*s: %.*s", namelen, name, valuelen,
1133                value));
1134
1135   return 0; /* 0 is successful */
1136 }
1137
1138 static ssize_t data_source_read_callback(nghttp2_session *session,
1139                                          int32_t stream_id,
1140                                          uint8_t *buf, size_t length,
1141                                          uint32_t *data_flags,
1142                                          nghttp2_data_source *source,
1143                                          void *userp)
1144 {
1145   struct Curl_easy *data_s;
1146   struct HTTP *stream = NULL;
1147   size_t nread;
1148   (void)source;
1149   (void)userp;
1150
1151   if(stream_id) {
1152     /* get the stream from the hash based on Stream ID, stream ID zero is for
1153        connection-oriented stuff */
1154     data_s = nghttp2_session_get_stream_user_data(session, stream_id);
1155     if(!data_s)
1156       /* Receiving a Stream ID not in the hash should not happen, this is an
1157          internal error more than anything else! */
1158       return NGHTTP2_ERR_CALLBACK_FAILURE;
1159
1160     stream = data_s->req.p.http;
1161     if(!stream)
1162       return NGHTTP2_ERR_CALLBACK_FAILURE;
1163   }
1164   else
1165     return NGHTTP2_ERR_INVALID_ARGUMENT;
1166
1167   nread = CURLMIN(stream->upload_len, length);
1168   if(nread > 0) {
1169     memcpy(buf, stream->upload_mem, nread);
1170     stream->upload_mem += nread;
1171     stream->upload_len -= nread;
1172     if(data_s->state.infilesize != -1)
1173       stream->upload_left -= nread;
1174   }
1175
1176   if(stream->upload_left == 0)
1177     *data_flags = NGHTTP2_DATA_FLAG_EOF;
1178   else if(nread == 0)
1179     return NGHTTP2_ERR_DEFERRED;
1180
1181   H2BUGF(infof(data_s, "data_source_read_callback: "
1182                "returns %zu bytes stream %u",
1183                nread, stream_id));
1184
1185   return nread;
1186 }
1187
1188 #if !defined(CURL_DISABLE_VERBOSE_STRINGS)
1189 static int error_callback(nghttp2_session *session,
1190                           const char *msg,
1191                           size_t len,
1192                           void *userp)
1193 {
1194   (void)session;
1195   (void)msg;
1196   (void)len;
1197   (void)userp;
1198   return 0;
1199 }
1200 #endif
1201
1202 static void populate_settings(struct Curl_easy *data,
1203                               struct http_conn *httpc)
1204 {
1205   nghttp2_settings_entry *iv = httpc->local_settings;
1206
1207   iv[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
1208   iv[0].value = Curl_multi_max_concurrent_streams(data->multi);
1209
1210   iv[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
1211   iv[1].value = HTTP2_HUGE_WINDOW_SIZE;
1212
1213   iv[2].settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH;
1214   iv[2].value = data->multi->push_cb != NULL;
1215
1216   httpc->local_settings_num = 3;
1217 }
1218
1219 void Curl_http2_done(struct Curl_easy *data, bool premature)
1220 {
1221   struct HTTP *http = data->req.p.http;
1222   struct http_conn *httpc = &data->conn->proto.httpc;
1223
1224   /* there might be allocated resources done before this got the 'h2' pointer
1225      setup */
1226   Curl_dyn_free(&http->header_recvbuf);
1227   Curl_dyn_free(&http->trailer_recvbuf);
1228   if(http->push_headers) {
1229     /* if they weren't used and then freed before */
1230     for(; http->push_headers_used > 0; --http->push_headers_used) {
1231       free(http->push_headers[http->push_headers_used - 1]);
1232     }
1233     free(http->push_headers);
1234     http->push_headers = NULL;
1235   }
1236
1237   if(!(data->conn->handler->protocol&PROTO_FAMILY_HTTP) ||
1238      !httpc->h2) /* not HTTP/2 ? */
1239     return;
1240
1241   /* do this before the reset handling, as that might clear ->stream_id */
1242   if(http->stream_id == httpc->pause_stream_id) {
1243     H2BUGF(infof(data, "DONE the pause stream (%x)", http->stream_id));
1244     httpc->pause_stream_id = 0;
1245   }
1246   if(premature || (!http->closed && http->stream_id)) {
1247     /* RST_STREAM */
1248     set_transfer(httpc, data); /* set the transfer */
1249     H2BUGF(infof(data, "RST stream %x", http->stream_id));
1250     if(!nghttp2_submit_rst_stream(httpc->h2, NGHTTP2_FLAG_NONE,
1251                                   http->stream_id, NGHTTP2_STREAM_CLOSED))
1252       (void)nghttp2_session_send(httpc->h2);
1253   }
1254
1255   if(data->state.drain)
1256     drained_transfer(data, httpc);
1257
1258   /* -1 means unassigned and 0 means cleared */
1259   if(http->stream_id > 0) {
1260     int rv = nghttp2_session_set_stream_user_data(httpc->h2,
1261                                                   http->stream_id, 0);
1262     if(rv) {
1263       infof(data, "http/2: failed to clear user_data for stream %d",
1264             http->stream_id);
1265       DEBUGASSERT(0);
1266     }
1267     set_transfer(httpc, NULL);
1268     http->stream_id = 0;
1269   }
1270 }
1271
1272 /*
1273  * Initialize nghttp2 for a Curl connection
1274  */
1275 static CURLcode http2_init(struct Curl_easy *data, struct connectdata *conn)
1276 {
1277   if(!conn->proto.httpc.h2) {
1278     int rc;
1279     nghttp2_session_callbacks *callbacks;
1280
1281     conn->proto.httpc.inbuf = malloc(H2_BUFSIZE);
1282     if(!conn->proto.httpc.inbuf)
1283       return CURLE_OUT_OF_MEMORY;
1284
1285     rc = nghttp2_session_callbacks_new(&callbacks);
1286
1287     if(rc) {
1288       failf(data, "Couldn't initialize nghttp2 callbacks");
1289       return CURLE_OUT_OF_MEMORY; /* most likely at least */
1290     }
1291
1292     /* nghttp2_send_callback */
1293     nghttp2_session_callbacks_set_send_callback(callbacks, send_callback);
1294     /* nghttp2_on_frame_recv_callback */
1295     nghttp2_session_callbacks_set_on_frame_recv_callback
1296       (callbacks, on_frame_recv);
1297     /* nghttp2_on_data_chunk_recv_callback */
1298     nghttp2_session_callbacks_set_on_data_chunk_recv_callback
1299       (callbacks, on_data_chunk_recv);
1300     /* nghttp2_on_stream_close_callback */
1301     nghttp2_session_callbacks_set_on_stream_close_callback
1302       (callbacks, on_stream_close);
1303     /* nghttp2_on_begin_headers_callback */
1304     nghttp2_session_callbacks_set_on_begin_headers_callback
1305       (callbacks, on_begin_headers);
1306     /* nghttp2_on_header_callback */
1307     nghttp2_session_callbacks_set_on_header_callback(callbacks, on_header);
1308
1309     nghttp2_session_callbacks_set_error_callback(callbacks, error_callback);
1310
1311     /* The nghttp2 session is not yet setup, do it */
1312     rc = nghttp2_session_client_new(&conn->proto.httpc.h2, callbacks, conn);
1313
1314     nghttp2_session_callbacks_del(callbacks);
1315
1316     if(rc) {
1317       failf(data, "Couldn't initialize nghttp2");
1318       return CURLE_OUT_OF_MEMORY; /* most likely at least */
1319     }
1320   }
1321   return CURLE_OK;
1322 }
1323
1324 /*
1325  * Append headers to ask for a HTTP1.1 to HTTP2 upgrade.
1326  */
1327 CURLcode Curl_http2_request_upgrade(struct dynbuf *req,
1328                                     struct Curl_easy *data)
1329 {
1330   CURLcode result;
1331   ssize_t binlen;
1332   char *base64;
1333   size_t blen;
1334   struct connectdata *conn = data->conn;
1335   struct SingleRequest *k = &data->req;
1336   uint8_t *binsettings = conn->proto.httpc.binsettings;
1337   struct http_conn *httpc = &conn->proto.httpc;
1338
1339   populate_settings(data, httpc);
1340
1341   /* this returns number of bytes it wrote */
1342   binlen = nghttp2_pack_settings_payload(binsettings, H2_BINSETTINGS_LEN,
1343                                          httpc->local_settings,
1344                                          httpc->local_settings_num);
1345   if(binlen <= 0) {
1346     failf(data, "nghttp2 unexpectedly failed on pack_settings_payload");
1347     Curl_dyn_free(req);
1348     return CURLE_FAILED_INIT;
1349   }
1350   conn->proto.httpc.binlen = binlen;
1351
1352   result = Curl_base64url_encode((const char *)binsettings, binlen,
1353                                  &base64, &blen);
1354   if(result) {
1355     Curl_dyn_free(req);
1356     return result;
1357   }
1358
1359   result = Curl_dyn_addf(req,
1360                          "Connection: Upgrade, HTTP2-Settings\r\n"
1361                          "Upgrade: %s\r\n"
1362                          "HTTP2-Settings: %s\r\n",
1363                          NGHTTP2_CLEARTEXT_PROTO_VERSION_ID, base64);
1364   free(base64);
1365
1366   k->upgr101 = UPGR101_REQUESTED;
1367
1368   return result;
1369 }
1370
1371 /*
1372  * Returns nonzero if current HTTP/2 session should be closed.
1373  */
1374 static int should_close_session(struct http_conn *httpc)
1375 {
1376   return httpc->drain_total == 0 && !nghttp2_session_want_read(httpc->h2) &&
1377     !nghttp2_session_want_write(httpc->h2);
1378 }
1379
1380 /*
1381  * h2_process_pending_input() processes pending input left in
1382  * httpc->inbuf.  Then, call h2_session_send() to send pending data.
1383  * This function returns 0 if it succeeds, or -1 and error code will
1384  * be assigned to *err.
1385  */
1386 static int h2_process_pending_input(struct Curl_easy *data,
1387                                     struct http_conn *httpc,
1388                                     CURLcode *err)
1389 {
1390   ssize_t nread;
1391   char *inbuf;
1392   ssize_t rv;
1393
1394   nread = httpc->inbuflen - httpc->nread_inbuf;
1395   inbuf = httpc->inbuf + httpc->nread_inbuf;
1396
1397   set_transfer(httpc, data); /* set the transfer */
1398   rv = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)inbuf, nread);
1399   if(rv < 0) {
1400     failf(data,
1401           "h2_process_pending_input: nghttp2_session_mem_recv() returned "
1402           "%zd:%s", rv, nghttp2_strerror((int)rv));
1403     *err = CURLE_RECV_ERROR;
1404     return -1;
1405   }
1406
1407   if(nread == rv) {
1408     H2BUGF(infof(data,
1409                  "h2_process_pending_input: All data in connection buffer "
1410                  "processed"));
1411     httpc->inbuflen = 0;
1412     httpc->nread_inbuf = 0;
1413   }
1414   else {
1415     httpc->nread_inbuf += rv;
1416     H2BUGF(infof(data,
1417                  "h2_process_pending_input: %zu bytes left in connection "
1418                  "buffer",
1419                  httpc->inbuflen - httpc->nread_inbuf));
1420   }
1421
1422   rv = h2_session_send(data, httpc->h2);
1423   if(rv) {
1424     *err = CURLE_SEND_ERROR;
1425     return -1;
1426   }
1427
1428   if(nghttp2_session_check_request_allowed(httpc->h2) == 0) {
1429     /* No more requests are allowed in the current session, so
1430        the connection may not be reused. This is set when a
1431        GOAWAY frame has been received or when the limit of stream
1432        identifiers has been reached. */
1433     connclose(data->conn, "http/2: No new requests allowed");
1434   }
1435
1436   if(should_close_session(httpc)) {
1437     struct HTTP *stream = data->req.p.http;
1438     H2BUGF(infof(data,
1439                  "h2_process_pending_input: nothing to do in this session"));
1440     if(stream->error)
1441       *err = CURLE_HTTP2;
1442     else {
1443       /* not an error per se, but should still close the connection */
1444       connclose(data->conn, "GOAWAY received");
1445       *err = CURLE_OK;
1446     }
1447     return -1;
1448   }
1449   return 0;
1450 }
1451
1452 /*
1453  * Called from transfer.c:done_sending when we stop uploading.
1454  */
1455 CURLcode Curl_http2_done_sending(struct Curl_easy *data,
1456                                  struct connectdata *conn)
1457 {
1458   CURLcode result = CURLE_OK;
1459
1460   if((conn->handler == &Curl_handler_http2_ssl) ||
1461      (conn->handler == &Curl_handler_http2)) {
1462     /* make sure this is only attempted for HTTP/2 transfers */
1463     struct HTTP *stream = data->req.p.http;
1464     struct http_conn *httpc = &conn->proto.httpc;
1465     nghttp2_session *h2 = httpc->h2;
1466
1467     if(stream->upload_left) {
1468       /* If the stream still thinks there's data left to upload. */
1469
1470       stream->upload_left = 0; /* DONE! */
1471
1472       /* resume sending here to trigger the callback to get called again so
1473          that it can signal EOF to nghttp2 */
1474       (void)nghttp2_session_resume_data(h2, stream->stream_id);
1475       (void)h2_process_pending_input(data, httpc, &result);
1476     }
1477
1478     /* If nghttp2 still has pending frames unsent */
1479     if(nghttp2_session_want_write(h2)) {
1480       struct SingleRequest *k = &data->req;
1481       int rv;
1482
1483       H2BUGF(infof(data, "HTTP/2 still wants to send data (easy %p)", data));
1484
1485       /* and attempt to send the pending frames */
1486       rv = h2_session_send(data, h2);
1487       if(rv)
1488         result = CURLE_SEND_ERROR;
1489
1490       if(nghttp2_session_want_write(h2)) {
1491          /* re-set KEEP_SEND to make sure we are called again */
1492          k->keepon |= KEEP_SEND;
1493       }
1494     }
1495   }
1496   return result;
1497 }
1498
1499 static ssize_t http2_handle_stream_close(struct connectdata *conn,
1500                                          struct Curl_easy *data,
1501                                          struct HTTP *stream, CURLcode *err)
1502 {
1503   struct http_conn *httpc = &conn->proto.httpc;
1504
1505   if(httpc->pause_stream_id == stream->stream_id) {
1506     httpc->pause_stream_id = 0;
1507   }
1508
1509   drained_transfer(data, httpc);
1510
1511   if(httpc->pause_stream_id == 0) {
1512     if(h2_process_pending_input(data, httpc, err) != 0) {
1513       return -1;
1514     }
1515   }
1516
1517   DEBUGASSERT(data->state.drain == 0);
1518
1519   /* Reset to FALSE to prevent infinite loop in readwrite_data function. */
1520   stream->closed = FALSE;
1521   if(stream->error == NGHTTP2_REFUSED_STREAM) {
1522     H2BUGF(infof(data, "REFUSED_STREAM (%d), try again on a new connection",
1523                  stream->stream_id));
1524     connclose(conn, "REFUSED_STREAM"); /* don't use this anymore */
1525     data->state.refused_stream = TRUE;
1526     *err = CURLE_RECV_ERROR; /* trigger Curl_retry_request() later */
1527     return -1;
1528   }
1529   else if(stream->error != NGHTTP2_NO_ERROR) {
1530     failf(data, "HTTP/2 stream %d was not closed cleanly: %s (err %u)",
1531           stream->stream_id, nghttp2_http2_strerror(stream->error),
1532           stream->error);
1533     *err = CURLE_HTTP2_STREAM;
1534     return -1;
1535   }
1536
1537   if(!stream->bodystarted) {
1538     failf(data, "HTTP/2 stream %d was closed cleanly, but before getting "
1539           " all response header fields, treated as error",
1540           stream->stream_id);
1541     *err = CURLE_HTTP2_STREAM;
1542     return -1;
1543   }
1544
1545   if(Curl_dyn_len(&stream->trailer_recvbuf)) {
1546     char *trailp = Curl_dyn_ptr(&stream->trailer_recvbuf);
1547     char *lf;
1548
1549     do {
1550       size_t len = 0;
1551       CURLcode result;
1552       /* each trailer line ends with a newline */
1553       lf = strchr(trailp, '\n');
1554       if(!lf)
1555         break;
1556       len = lf + 1 - trailp;
1557
1558       Curl_debug(data, CURLINFO_HEADER_IN, trailp, len);
1559       /* pass the trailers one by one to the callback */
1560       result = Curl_client_write(data, CLIENTWRITE_HEADER, trailp, len);
1561       if(result) {
1562         *err = result;
1563         return -1;
1564       }
1565       trailp = ++lf;
1566     } while(lf);
1567   }
1568
1569   stream->close_handled = TRUE;
1570
1571   H2BUGF(infof(data, "http2_recv returns 0, http2_handle_stream_close"));
1572   return 0;
1573 }
1574
1575 /*
1576  * h2_pri_spec() fills in the pri_spec struct, used by nghttp2 to send weight
1577  * and dependency to the peer. It also stores the updated values in the state
1578  * struct.
1579  */
1580
1581 static void h2_pri_spec(struct Curl_easy *data,
1582                         nghttp2_priority_spec *pri_spec)
1583 {
1584   struct HTTP *depstream = (data->set.stream_depends_on?
1585                             data->set.stream_depends_on->req.p.http:NULL);
1586   int32_t depstream_id = depstream? depstream->stream_id:0;
1587   nghttp2_priority_spec_init(pri_spec, depstream_id, data->set.stream_weight,
1588                              data->set.stream_depends_e);
1589   data->state.stream_weight = data->set.stream_weight;
1590   data->state.stream_depends_e = data->set.stream_depends_e;
1591   data->state.stream_depends_on = data->set.stream_depends_on;
1592 }
1593
1594 /*
1595  * h2_session_send() checks if there's been an update in the priority /
1596  * dependency settings and if so it submits a PRIORITY frame with the updated
1597  * info.
1598  */
1599 static int h2_session_send(struct Curl_easy *data,
1600                            nghttp2_session *h2)
1601 {
1602   struct HTTP *stream = data->req.p.http;
1603   struct http_conn *httpc = &data->conn->proto.httpc;
1604   set_transfer(httpc, data);
1605   if((data->set.stream_weight != data->state.stream_weight) ||
1606      (data->set.stream_depends_e != data->state.stream_depends_e) ||
1607      (data->set.stream_depends_on != data->state.stream_depends_on) ) {
1608     /* send new weight and/or dependency */
1609     nghttp2_priority_spec pri_spec;
1610     int rv;
1611
1612     h2_pri_spec(data, &pri_spec);
1613
1614     H2BUGF(infof(data, "Queuing PRIORITY on stream %u (easy %p)",
1615                  stream->stream_id, data));
1616     DEBUGASSERT(stream->stream_id != -1);
1617     rv = nghttp2_submit_priority(h2, NGHTTP2_FLAG_NONE, stream->stream_id,
1618                                  &pri_spec);
1619     if(rv)
1620       return rv;
1621   }
1622
1623   return nghttp2_session_send(h2);
1624 }
1625
1626 static ssize_t http2_recv(struct Curl_easy *data, int sockindex,
1627                           char *mem, size_t len, CURLcode *err)
1628 {
1629   ssize_t nread;
1630   struct connectdata *conn = data->conn;
1631   struct http_conn *httpc = &conn->proto.httpc;
1632   struct HTTP *stream = data->req.p.http;
1633
1634   (void)sockindex; /* we always do HTTP2 on sockindex 0 */
1635
1636   if(should_close_session(httpc)) {
1637     H2BUGF(infof(data,
1638                  "http2_recv: nothing to do in this session"));
1639     if(conn->bits.close) {
1640       /* already marked for closure, return OK and we're done */
1641       *err = CURLE_OK;
1642       return 0;
1643     }
1644     *err = CURLE_HTTP2;
1645     return -1;
1646   }
1647
1648   /* Nullify here because we call nghttp2_session_send() and they
1649      might refer to the old buffer. */
1650   stream->upload_mem = NULL;
1651   stream->upload_len = 0;
1652
1653   /*
1654    * At this point 'stream' is just in the Curl_easy the connection
1655    * identifies as its owner at this time.
1656    */
1657
1658   if(stream->bodystarted &&
1659      stream->nread_header_recvbuf < Curl_dyn_len(&stream->header_recvbuf)) {
1660     /* If there is header data pending for this stream to return, do that */
1661     size_t left =
1662       Curl_dyn_len(&stream->header_recvbuf) - stream->nread_header_recvbuf;
1663     size_t ncopy = CURLMIN(len, left);
1664     memcpy(mem, Curl_dyn_ptr(&stream->header_recvbuf) +
1665            stream->nread_header_recvbuf, ncopy);
1666     stream->nread_header_recvbuf += ncopy;
1667
1668     H2BUGF(infof(data, "http2_recv: Got %d bytes from header_recvbuf",
1669                  (int)ncopy));
1670     return ncopy;
1671   }
1672
1673   H2BUGF(infof(data, "http2_recv: easy %p (stream %u) win %u/%u",
1674                data, stream->stream_id,
1675                nghttp2_session_get_local_window_size(httpc->h2),
1676                nghttp2_session_get_stream_local_window_size(httpc->h2,
1677                                                             stream->stream_id)
1678            ));
1679
1680   if((data->state.drain) && stream->memlen) {
1681     H2BUGF(infof(data, "http2_recv: DRAIN %zu bytes stream %u (%p => %p)",
1682                  stream->memlen, stream->stream_id,
1683                  stream->mem, mem));
1684     if(mem != stream->mem) {
1685       /* if we didn't get the same buffer this time, we must move the data to
1686          the beginning */
1687       memmove(mem, stream->mem, stream->memlen);
1688       stream->len = len - stream->memlen;
1689       stream->mem = mem;
1690     }
1691     if(httpc->pause_stream_id == stream->stream_id && !stream->pausedata) {
1692       /* We have paused nghttp2, but we have no pause data (see
1693          on_data_chunk_recv). */
1694       httpc->pause_stream_id = 0;
1695       if(h2_process_pending_input(data, httpc, err) != 0) {
1696         return -1;
1697       }
1698     }
1699   }
1700   else if(stream->pausedata) {
1701     DEBUGASSERT(httpc->pause_stream_id == stream->stream_id);
1702     nread = CURLMIN(len, stream->pauselen);
1703     memcpy(mem, stream->pausedata, nread);
1704
1705     stream->pausedata += nread;
1706     stream->pauselen -= nread;
1707
1708     if(stream->pauselen == 0) {
1709       H2BUGF(infof(data, "Unpaused by stream %u", stream->stream_id));
1710       DEBUGASSERT(httpc->pause_stream_id == stream->stream_id);
1711       httpc->pause_stream_id = 0;
1712
1713       stream->pausedata = NULL;
1714       stream->pauselen = 0;
1715
1716       /* When NGHTTP2_ERR_PAUSE is returned from
1717          data_source_read_callback, we might not process DATA frame
1718          fully.  Calling nghttp2_session_mem_recv() again will
1719          continue to process DATA frame, but if there is no incoming
1720          frames, then we have to call it again with 0-length data.
1721          Without this, on_stream_close callback will not be called,
1722          and stream could be hanged. */
1723       if(h2_process_pending_input(data, httpc, err) != 0) {
1724         return -1;
1725       }
1726     }
1727     H2BUGF(infof(data, "http2_recv: returns unpaused %zd bytes on stream %u",
1728                  nread, stream->stream_id));
1729     return nread;
1730   }
1731   else if(httpc->pause_stream_id) {
1732     /* If a stream paused nghttp2_session_mem_recv previously, and has
1733        not processed all data, it still refers to the buffer in
1734        nghttp2_session.  If we call nghttp2_session_mem_recv(), we may
1735        overwrite that buffer.  To avoid that situation, just return
1736        here with CURLE_AGAIN.  This could be busy loop since data in
1737        socket is not read.  But it seems that usually streams are
1738        notified with its drain property, and socket is read again
1739        quickly. */
1740     if(stream->closed)
1741       /* closed overrides paused */
1742       return 0;
1743     H2BUGF(infof(data, "stream %x is paused, pause id: %x",
1744                  stream->stream_id, httpc->pause_stream_id));
1745     *err = CURLE_AGAIN;
1746     return -1;
1747   }
1748   else {
1749     /* remember where to store incoming data for this stream and how big the
1750        buffer is */
1751     stream->mem = mem;
1752     stream->len = len;
1753     stream->memlen = 0;
1754
1755     if(httpc->inbuflen == 0) {
1756       nread = ((Curl_recv *)httpc->recv_underlying)(
1757         data, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, err);
1758
1759       if(nread == -1) {
1760         if(*err != CURLE_AGAIN)
1761           failf(data, "Failed receiving HTTP2 data");
1762         else if(stream->closed)
1763           /* received when the stream was already closed! */
1764           return http2_handle_stream_close(conn, data, stream, err);
1765
1766         return -1;
1767       }
1768
1769       if(nread == 0) {
1770         if(!stream->closed) {
1771           /* This will happen when the server or proxy server is SIGKILLed
1772              during data transfer. We should emit an error since our data
1773              received may be incomplete. */
1774           failf(data, "HTTP/2 stream %d was not closed cleanly before"
1775                 " end of the underlying stream",
1776                 stream->stream_id);
1777           *err = CURLE_HTTP2_STREAM;
1778           return -1;
1779         }
1780
1781         H2BUGF(infof(data, "end of stream"));
1782         *err = CURLE_OK;
1783         return 0;
1784       }
1785
1786       H2BUGF(infof(data, "nread=%zd", nread));
1787
1788       httpc->inbuflen = nread;
1789
1790       DEBUGASSERT(httpc->nread_inbuf == 0);
1791     }
1792     else {
1793       nread = httpc->inbuflen - httpc->nread_inbuf;
1794       (void)nread;  /* silence warning, used in debug */
1795       H2BUGF(infof(data, "Use data left in connection buffer, nread=%zd",
1796                    nread));
1797     }
1798
1799     if(h2_process_pending_input(data, httpc, err))
1800       return -1;
1801   }
1802   if(stream->memlen) {
1803     ssize_t retlen = stream->memlen;
1804     H2BUGF(infof(data, "http2_recv: returns %zd for stream %u",
1805                  retlen, stream->stream_id));
1806     stream->memlen = 0;
1807
1808     if(httpc->pause_stream_id == stream->stream_id) {
1809       /* data for this stream is returned now, but this stream caused a pause
1810          already so we need it called again asap */
1811       H2BUGF(infof(data, "Data returned for PAUSED stream %u",
1812                    stream->stream_id));
1813     }
1814     else if(!stream->closed) {
1815       drained_transfer(data, httpc);
1816     }
1817     else
1818       /* this stream is closed, trigger a another read ASAP to detect that */
1819       Curl_expire(data, 0, EXPIRE_RUN_NOW);
1820
1821     return retlen;
1822   }
1823   if(stream->closed)
1824     return http2_handle_stream_close(conn, data, stream, err);
1825   *err = CURLE_AGAIN;
1826   H2BUGF(infof(data, "http2_recv returns AGAIN for stream %u",
1827                stream->stream_id));
1828   return -1;
1829 }
1830
1831 static ssize_t http2_send(struct Curl_easy *data, int sockindex,
1832                           const void *mem, size_t len, CURLcode *err)
1833 {
1834   /*
1835    * Currently, we send request in this function, but this function is also
1836    * used to send request body. It would be nice to add dedicated function for
1837    * request.
1838    */
1839   int rv;
1840   struct connectdata *conn = data->conn;
1841   struct http_conn *httpc = &conn->proto.httpc;
1842   struct HTTP *stream = data->req.p.http;
1843   nghttp2_nv *nva = NULL;
1844   size_t nheader;
1845   nghttp2_data_provider data_prd;
1846   int32_t stream_id;
1847   nghttp2_session *h2 = httpc->h2;
1848   nghttp2_priority_spec pri_spec;
1849   CURLcode result;
1850   struct h2h3req *hreq;
1851
1852   (void)sockindex;
1853
1854   H2BUGF(infof(data, "http2_send len=%zu", len));
1855
1856   if(stream->stream_id != -1) {
1857     if(stream->close_handled) {
1858       infof(data, "stream %d closed", stream->stream_id);
1859       *err = CURLE_HTTP2_STREAM;
1860       return -1;
1861     }
1862     else if(stream->closed) {
1863       return http2_handle_stream_close(conn, data, stream, err);
1864     }
1865     /* If stream_id != -1, we have dispatched request HEADERS, and now
1866        are going to send or sending request body in DATA frame */
1867     stream->upload_mem = mem;
1868     stream->upload_len = len;
1869     rv = nghttp2_session_resume_data(h2, stream->stream_id);
1870     if(nghttp2_is_fatal(rv)) {
1871       *err = CURLE_SEND_ERROR;
1872       return -1;
1873     }
1874     rv = h2_session_send(data, h2);
1875     if(nghttp2_is_fatal(rv)) {
1876       *err = CURLE_SEND_ERROR;
1877       return -1;
1878     }
1879     len -= stream->upload_len;
1880
1881     /* Nullify here because we call nghttp2_session_send() and they
1882        might refer to the old buffer. */
1883     stream->upload_mem = NULL;
1884     stream->upload_len = 0;
1885
1886     if(should_close_session(httpc)) {
1887       H2BUGF(infof(data, "http2_send: nothing to do in this session"));
1888       *err = CURLE_HTTP2;
1889       return -1;
1890     }
1891
1892     if(stream->upload_left) {
1893       /* we are sure that we have more data to send here.  Calling the
1894          following API will make nghttp2_session_want_write() return
1895          nonzero if remote window allows it, which then libcurl checks
1896          socket is writable or not.  See http2_perform_getsock(). */
1897       nghttp2_session_resume_data(h2, stream->stream_id);
1898     }
1899
1900 #ifdef DEBUG_HTTP2
1901     if(!len) {
1902       infof(data, "http2_send: easy %p (stream %u) win %u/%u",
1903             data, stream->stream_id,
1904             nghttp2_session_get_remote_window_size(httpc->h2),
1905             nghttp2_session_get_stream_remote_window_size(httpc->h2,
1906                                                           stream->stream_id)
1907         );
1908
1909     }
1910     infof(data, "http2_send returns %zu for stream %u", len,
1911           stream->stream_id);
1912 #endif
1913     return len;
1914   }
1915
1916   result = Curl_pseudo_headers(data, mem, len, &hreq);
1917   if(result) {
1918     *err = result;
1919     return -1;
1920   }
1921   nheader = hreq->entries;
1922
1923   nva = malloc(sizeof(nghttp2_nv) * nheader);
1924   if(!nva) {
1925     Curl_pseudo_free(hreq);
1926     *err = CURLE_OUT_OF_MEMORY;
1927     return -1;
1928   }
1929   else {
1930     unsigned int i;
1931     for(i = 0; i < nheader; i++) {
1932       nva[i].name = (unsigned char *)hreq->header[i].name;
1933       nva[i].namelen = hreq->header[i].namelen;
1934       nva[i].value = (unsigned char *)hreq->header[i].value;
1935       nva[i].valuelen = hreq->header[i].valuelen;
1936       nva[i].flags = NGHTTP2_NV_FLAG_NONE;
1937     }
1938     Curl_pseudo_free(hreq);
1939   }
1940
1941   h2_pri_spec(data, &pri_spec);
1942
1943   H2BUGF(infof(data, "http2_send request allowed %d (easy handle %p)",
1944                nghttp2_session_check_request_allowed(h2), (void *)data));
1945
1946   switch(data->state.httpreq) {
1947   case HTTPREQ_POST:
1948   case HTTPREQ_POST_FORM:
1949   case HTTPREQ_POST_MIME:
1950   case HTTPREQ_PUT:
1951     if(data->state.infilesize != -1)
1952       stream->upload_left = data->state.infilesize;
1953     else
1954       /* data sending without specifying the data amount up front */
1955       stream->upload_left = -1; /* unknown, but not zero */
1956
1957     data_prd.read_callback = data_source_read_callback;
1958     data_prd.source.ptr = NULL;
1959     stream_id = nghttp2_submit_request(h2, &pri_spec, nva, nheader,
1960                                        &data_prd, data);
1961     break;
1962   default:
1963     stream_id = nghttp2_submit_request(h2, &pri_spec, nva, nheader,
1964                                        NULL, data);
1965   }
1966
1967   Curl_safefree(nva);
1968
1969   if(stream_id < 0) {
1970     H2BUGF(infof(data,
1971                  "http2_send() nghttp2_submit_request error (%s)%d",
1972                  nghttp2_strerror(stream_id), stream_id));
1973     *err = CURLE_SEND_ERROR;
1974     return -1;
1975   }
1976
1977   infof(data, "Using Stream ID: %x (easy handle %p)",
1978         stream_id, (void *)data);
1979   stream->stream_id = stream_id;
1980
1981   rv = h2_session_send(data, h2);
1982   if(rv) {
1983     H2BUGF(infof(data,
1984                  "http2_send() nghttp2_session_send error (%s)%d",
1985                  nghttp2_strerror(rv), rv));
1986
1987     *err = CURLE_SEND_ERROR;
1988     return -1;
1989   }
1990
1991   if(should_close_session(httpc)) {
1992     H2BUGF(infof(data, "http2_send: nothing to do in this session"));
1993     *err = CURLE_HTTP2;
1994     return -1;
1995   }
1996
1997   /* If whole HEADERS frame was sent off to the underlying socket, the nghttp2
1998      library calls data_source_read_callback. But only it found that no data
1999      available, so it deferred the DATA transmission. Which means that
2000      nghttp2_session_want_write() returns 0 on http2_perform_getsock(), which
2001      results that no writable socket check is performed. To workaround this,
2002      we issue nghttp2_session_resume_data() here to bring back DATA
2003      transmission from deferred state. */
2004   nghttp2_session_resume_data(h2, stream->stream_id);
2005
2006   return len;
2007 }
2008
2009 CURLcode Curl_http2_setup(struct Curl_easy *data,
2010                           struct connectdata *conn)
2011 {
2012   CURLcode result;
2013   struct http_conn *httpc = &conn->proto.httpc;
2014   struct HTTP *stream = data->req.p.http;
2015
2016   DEBUGASSERT(data->state.buffer);
2017
2018   stream->stream_id = -1;
2019
2020   Curl_dyn_init(&stream->header_recvbuf, DYN_H2_HEADERS);
2021   Curl_dyn_init(&stream->trailer_recvbuf, DYN_H2_TRAILERS);
2022
2023   stream->upload_left = 0;
2024   stream->upload_mem = NULL;
2025   stream->upload_len = 0;
2026   stream->mem = data->state.buffer;
2027   stream->len = data->set.buffer_size;
2028
2029   multi_connchanged(data->multi);
2030   /* below this point only connection related inits are done, which only needs
2031      to be done once per connection */
2032
2033   if((conn->handler == &Curl_handler_http2_ssl) ||
2034      (conn->handler == &Curl_handler_http2))
2035     return CURLE_OK; /* already done */
2036
2037   if(conn->handler->flags & PROTOPT_SSL)
2038     conn->handler = &Curl_handler_http2_ssl;
2039   else
2040     conn->handler = &Curl_handler_http2;
2041
2042   result = http2_init(data, conn);
2043   if(result) {
2044     Curl_dyn_free(&stream->header_recvbuf);
2045     return result;
2046   }
2047
2048   infof(data, "Using HTTP2, server supports multiplexing");
2049
2050   conn->bits.multiplex = TRUE; /* at least potentially multiplexed */
2051   conn->httpversion = 20;
2052   conn->bundle->multiuse = BUNDLE_MULTIPLEX;
2053
2054   httpc->inbuflen = 0;
2055   httpc->nread_inbuf = 0;
2056
2057   httpc->pause_stream_id = 0;
2058   httpc->drain_total = 0;
2059
2060   return CURLE_OK;
2061 }
2062
2063 CURLcode Curl_http2_switched(struct Curl_easy *data,
2064                              const char *mem, size_t nread)
2065 {
2066   CURLcode result;
2067   struct connectdata *conn = data->conn;
2068   struct http_conn *httpc = &conn->proto.httpc;
2069   int rv;
2070   struct HTTP *stream = data->req.p.http;
2071
2072   result = Curl_http2_setup(data, conn);
2073   if(result)
2074     return result;
2075
2076   httpc->recv_underlying = conn->recv[FIRSTSOCKET];
2077   httpc->send_underlying = conn->send[FIRSTSOCKET];
2078   conn->recv[FIRSTSOCKET] = http2_recv;
2079   conn->send[FIRSTSOCKET] = http2_send;
2080
2081   if(data->req.upgr101 == UPGR101_RECEIVED) {
2082     /* stream 1 is opened implicitly on upgrade */
2083     stream->stream_id = 1;
2084     /* queue SETTINGS frame (again) */
2085     rv = nghttp2_session_upgrade2(httpc->h2, httpc->binsettings, httpc->binlen,
2086                                   data->state.httpreq == HTTPREQ_HEAD, NULL);
2087     if(rv) {
2088       failf(data, "nghttp2_session_upgrade2() failed: %s(%d)",
2089             nghttp2_strerror(rv), rv);
2090       return CURLE_HTTP2;
2091     }
2092
2093     rv = nghttp2_session_set_stream_user_data(httpc->h2,
2094                                               stream->stream_id,
2095                                               data);
2096     if(rv) {
2097       infof(data, "http/2: failed to set user_data for stream %d",
2098             stream->stream_id);
2099       DEBUGASSERT(0);
2100     }
2101   }
2102   else {
2103     populate_settings(data, httpc);
2104
2105     /* stream ID is unknown at this point */
2106     stream->stream_id = -1;
2107     rv = nghttp2_submit_settings(httpc->h2, NGHTTP2_FLAG_NONE,
2108                                  httpc->local_settings,
2109                                  httpc->local_settings_num);
2110     if(rv) {
2111       failf(data, "nghttp2_submit_settings() failed: %s(%d)",
2112             nghttp2_strerror(rv), rv);
2113       return CURLE_HTTP2;
2114     }
2115   }
2116
2117   rv = nghttp2_session_set_local_window_size(httpc->h2, NGHTTP2_FLAG_NONE, 0,
2118                                              HTTP2_HUGE_WINDOW_SIZE);
2119   if(rv) {
2120     failf(data, "nghttp2_session_set_local_window_size() failed: %s(%d)",
2121           nghttp2_strerror(rv), rv);
2122     return CURLE_HTTP2;
2123   }
2124
2125   /* we are going to copy mem to httpc->inbuf.  This is required since
2126      mem is part of buffer pointed by stream->mem, and callbacks
2127      called by nghttp2_session_mem_recv() will write stream specific
2128      data into stream->mem, overwriting data already there. */
2129   if(H2_BUFSIZE < nread) {
2130     failf(data, "connection buffer size is too small to store data following "
2131           "HTTP Upgrade response header: buflen=%d, datalen=%zu",
2132           H2_BUFSIZE, nread);
2133     return CURLE_HTTP2;
2134   }
2135
2136   infof(data, "Copying HTTP/2 data in stream buffer to connection buffer"
2137         " after upgrade: len=%zu",
2138         nread);
2139
2140   if(nread)
2141     memcpy(httpc->inbuf, mem, nread);
2142
2143   httpc->inbuflen = nread;
2144
2145   DEBUGASSERT(httpc->nread_inbuf == 0);
2146
2147   if(-1 == h2_process_pending_input(data, httpc, &result))
2148     return CURLE_HTTP2;
2149
2150   return CURLE_OK;
2151 }
2152
2153 CURLcode Curl_http2_stream_pause(struct Curl_easy *data, bool pause)
2154 {
2155   DEBUGASSERT(data);
2156   DEBUGASSERT(data->conn);
2157   /* if it isn't HTTP/2, we're done */
2158   if(!(data->conn->handler->protocol & PROTO_FAMILY_HTTP) ||
2159      !data->conn->proto.httpc.h2)
2160     return CURLE_OK;
2161 #ifdef NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE
2162   else {
2163     struct HTTP *stream = data->req.p.http;
2164     struct http_conn *httpc = &data->conn->proto.httpc;
2165     uint32_t window = !pause * HTTP2_HUGE_WINDOW_SIZE;
2166     int rv = nghttp2_session_set_local_window_size(httpc->h2,
2167                                                    NGHTTP2_FLAG_NONE,
2168                                                    stream->stream_id,
2169                                                    window);
2170     if(rv) {
2171       failf(data, "nghttp2_session_set_local_window_size() failed: %s(%d)",
2172             nghttp2_strerror(rv), rv);
2173       return CURLE_HTTP2;
2174     }
2175
2176     /* make sure the window update gets sent */
2177     rv = h2_session_send(data, httpc->h2);
2178     if(rv)
2179       return CURLE_SEND_ERROR;
2180
2181     DEBUGF(infof(data, "Set HTTP/2 window size to %u for stream %u",
2182                  window, stream->stream_id));
2183
2184 #ifdef DEBUGBUILD
2185     {
2186       /* read out the stream local window again */
2187       uint32_t window2 =
2188         nghttp2_session_get_stream_local_window_size(httpc->h2,
2189                                                      stream->stream_id);
2190       DEBUGF(infof(data, "HTTP/2 window size is now %u for stream %u",
2191                    window2, stream->stream_id));
2192     }
2193 #endif
2194   }
2195 #endif
2196   return CURLE_OK;
2197 }
2198
2199 CURLcode Curl_http2_add_child(struct Curl_easy *parent,
2200                               struct Curl_easy *child,
2201                               bool exclusive)
2202 {
2203   if(parent) {
2204     struct Curl_http2_dep **tail;
2205     struct Curl_http2_dep *dep = calloc(1, sizeof(struct Curl_http2_dep));
2206     if(!dep)
2207       return CURLE_OUT_OF_MEMORY;
2208     dep->data = child;
2209
2210     if(parent->set.stream_dependents && exclusive) {
2211       struct Curl_http2_dep *node = parent->set.stream_dependents;
2212       while(node) {
2213         node->data->set.stream_depends_on = child;
2214         node = node->next;
2215       }
2216
2217       tail = &child->set.stream_dependents;
2218       while(*tail)
2219         tail = &(*tail)->next;
2220
2221       DEBUGASSERT(!*tail);
2222       *tail = parent->set.stream_dependents;
2223       parent->set.stream_dependents = 0;
2224     }
2225
2226     tail = &parent->set.stream_dependents;
2227     while(*tail) {
2228       (*tail)->data->set.stream_depends_e = FALSE;
2229       tail = &(*tail)->next;
2230     }
2231
2232     DEBUGASSERT(!*tail);
2233     *tail = dep;
2234   }
2235
2236   child->set.stream_depends_on = parent;
2237   child->set.stream_depends_e = exclusive;
2238   return CURLE_OK;
2239 }
2240
2241 void Curl_http2_remove_child(struct Curl_easy *parent, struct Curl_easy *child)
2242 {
2243   struct Curl_http2_dep *last = 0;
2244   struct Curl_http2_dep *data = parent->set.stream_dependents;
2245   DEBUGASSERT(child->set.stream_depends_on == parent);
2246
2247   while(data && data->data != child) {
2248     last = data;
2249     data = data->next;
2250   }
2251
2252   DEBUGASSERT(data);
2253
2254   if(data) {
2255     if(last) {
2256       last->next = data->next;
2257     }
2258     else {
2259       parent->set.stream_dependents = data->next;
2260     }
2261     free(data);
2262   }
2263
2264   child->set.stream_depends_on = 0;
2265   child->set.stream_depends_e = FALSE;
2266 }
2267
2268 void Curl_http2_cleanup_dependencies(struct Curl_easy *data)
2269 {
2270   while(data->set.stream_dependents) {
2271     struct Curl_easy *tmp = data->set.stream_dependents->data;
2272     Curl_http2_remove_child(data, tmp);
2273     if(data->set.stream_depends_on)
2274       Curl_http2_add_child(data->set.stream_depends_on, tmp, FALSE);
2275   }
2276
2277   if(data->set.stream_depends_on)
2278     Curl_http2_remove_child(data->set.stream_depends_on, data);
2279 }
2280
2281 /* Only call this function for a transfer that already got a HTTP/2
2282    CURLE_HTTP2_STREAM error! */
2283 bool Curl_h2_http_1_1_error(struct Curl_easy *data)
2284 {
2285   struct HTTP *stream = data->req.p.http;
2286   return (stream->error == NGHTTP2_HTTP_1_1_REQUIRED);
2287 }
2288
2289 #else /* !USE_NGHTTP2 */
2290
2291 /* Satisfy external references even if http2 is not compiled in. */
2292 #include <curl/curl.h>
2293
2294 char *curl_pushheader_bynum(struct curl_pushheaders *h, size_t num)
2295 {
2296   (void) h;
2297   (void) num;
2298   return NULL;
2299 }
2300
2301 char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header)
2302 {
2303   (void) h;
2304   (void) header;
2305   return NULL;
2306 }
2307
2308 #endif /* USE_NGHTTP2 */