http2.c 71 KB

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