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