hpack.c 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478
  1. /*
  2. * libwebsockets - small server side websockets and web server implementation
  3. *
  4. * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to
  8. * deal in the Software without restriction, including without limitation the
  9. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  10. * sell copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  22. * IN THE SOFTWARE.
  23. */
  24. #include "private-lib-core.h"
  25. /*
  26. * Official static header table for HPACK
  27. * +-------+-----------------------------+---------------+
  28. | 1 | :authority | |
  29. | 2 | :method | GET |
  30. | 3 | :method | POST |
  31. | 4 | :path | / |
  32. | 5 | :path | /index.html |
  33. | 6 | :scheme | http |
  34. | 7 | :scheme | https |
  35. | 8 | :status | 200 |
  36. | 9 | :status | 204 |
  37. | 10 | :status | 206 |
  38. | 11 | :status | 304 |
  39. | 12 | :status | 400 |
  40. | 13 | :status | 404 |
  41. | 14 | :status | 500 |
  42. | 15 | accept-charset | |
  43. | 16 | accept-encoding | gzip, deflate |
  44. | 17 | accept-language | |
  45. | 18 | accept-ranges | |
  46. | 19 | accept | |
  47. | 20 | access-control-allow-origin | |
  48. | 21 | age | |
  49. | 22 | allow | |
  50. | 23 | authorization | |
  51. | 24 | cache-control | |
  52. | 25 | content-disposition | |
  53. | 26 | content-encoding | |
  54. | 27 | content-language | |
  55. | 28 | content-length | |
  56. | 29 | content-location | |
  57. | 30 | content-range | |
  58. | 31 | content-type | |
  59. | 32 | cookie | |
  60. | 33 | date | |
  61. | 34 | etag | |
  62. | 35 | expect | |
  63. | 36 | expires | |
  64. | 37 | from | |
  65. | 38 | host | |
  66. | 39 | if-match | |
  67. | 40 | if-modified-since | |
  68. | 41 | if-none-match | |
  69. | 42 | if-range | |
  70. | 43 | if-unmodified-since | |
  71. | 44 | last-modified | |
  72. | 45 | link | |
  73. | 46 | location | |
  74. | 47 | max-forwards | |
  75. | 48 | proxy-authenticate | |
  76. | 49 | proxy-authorization | |
  77. | 50 | range | |
  78. | 51 | referer | |
  79. | 52 | refresh | |
  80. | 53 | retry-after | |
  81. | 54 | server | |
  82. | 55 | set-cookie | |
  83. | 56 | strict-transport-security | |
  84. | 57 | transfer-encoding | |
  85. | 58 | user-agent | |
  86. | 59 | vary | |
  87. | 60 | via | |
  88. | 61 | www-authenticate | |
  89. +-------+-----------------------------+---------------+
  90. */
  91. static const uint8_t static_hdr_len[62] = {
  92. 0, /* starts at 1 */
  93. 10, 7, 7, 5, 5, 7, 7, 7, 7, 7,
  94. 7, 7, 7, 7, 14, 15, 15, 13, 6, 27,
  95. 3, 5, 13, 13, 19, 16, 16, 14, 16, 13,
  96. 12, 6, 4, 4, 6, 7, 4, 4, 8, 17,
  97. 13, 8, 19, 13, 4, 8, 12, 18, 19, 5,
  98. 7, 7, 11, 6, 10, 25, 17, 10, 4, 3,
  99. 16
  100. };
  101. static const unsigned char static_token[] = {
  102. 0,
  103. WSI_TOKEN_HTTP_COLON_AUTHORITY,
  104. WSI_TOKEN_HTTP_COLON_METHOD,
  105. WSI_TOKEN_HTTP_COLON_METHOD,
  106. WSI_TOKEN_HTTP_COLON_PATH,
  107. WSI_TOKEN_HTTP_COLON_PATH,
  108. WSI_TOKEN_HTTP_COLON_SCHEME,
  109. WSI_TOKEN_HTTP_COLON_SCHEME,
  110. WSI_TOKEN_HTTP_COLON_STATUS,
  111. WSI_TOKEN_HTTP_COLON_STATUS,
  112. WSI_TOKEN_HTTP_COLON_STATUS,
  113. WSI_TOKEN_HTTP_COLON_STATUS,
  114. WSI_TOKEN_HTTP_COLON_STATUS,
  115. WSI_TOKEN_HTTP_COLON_STATUS,
  116. WSI_TOKEN_HTTP_COLON_STATUS,
  117. WSI_TOKEN_HTTP_ACCEPT_CHARSET,
  118. WSI_TOKEN_HTTP_ACCEPT_ENCODING,
  119. WSI_TOKEN_HTTP_ACCEPT_LANGUAGE,
  120. WSI_TOKEN_HTTP_ACCEPT_RANGES,
  121. WSI_TOKEN_HTTP_ACCEPT,
  122. WSI_TOKEN_HTTP_ACCESS_CONTROL_ALLOW_ORIGIN,
  123. WSI_TOKEN_HTTP_AGE,
  124. WSI_TOKEN_HTTP_ALLOW,
  125. WSI_TOKEN_HTTP_AUTHORIZATION,
  126. WSI_TOKEN_HTTP_CACHE_CONTROL,
  127. WSI_TOKEN_HTTP_CONTENT_DISPOSITION,
  128. WSI_TOKEN_HTTP_CONTENT_ENCODING,
  129. WSI_TOKEN_HTTP_CONTENT_LANGUAGE,
  130. WSI_TOKEN_HTTP_CONTENT_LENGTH,
  131. WSI_TOKEN_HTTP_CONTENT_LOCATION,
  132. WSI_TOKEN_HTTP_CONTENT_RANGE,
  133. WSI_TOKEN_HTTP_CONTENT_TYPE,
  134. WSI_TOKEN_HTTP_COOKIE,
  135. WSI_TOKEN_HTTP_DATE,
  136. WSI_TOKEN_HTTP_ETAG,
  137. WSI_TOKEN_HTTP_EXPECT,
  138. WSI_TOKEN_HTTP_EXPIRES,
  139. WSI_TOKEN_HTTP_FROM,
  140. WSI_TOKEN_HOST,
  141. WSI_TOKEN_HTTP_IF_MATCH,
  142. WSI_TOKEN_HTTP_IF_MODIFIED_SINCE,
  143. WSI_TOKEN_HTTP_IF_NONE_MATCH,
  144. WSI_TOKEN_HTTP_IF_RANGE,
  145. WSI_TOKEN_HTTP_IF_UNMODIFIED_SINCE,
  146. WSI_TOKEN_HTTP_LAST_MODIFIED,
  147. WSI_TOKEN_HTTP_LINK,
  148. WSI_TOKEN_HTTP_LOCATION,
  149. WSI_TOKEN_HTTP_MAX_FORWARDS,
  150. WSI_TOKEN_HTTP_PROXY_AUTHENTICATE,
  151. WSI_TOKEN_HTTP_PROXY_AUTHORIZATION,
  152. WSI_TOKEN_HTTP_RANGE,
  153. WSI_TOKEN_HTTP_REFERER,
  154. WSI_TOKEN_HTTP_REFRESH,
  155. WSI_TOKEN_HTTP_RETRY_AFTER,
  156. WSI_TOKEN_HTTP_SERVER,
  157. WSI_TOKEN_HTTP_SET_COOKIE,
  158. WSI_TOKEN_HTTP_STRICT_TRANSPORT_SECURITY,
  159. WSI_TOKEN_HTTP_TRANSFER_ENCODING,
  160. WSI_TOKEN_HTTP_USER_AGENT,
  161. WSI_TOKEN_HTTP_VARY,
  162. WSI_TOKEN_HTTP_VIA,
  163. WSI_TOKEN_HTTP_WWW_AUTHENTICATE,
  164. };
  165. /* some of the entries imply values as well as header names */
  166. static const char * const http2_canned[] = {
  167. "",
  168. "",
  169. "GET",
  170. "POST",
  171. "/",
  172. "/index.html",
  173. "http",
  174. "https",
  175. "200",
  176. "204",
  177. "206",
  178. "304",
  179. "400",
  180. "404",
  181. "500",
  182. "",
  183. "gzip, deflate"
  184. };
  185. /* see minihuf.c */
  186. #include "huftable.h"
  187. static int huftable_decode(int pos, char c)
  188. {
  189. int q = pos + !!c;
  190. if (lextable_terms[q >> 3] & (1 << (q & 7))) /* terminal */
  191. return lextable[q] | 0x8000;
  192. return pos + (lextable[q] << 1);
  193. }
  194. static int lws_frag_start(struct lws *wsi, int hdr_token_idx)
  195. {
  196. struct allocated_headers *ah = wsi->http.ah;
  197. if (!ah) {
  198. lwsl_notice("%s: no ah\n", __func__);
  199. return 1;
  200. }
  201. ah->hdr_token_idx = -1;
  202. lwsl_header("%s: token %d ah->pos = %d, ah->nfrag = %d\n",
  203. __func__, hdr_token_idx, ah->pos, ah->nfrag);
  204. if (!hdr_token_idx) {
  205. lwsl_err("%s: zero hdr_token_idx\n", __func__);
  206. return 1;
  207. }
  208. if (ah->nfrag >= LWS_ARRAY_SIZE(ah->frag_index)) {
  209. lwsl_err("%s: frag index %d too big\n", __func__, ah->nfrag);
  210. return 1;
  211. }
  212. if ((hdr_token_idx == WSI_TOKEN_HTTP_COLON_AUTHORITY ||
  213. hdr_token_idx == WSI_TOKEN_HTTP_COLON_METHOD ||
  214. hdr_token_idx == WSI_TOKEN_HTTP_COLON_PATH ||
  215. hdr_token_idx == WSI_TOKEN_COLON_PROTOCOL ||
  216. hdr_token_idx == WSI_TOKEN_HTTP_COLON_SCHEME) &&
  217. ah->frag_index[hdr_token_idx]) {
  218. if (!(ah->frags[ah->frag_index[hdr_token_idx]].flags & 1)) {
  219. lws_h2_goaway(lws_get_network_wsi(wsi),
  220. H2_ERR_PROTOCOL_ERROR,
  221. "Duplicated pseudoheader");
  222. return 1;
  223. }
  224. }
  225. if (ah->nfrag == 0)
  226. ah->nfrag = 1;
  227. ah->frags[ah->nfrag].offset = ah->pos;
  228. ah->frags[ah->nfrag].len = 0;
  229. ah->frags[ah->nfrag].nfrag = 0;
  230. ah->frags[ah->nfrag].flags = 2; /* we had reason to set it */
  231. ah->hdr_token_idx = hdr_token_idx;
  232. /*
  233. * Okay, but we could be, eg, the second or subsequent cookie: header
  234. */
  235. if (ah->frag_index[hdr_token_idx]) {
  236. int n;
  237. /* find the last fragment for this header... */
  238. n = ah->frag_index[hdr_token_idx];
  239. while (ah->frags[n].nfrag)
  240. n = ah->frags[n].nfrag;
  241. /* and point it to continue in our continuation fragment */
  242. ah->frags[n].nfrag = ah->nfrag;
  243. /* cookie continuations need a separator token of ';' */
  244. if (hdr_token_idx == WSI_TOKEN_HTTP_COOKIE) {
  245. ah->data[ah->pos++] = ';';
  246. ah->frags[ah->nfrag].len++;
  247. }
  248. } else
  249. ah->frag_index[hdr_token_idx] = ah->nfrag;
  250. return 0;
  251. }
  252. static int lws_frag_append(struct lws *wsi, unsigned char c)
  253. {
  254. struct allocated_headers *ah = wsi->http.ah;
  255. ah->data[ah->pos++] = c;
  256. ah->frags[ah->nfrag].len++;
  257. return (int)ah->pos >= wsi->a.context->max_http_header_data;
  258. }
  259. static int lws_frag_end(struct lws *wsi)
  260. {
  261. lwsl_header("%s\n", __func__);
  262. if (lws_frag_append(wsi, 0))
  263. return 1;
  264. /* don't account for the terminating NUL in the logical length */
  265. wsi->http.ah->frags[wsi->http.ah->nfrag].len--;
  266. wsi->http.ah->nfrag++;
  267. return 0;
  268. }
  269. int
  270. lws_hdr_extant(struct lws *wsi, enum lws_token_indexes h)
  271. {
  272. struct allocated_headers *ah = wsi->http.ah;
  273. int n;
  274. if (!ah)
  275. return 0;
  276. n = ah->frag_index[h];
  277. if (!n)
  278. return 0;
  279. return !!(ah->frags[n].flags & 2);
  280. }
  281. static void lws_dump_header(struct lws *wsi, int hdr)
  282. {
  283. char s[200];
  284. const unsigned char *p;
  285. int len;
  286. if (hdr == LWS_HPACK_IGNORE_ENTRY) {
  287. lwsl_notice("hdr tok ignored\n");
  288. return;
  289. }
  290. (void)p;
  291. len = lws_hdr_copy(wsi, s, sizeof(s) - 1, hdr);
  292. if (len < 0)
  293. strcpy(s, "(too big to show)");
  294. else
  295. s[len] = '\0';
  296. #if defined(_DEBUG)
  297. p = lws_token_to_string(hdr);
  298. lwsl_header(" hdr tok %d (%s) = '%s' (len %d)\n", hdr,
  299. p ? (char *)p : (char *)"null", s, len);
  300. #endif
  301. }
  302. /*
  303. * dynamic table
  304. *
  305. * [ 0 .... num_entries - 1]
  306. *
  307. * Starts filling at 0+
  308. *
  309. * #62 is *most recently entered*
  310. *
  311. * Number of entries is not restricted, but aggregated size of the entry
  312. * payloads is. Unfortunately the way HPACK does this is specific to an
  313. * imagined implementation, and lws implementation is much more efficient
  314. * (ignoring unknown headers and using the lws token index for the header
  315. * name part).
  316. */
  317. /*
  318. * returns 0 if dynamic entry (arg and len are filled)
  319. * returns -1 if failure
  320. * returns nonzero token index if actually static token
  321. */
  322. static int
  323. lws_token_from_index(struct lws *wsi, int index, const char **arg, int *len,
  324. uint32_t *hdr_len)
  325. {
  326. struct hpack_dynamic_table *dyn;
  327. if (index == LWS_HPACK_IGNORE_ENTRY)
  328. return LWS_HPACK_IGNORE_ENTRY;
  329. /* dynamic table only belongs to network wsi */
  330. wsi = lws_get_network_wsi(wsi);
  331. if (!wsi->h2.h2n)
  332. return -1;
  333. dyn = &wsi->h2.h2n->hpack_dyn_table;
  334. if (index < 0)
  335. return -1;
  336. if (index < (int)LWS_ARRAY_SIZE(static_token)) {
  337. if (arg && index < (int)LWS_ARRAY_SIZE(http2_canned)) {
  338. *arg = http2_canned[index];
  339. *len = (int)strlen(http2_canned[index]);
  340. }
  341. if (hdr_len)
  342. *hdr_len = static_hdr_len[index];
  343. return static_token[index];
  344. }
  345. if (!dyn) {
  346. lwsl_notice("no dynamic table\n");
  347. return -1;
  348. }
  349. if (index >= (int)LWS_ARRAY_SIZE(static_token) + dyn->used_entries) {
  350. lwsl_info(" %s: adjusted index %d >= %d\n", __func__, index,
  351. (int)LWS_ARRAY_SIZE(static_token) + dyn->used_entries);
  352. lws_h2_goaway(wsi, H2_ERR_COMPRESSION_ERROR,
  353. "index out of range");
  354. return -1;
  355. }
  356. index -= (int)LWS_ARRAY_SIZE(static_token);
  357. index = lws_safe_modulo(dyn->pos - 1 - index, dyn->num_entries);
  358. if (index < 0)
  359. index += dyn->num_entries;
  360. lwsl_header("%s: dyn index %d, tok %d\n", __func__, index,
  361. dyn->entries[index].lws_hdr_idx);
  362. if (arg && len) {
  363. *arg = dyn->entries[index].value;
  364. *len = dyn->entries[index].value_len;
  365. }
  366. if (hdr_len)
  367. *hdr_len = dyn->entries[index].hdr_len;
  368. return dyn->entries[index].lws_hdr_idx;
  369. }
  370. static int
  371. lws_h2_dynamic_table_dump(struct lws *wsi)
  372. {
  373. #if 0
  374. struct lws *nwsi = lws_get_network_wsi(wsi);
  375. struct hpack_dynamic_table *dyn;
  376. int n, m;
  377. const char *p;
  378. if (!nwsi->h2.h2n)
  379. return 1;
  380. dyn = &nwsi->h2.h2n->hpack_dyn_table;
  381. lwsl_header("Dump dyn table for nwsi %p (%d / %d members, pos = %d, "
  382. "start index %d, virt used %d / %d)\n", nwsi,
  383. dyn->used_entries, dyn->num_entries, dyn->pos,
  384. (uint32_t)LWS_ARRAY_SIZE(static_token),
  385. dyn->virtual_payload_usage, dyn->virtual_payload_max);
  386. for (n = 0; n < dyn->used_entries; n++) {
  387. m = lws_safe_modulo(dyn->pos - 1 - n, dyn->num_entries);
  388. if (m < 0)
  389. m += dyn->num_entries;
  390. if (dyn->entries[m].lws_hdr_idx != LWS_HPACK_IGNORE_ENTRY)
  391. p = (const char *)lws_token_to_string(
  392. dyn->entries[m].lws_hdr_idx);
  393. else
  394. p = "(ignored)";
  395. lwsl_header(" %3d: tok %s: (len %d) val '%s'\n",
  396. (int)(n + LWS_ARRAY_SIZE(static_token)), p,
  397. dyn->entries[m].hdr_len, dyn->entries[m].value ?
  398. dyn->entries[m].value : "null");
  399. }
  400. #endif
  401. return 0;
  402. }
  403. static void
  404. lws_dynamic_free(struct hpack_dynamic_table *dyn, int idx)
  405. {
  406. lwsl_header("freeing %d for reuse\n", idx);
  407. dyn->virtual_payload_usage -= dyn->entries[idx].value_len +
  408. dyn->entries[idx].hdr_len;
  409. lws_free_set_NULL(dyn->entries[idx].value);
  410. dyn->entries[idx].value = NULL;
  411. dyn->entries[idx].value_len = 0;
  412. dyn->entries[idx].hdr_len = 0;
  413. dyn->entries[idx].lws_hdr_idx = LWS_HPACK_IGNORE_ENTRY;
  414. dyn->used_entries--;
  415. }
  416. /*
  417. * There are two address spaces, 1) internal ringbuffer and 2) HPACK indexes.
  418. *
  419. * Internal ringbuffer:
  420. *
  421. * The internal ringbuffer wraps as we keep filling it, dyn->pos points to
  422. * the next index to be written.
  423. *
  424. * HPACK indexes:
  425. *
  426. * The last-written entry becomes entry 0, the previously-last-written entry
  427. * becomes entry 1 etc.
  428. */
  429. static int
  430. lws_dynamic_token_insert(struct lws *wsi, int hdr_len,
  431. int lws_hdr_index, char *arg, int len)
  432. {
  433. struct hpack_dynamic_table *dyn;
  434. int new_index;
  435. /* dynamic table only belongs to network wsi */
  436. wsi = lws_get_network_wsi(wsi);
  437. if (!wsi->h2.h2n)
  438. return 1;
  439. dyn = &wsi->h2.h2n->hpack_dyn_table;
  440. if (!dyn->entries) {
  441. lwsl_err("%s: unsized dyn table\n", __func__);
  442. return 1;
  443. }
  444. lws_h2_dynamic_table_dump(wsi);
  445. new_index = lws_safe_modulo(dyn->pos, dyn->num_entries);
  446. if (dyn->num_entries && dyn->used_entries == dyn->num_entries) {
  447. if (dyn->virtual_payload_usage < dyn->virtual_payload_max)
  448. lwsl_err("Dropping header content before limit!\n");
  449. /* we have to drop the oldest to make space */
  450. lws_dynamic_free(dyn, new_index);
  451. }
  452. /*
  453. * evict guys to make room, allowing for some overage. We have to
  454. * take care about getting a single huge header, and evicting
  455. * everything
  456. */
  457. while (dyn->virtual_payload_usage &&
  458. dyn->used_entries &&
  459. dyn->virtual_payload_usage + hdr_len + len >
  460. dyn->virtual_payload_max + 1024) {
  461. int n = lws_safe_modulo(dyn->pos - dyn->used_entries,
  462. dyn->num_entries);
  463. if (n < 0)
  464. n += dyn->num_entries;
  465. lws_dynamic_free(dyn, n);
  466. }
  467. if (dyn->used_entries < dyn->num_entries)
  468. dyn->used_entries++;
  469. dyn->entries[new_index].value_len = 0;
  470. if (lws_hdr_index != LWS_HPACK_IGNORE_ENTRY) {
  471. if (dyn->entries[new_index].value)
  472. lws_free_set_NULL(dyn->entries[new_index].value);
  473. dyn->entries[new_index].value =
  474. lws_malloc(len + 1, "hpack dyn");
  475. if (!dyn->entries[new_index].value)
  476. return 1;
  477. memcpy(dyn->entries[new_index].value, arg, len);
  478. dyn->entries[new_index].value[len] = '\0';
  479. dyn->entries[new_index].value_len = len;
  480. } else
  481. dyn->entries[new_index].value = NULL;
  482. dyn->entries[new_index].lws_hdr_idx = lws_hdr_index;
  483. dyn->entries[new_index].hdr_len = hdr_len;
  484. dyn->virtual_payload_usage += hdr_len + len;
  485. lwsl_info("%s: index %ld: lws_hdr_index 0x%x, hdr len %d, '%s' len %d\n",
  486. __func__, (long)LWS_ARRAY_SIZE(static_token),
  487. lws_hdr_index, hdr_len, dyn->entries[new_index].value ?
  488. dyn->entries[new_index].value : "null", len);
  489. dyn->pos = lws_safe_modulo(dyn->pos + 1, dyn->num_entries);
  490. lws_h2_dynamic_table_dump(wsi);
  491. return 0;
  492. }
  493. int
  494. lws_hpack_dynamic_size(struct lws *wsi, int size)
  495. {
  496. struct hpack_dynamic_table *dyn;
  497. struct hpack_dt_entry *dte;
  498. struct lws *nwsi;
  499. int min, n = 0, m;
  500. /*
  501. * "size" here is coming from the http/2 SETTING
  502. * SETTINGS_HEADER_TABLE_SIZE. This is a (virtual, in our case)
  503. * linear buffer containing dynamic header names and values... when it
  504. * is full, old entries are evicted.
  505. *
  506. * We encode the header as an lws_hdr_idx, which is all the rest of
  507. * lws cares about; if there is no matching header we store an empty
  508. * entry in the dyn table as a placeholder.
  509. *
  510. * So to make the two systems work together we keep an accounting of
  511. * what we are using to decide when to evict... we must only evict
  512. * things when the remote peer's accounting also makes him feel he
  513. * should evict something.
  514. */
  515. nwsi = lws_get_network_wsi(wsi);
  516. if (!nwsi->h2.h2n)
  517. goto bail;
  518. dyn = &nwsi->h2.h2n->hpack_dyn_table;
  519. lwsl_info("%s: from %d to %d, lim %u\n", __func__,
  520. (int)dyn->num_entries, size,
  521. (unsigned int)nwsi->a.vhost->h2.set.s[H2SET_HEADER_TABLE_SIZE]);
  522. if (!size) {
  523. size = dyn->num_entries * 8;
  524. lws_hpack_destroy_dynamic_header(wsi);
  525. }
  526. if (size > (int)nwsi->a.vhost->h2.set.s[H2SET_HEADER_TABLE_SIZE]) {
  527. lwsl_info("rejecting hpack dyn size %u vs %u\n", size,
  528. (unsigned int)nwsi->a.vhost->h2.set.s[H2SET_HEADER_TABLE_SIZE]);
  529. // this seems necessary to work with some browsers
  530. if (nwsi->a.vhost->h2.set.s[H2SET_HEADER_TABLE_SIZE] == 65536 &&
  531. size == 65537) { /* h2spec */
  532. lws_h2_goaway(nwsi, H2_ERR_COMPRESSION_ERROR,
  533. "Asked for header table bigger than we told");
  534. goto bail;
  535. }
  536. size = nwsi->a.vhost->h2.set.s[H2SET_HEADER_TABLE_SIZE];
  537. }
  538. dyn->virtual_payload_max = size;
  539. size = size / 8;
  540. min = size;
  541. if (min > dyn->used_entries)
  542. min = dyn->used_entries;
  543. if (size == dyn->num_entries)
  544. return 0;
  545. if (dyn->num_entries < min)
  546. min = dyn->num_entries;
  547. // lwsl_notice("dte requested size %d\n", size);
  548. dte = lws_zalloc(sizeof(*dte) * (size + 1), "dynamic table entries");
  549. if (!dte)
  550. goto bail;
  551. while (dyn->virtual_payload_usage && dyn->used_entries &&
  552. dyn->virtual_payload_usage > dyn->virtual_payload_max) {
  553. n = lws_safe_modulo(dyn->pos - dyn->used_entries, dyn->num_entries);
  554. if (n < 0)
  555. n += dyn->num_entries;
  556. lws_dynamic_free(dyn, n);
  557. }
  558. if (min > dyn->used_entries)
  559. min = dyn->used_entries;
  560. if (dyn->entries) {
  561. for (n = 0; n < min; n++) {
  562. m = (dyn->pos - dyn->used_entries + n) %
  563. dyn->num_entries;
  564. if (m < 0)
  565. m += dyn->num_entries;
  566. dte[n] = dyn->entries[m];
  567. }
  568. lws_free(dyn->entries);
  569. }
  570. dyn->entries = dte;
  571. dyn->num_entries = size;
  572. dyn->used_entries = min;
  573. if (size)
  574. dyn->pos = lws_safe_modulo(min, size);
  575. else
  576. dyn->pos = 0;
  577. lws_h2_dynamic_table_dump(wsi);
  578. return 0;
  579. bail:
  580. lwsl_info("%s: failed to resize to %d\n", __func__, size);
  581. return 1;
  582. }
  583. void
  584. lws_hpack_destroy_dynamic_header(struct lws *wsi)
  585. {
  586. struct hpack_dynamic_table *dyn;
  587. int n;
  588. if (!wsi->h2.h2n)
  589. return;
  590. dyn = &wsi->h2.h2n->hpack_dyn_table;
  591. if (!dyn->entries)
  592. return;
  593. for (n = 0; n < dyn->num_entries; n++)
  594. if (dyn->entries[n].value)
  595. lws_free_set_NULL(dyn->entries[n].value);
  596. lws_free_set_NULL(dyn->entries);
  597. }
  598. static int
  599. lws_hpack_use_idx_hdr(struct lws *wsi, int idx, int known_token)
  600. {
  601. const char *arg = NULL;
  602. int len = 0;
  603. const char *p = NULL;
  604. int tok = lws_token_from_index(wsi, idx, &arg, &len, NULL);
  605. if (tok == LWS_HPACK_IGNORE_ENTRY) {
  606. lwsl_header("%s: lws_token says ignore, returning\n", __func__);
  607. return 0;
  608. }
  609. if (tok == -1) {
  610. lwsl_info("%s: idx %d mapped to tok %d\n", __func__, idx, tok);
  611. return 1;
  612. }
  613. if (arg) {
  614. /* dynamic result */
  615. if (known_token > 0)
  616. tok = known_token;
  617. lwsl_header("%s: dyn: idx %d '%s' tok %d\n", __func__, idx, arg,
  618. tok);
  619. } else
  620. lwsl_header("writing indexed hdr %d (tok %d '%s')\n", idx, tok,
  621. lws_token_to_string(tok));
  622. if (tok == LWS_HPACK_IGNORE_ENTRY)
  623. return 0;
  624. if (arg)
  625. p = arg;
  626. if (idx < (int)LWS_ARRAY_SIZE(http2_canned))
  627. p = http2_canned[idx];
  628. if (lws_frag_start(wsi, tok))
  629. return 1;
  630. if (p)
  631. while (*p && len--)
  632. if (lws_frag_append(wsi, *p++))
  633. return 1;
  634. if (lws_frag_end(wsi))
  635. return 1;
  636. lws_dump_header(wsi, tok);
  637. return 0;
  638. }
  639. #if !defined(LWS_HTTP_HEADERS_ALL) && !defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) && !defined(LWS_ROLE_WS) && !defined(LWS_ROLE_H2)
  640. static uint8_t lws_header_implies_psuedoheader_map[] = {
  641. 0x03,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  642. };
  643. #endif
  644. #if !defined(LWS_HTTP_HEADERS_ALL) && defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) && !defined(LWS_ROLE_WS) && !defined(LWS_ROLE_H2)
  645. static uint8_t lws_header_implies_psuedoheader_map[] = {
  646. 0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  647. };
  648. #endif
  649. #if !defined(LWS_HTTP_HEADERS_ALL) && !defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) && defined(LWS_ROLE_WS) && !defined(LWS_ROLE_H2)
  650. static uint8_t lws_header_implies_psuedoheader_map[] = {
  651. 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  652. };
  653. #endif
  654. #if !defined(LWS_HTTP_HEADERS_ALL) && defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) && defined(LWS_ROLE_WS) && !defined(LWS_ROLE_H2)
  655. static uint8_t lws_header_implies_psuedoheader_map[] = {
  656. 0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0x00,0x00,0x00,0x00,0x00,0x00,
  657. };
  658. #endif
  659. #if !defined(LWS_HTTP_HEADERS_ALL) && !defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) && !defined(LWS_ROLE_WS) && defined(LWS_ROLE_H2)
  660. static uint8_t lws_header_implies_psuedoheader_map[] = {
  661. 0x03,0x00,0x80,0x0f,0x00,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  662. };
  663. #endif
  664. #if !defined(LWS_HTTP_HEADERS_ALL) && defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) && !defined(LWS_ROLE_WS) && defined(LWS_ROLE_H2)
  665. static uint8_t lws_header_implies_psuedoheader_map[] = {
  666. 0x07,0x00,0x00,0x3e,0x00,0x00,0x00,0x80,0x03,0x09,0x00,0x00,0x00,0x00,0x00,0x00,
  667. };
  668. #endif
  669. #if !defined(LWS_HTTP_HEADERS_ALL) && !defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) && defined(LWS_ROLE_WS) && defined(LWS_ROLE_H2)
  670. static uint8_t lws_header_implies_psuedoheader_map[] = {
  671. 0x03,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x00,0x00,0x00,
  672. };
  673. #endif
  674. #if defined(LWS_HTTP_HEADERS_ALL) || ( defined(LWS_WITH_HTTP_UNCOMMON_HEADERS) && defined(LWS_ROLE_WS) && defined(LWS_ROLE_H2))
  675. static uint8_t lws_header_implies_psuedoheader_map[] = {
  676. 0x07,0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0x00,0x0e,0x24,0x00,0x00,0x00,0x00,0x00,
  677. };
  678. #endif
  679. static int
  680. lws_hpack_handle_pseudo_rules(struct lws *nwsi, struct lws *wsi, int m)
  681. {
  682. if (m == LWS_HPACK_IGNORE_ENTRY || m == -1)
  683. return 0;
  684. if (wsi->seen_nonpseudoheader &&
  685. (lws_header_implies_psuedoheader_map[m >> 3] & (1 << (m & 7)))) {
  686. lwsl_info("lws tok %d seems to be a pseudoheader\n", m);
  687. /*
  688. * it's not legal to see a
  689. * pseudoheader after normal
  690. * headers
  691. */
  692. lws_h2_goaway(nwsi, H2_ERR_PROTOCOL_ERROR,
  693. "Pseudoheader after normal hdrs");
  694. return 1;
  695. }
  696. if (!(lws_header_implies_psuedoheader_map[m >> 3] & (1 << (m & 7))))
  697. wsi->seen_nonpseudoheader = 1;
  698. return 0;
  699. }
  700. int lws_hpack_interpret(struct lws *wsi, unsigned char c)
  701. {
  702. struct lws *nwsi = lws_get_network_wsi(wsi);
  703. struct lws_h2_netconn *h2n = nwsi->h2.h2n;
  704. struct allocated_headers *ah = wsi->http.ah;
  705. unsigned int prev;
  706. unsigned char c1;
  707. int n, m, plen;
  708. if (!h2n)
  709. return -1;
  710. /*
  711. * HPKT_INDEXED_HDR_7 1xxxxxxx: just "header field"
  712. * HPKT_INDEXED_HDR_6_VALUE_INCR 01xxxxxx: NEW indexed hdr + val
  713. * HPKT_LITERAL_HDR_VALUE_INCR 01000000: NEW literal hdr + val
  714. * HPKT_INDEXED_HDR_4_VALUE 0000xxxx: indexed hdr + val
  715. * HPKT_INDEXED_HDR_4_VALUE_NEVER 0001xxxx: NEVER NEW indexed hdr + val
  716. * HPKT_LITERAL_HDR_VALUE 00000000: literal hdr + val
  717. * HPKT_LITERAL_HDR_VALUE_NEVER 00010000: NEVER NEW literal hdr + val
  718. */
  719. switch (h2n->hpack) {
  720. case HPKS_TYPE:
  721. h2n->is_first_header_char = 1;
  722. h2n->huff_pad = 0;
  723. h2n->zero_huff_padding = 0;
  724. h2n->last_action_dyntable_resize = 0;
  725. h2n->ext_count = 0;
  726. h2n->hpack_hdr_len = 0;
  727. h2n->unknown_header = 0;
  728. ah->parser_state = 255;
  729. if (c & 0x80) { /* 1.... indexed header field only */
  730. /* just a possibly-extended integer */
  731. h2n->hpack_type = HPKT_INDEXED_HDR_7;
  732. lwsl_header("HPKT_INDEXED_HDR_7 hdr %d\n", c & 0x7f);
  733. lws_h2_dynamic_table_dump(wsi);
  734. h2n->hdr_idx = c & 0x7f;
  735. if ((c & 0x7f) == 0x7f) {
  736. h2n->hpack_len = 0;
  737. h2n->hpack_m = 0x7f;
  738. h2n->hpack = HPKS_IDX_EXT;
  739. break;
  740. }
  741. if (!h2n->hdr_idx) {
  742. lws_h2_goaway(nwsi, H2_ERR_COMPRESSION_ERROR,
  743. "hdr index 0 seen");
  744. return 1;
  745. }
  746. m = lws_token_from_index(wsi, h2n->hdr_idx,
  747. NULL, NULL, NULL);
  748. if (lws_hpack_handle_pseudo_rules(nwsi, wsi, m))
  749. return 1;
  750. lwsl_header("HPKT_INDEXED_HDR_7: hdr %d\n", c & 0x7f);
  751. if (lws_hpack_use_idx_hdr(wsi, c & 0x7f, -1)) {
  752. lwsl_header("%s: idx hdr wr fail\n", __func__);
  753. return 1;
  754. }
  755. /* stay at same state */
  756. break;
  757. }
  758. if (c & 0x40) { /* 01.... indexed or literal header incr idx */
  759. /*
  760. * [possibly-ext hdr idx (6) | new literal hdr name]
  761. * H + possibly-ext value length
  762. * literal value
  763. */
  764. h2n->hdr_idx = 0;
  765. if (c == 0x40) { /* literal header */
  766. lwsl_header(" HPKT_LITERAL_HDR_VALUE_INCR\n");
  767. h2n->hpack_type = HPKT_LITERAL_HDR_VALUE_INCR;
  768. h2n->value = 0;
  769. h2n->hpack_len = 0;
  770. h2n->hpack = HPKS_HLEN;
  771. break;
  772. }
  773. /* indexed header */
  774. h2n->hpack_type = HPKT_INDEXED_HDR_6_VALUE_INCR;
  775. lwsl_header(" HPKT_INDEXED_HDR_6_VALUE_INCR (hdr %d)\n",
  776. c & 0x3f);
  777. h2n->hdr_idx = c & 0x3f;
  778. if ((c & 0x3f) == 0x3f) {
  779. h2n->hpack_m = 0x3f;
  780. h2n->hpack_len = 0;
  781. h2n->hpack = HPKS_IDX_EXT;
  782. break;
  783. }
  784. h2n->value = 1;
  785. h2n->hpack = HPKS_HLEN;
  786. if (!h2n->hdr_idx) {
  787. lws_h2_goaway(nwsi, H2_ERR_COMPRESSION_ERROR,
  788. "hdr index 0 seen");
  789. return 1;
  790. }
  791. break;
  792. }
  793. switch(c & 0xf0) {
  794. case 0x10: /* literal header never index */
  795. case 0: /* literal header without indexing */
  796. /*
  797. * follows 0x40 except 4-bit hdr idx
  798. * and don't add to index
  799. */
  800. if (c == 0) { /* literal name */
  801. h2n->hpack_type = HPKT_LITERAL_HDR_VALUE;
  802. lwsl_header(" HPKT_LITERAL_HDR_VALUE\n");
  803. h2n->hpack = HPKS_HLEN;
  804. h2n->value = 0;
  805. break;
  806. }
  807. if (c == 0x10) { /* literal name NEVER */
  808. h2n->hpack_type = HPKT_LITERAL_HDR_VALUE_NEVER;
  809. lwsl_header(" HPKT_LITERAL_HDR_VALUE_NEVER\n");
  810. h2n->hpack = HPKS_HLEN;
  811. h2n->value = 0;
  812. break;
  813. }
  814. lwsl_header("indexed\n");
  815. /* indexed name */
  816. if (c & 0x10) {
  817. h2n->hpack_type = HPKT_INDEXED_HDR_4_VALUE_NEVER;
  818. lwsl_header("HPKT_LITERAL_HDR_4_VALUE_NEVER\n");
  819. } else {
  820. h2n->hpack_type = HPKT_INDEXED_HDR_4_VALUE;
  821. lwsl_header(" HPKT_INDEXED_HDR_4_VALUE\n");
  822. }
  823. h2n->hdr_idx = 0;
  824. if ((c & 0xf) == 0xf) {
  825. h2n->hpack_len = c & 0xf;
  826. h2n->hpack_m = 0xf;
  827. h2n->hpack_len = 0;
  828. h2n->hpack = HPKS_IDX_EXT;
  829. break;
  830. }
  831. h2n->hdr_idx = c & 0xf;
  832. h2n->value = 1;
  833. h2n->hpack = HPKS_HLEN;
  834. break;
  835. case 0x20:
  836. case 0x30: /* header table size update */
  837. /* possibly-extended size value (5) */
  838. lwsl_header("HPKT_SIZE_5 %x\n", c &0x1f);
  839. h2n->hpack_type = HPKT_SIZE_5;
  840. h2n->hpack_len = c & 0x1f;
  841. if (h2n->hpack_len == 0x1f) {
  842. h2n->hpack_m = 0x1f;
  843. h2n->hpack_len = 0;
  844. h2n->hpack = HPKS_IDX_EXT;
  845. break;
  846. }
  847. h2n->last_action_dyntable_resize = 1;
  848. if (lws_hpack_dynamic_size(wsi, h2n->hpack_len))
  849. return 1;
  850. break;
  851. }
  852. break;
  853. case HPKS_IDX_EXT:
  854. h2n->hpack_len = h2n->hpack_len |
  855. ((c & 0x7f) << h2n->ext_count);
  856. h2n->ext_count += 7;
  857. if (c & 0x80) /* extended int not complete yet */
  858. break;
  859. /* extended integer done */
  860. h2n->hpack_len += h2n->hpack_m;
  861. lwsl_header("HPKS_IDX_EXT: hpack_len %u\n", (unsigned int)h2n->hpack_len);
  862. switch (h2n->hpack_type) {
  863. case HPKT_INDEXED_HDR_7:
  864. if (lws_hpack_use_idx_hdr(wsi, h2n->hpack_len,
  865. h2n->hdr_idx)) {
  866. lwsl_notice("%s: hd7 use fail\n", __func__);
  867. return 1;
  868. }
  869. h2n->hpack = HPKS_TYPE;
  870. break;
  871. case HPKT_SIZE_5:
  872. h2n->last_action_dyntable_resize = 1;
  873. if (lws_hpack_dynamic_size(wsi, h2n->hpack_len))
  874. return 1;
  875. h2n->hpack = HPKS_TYPE;
  876. break;
  877. default:
  878. h2n->hdr_idx = h2n->hpack_len;
  879. if (!h2n->hdr_idx) {
  880. lws_h2_goaway(nwsi, H2_ERR_COMPRESSION_ERROR,
  881. "extended header index was 0");
  882. return 1;
  883. }
  884. h2n->value = 1;
  885. h2n->hpack = HPKS_HLEN;
  886. break;
  887. }
  888. break;
  889. case HPKS_HLEN: /* [ H | 7+ ] */
  890. h2n->huff = !!(c & 0x80);
  891. h2n->hpack_pos = 0;
  892. h2n->hpack_len = c & 0x7f;
  893. if (h2n->hpack_len == 0x7f) {
  894. h2n->hpack_m = 0x7f;
  895. h2n->hpack_len = 0;
  896. h2n->ext_count = 0;
  897. h2n->hpack = HPKS_HLEN_EXT;
  898. break;
  899. }
  900. if (h2n->value && !h2n->hpack_len) {
  901. lwsl_debug("%s: zero-length header data\n", __func__);
  902. h2n->hpack = HPKS_TYPE;
  903. goto fin;
  904. }
  905. pre_data:
  906. h2n->hpack = HPKS_DATA;
  907. if (!h2n->value || !h2n->hdr_idx) {
  908. ah->parser_state = WSI_TOKEN_NAME_PART;
  909. ah->lextable_pos = 0;
  910. h2n->unknown_header = 0;
  911. break;
  912. }
  913. if (h2n->hpack_type == HPKT_LITERAL_HDR_VALUE ||
  914. h2n->hpack_type == HPKT_LITERAL_HDR_VALUE_INCR ||
  915. h2n->hpack_type == HPKT_LITERAL_HDR_VALUE_NEVER) {
  916. n = ah->parser_state;
  917. if (n == 255) {
  918. n = -1;
  919. h2n->hdr_idx = -1;
  920. } else
  921. h2n->hdr_idx = 1;
  922. } else {
  923. n = lws_token_from_index(wsi, h2n->hdr_idx, NULL,
  924. NULL, NULL);
  925. lwsl_header(" lws_tok_from_idx(%u) says %d\n",
  926. (unsigned int)h2n->hdr_idx, n);
  927. }
  928. if (n == LWS_HPACK_IGNORE_ENTRY || n == -1)
  929. h2n->hdr_idx = LWS_HPACK_IGNORE_ENTRY;
  930. switch (h2n->hpack_type) {
  931. /*
  932. * hpack types with literal headers were parsed by the lws
  933. * header SM... on recognition of a known lws header, it does
  934. * the correct lws_frag_start() for us already. Other types
  935. * (ie, indexed header) need us to do it here.
  936. */
  937. case HPKT_LITERAL_HDR_VALUE_INCR:
  938. case HPKT_LITERAL_HDR_VALUE:
  939. case HPKT_LITERAL_HDR_VALUE_NEVER:
  940. break;
  941. default:
  942. if (n != -1 && n != LWS_HPACK_IGNORE_ENTRY &&
  943. lws_frag_start(wsi, n)) {
  944. lwsl_header("%s: frag start failed\n",
  945. __func__);
  946. return 1;
  947. }
  948. break;
  949. }
  950. break;
  951. case HPKS_HLEN_EXT:
  952. h2n->hpack_len = h2n->hpack_len |
  953. ((c & 0x7f) << h2n->ext_count);
  954. h2n->ext_count += 7;
  955. if (c & 0x80) /* extended integer not complete yet */
  956. break;
  957. h2n->hpack_len += h2n->hpack_m;
  958. goto pre_data;
  959. case HPKS_DATA:
  960. //lwsl_header(" 0x%02X huff %d\n", c, h2n->huff);
  961. c1 = c;
  962. for (n = 0; n < 8; n++) {
  963. if (h2n->huff) {
  964. char b = (c >> 7) & 1;
  965. prev = h2n->hpack_pos;
  966. h2n->hpack_pos = huftable_decode(
  967. h2n->hpack_pos, b);
  968. c <<= 1;
  969. if (h2n->hpack_pos == 0xffff) {
  970. lwsl_notice("Huffman err\n");
  971. return 1;
  972. }
  973. if (!(h2n->hpack_pos & 0x8000)) {
  974. if (!b)
  975. h2n->zero_huff_padding = 1;
  976. h2n->huff_pad++;
  977. continue;
  978. }
  979. c1 = h2n->hpack_pos & 0x7fff;
  980. h2n->hpack_pos = 0;
  981. h2n->huff_pad = 0;
  982. h2n->zero_huff_padding = 0;
  983. /* EOS |11111111|11111111|11111111|111111 */
  984. if (!c1 && prev == HUFTABLE_0x100_PREV) {
  985. lws_h2_goaway(nwsi,
  986. H2_ERR_COMPRESSION_ERROR,
  987. "Huffman EOT seen");
  988. return 1;
  989. }
  990. } else
  991. n = 8;
  992. if (h2n->value) { /* value */
  993. if (h2n->hdr_idx &&
  994. h2n->hdr_idx != LWS_HPACK_IGNORE_ENTRY) {
  995. if (ah->hdr_token_idx ==
  996. WSI_TOKEN_HTTP_COLON_PATH) {
  997. switch (lws_parse_urldecode(
  998. wsi, &c1)) {
  999. case LPUR_CONTINUE:
  1000. break;
  1001. case LPUR_SWALLOW:
  1002. goto swallow;
  1003. case LPUR_EXCESSIVE:
  1004. case LPUR_FORBID:
  1005. lws_h2_goaway(nwsi,
  1006. H2_ERR_PROTOCOL_ERROR,
  1007. "Evil URI");
  1008. return 1;
  1009. default:
  1010. return -1;
  1011. }
  1012. }
  1013. if (lws_frag_append(wsi, c1)) {
  1014. lwsl_notice(
  1015. "%s: frag app fail\n",
  1016. __func__);
  1017. return 1;
  1018. }
  1019. } //else
  1020. //lwsl_header("ignoring %c\n", c1);
  1021. } else {
  1022. /*
  1023. * Convert name using existing parser,
  1024. * If h2n->unknown_header == 0, result is
  1025. * in wsi->parser_state
  1026. * using WSI_TOKEN_GET_URI.
  1027. *
  1028. * If unknown header h2n->unknown_header
  1029. * will be set.
  1030. */
  1031. h2n->hpack_hdr_len++;
  1032. if (h2n->is_first_header_char) {
  1033. h2n->is_first_header_char = 0;
  1034. h2n->first_hdr_char = c1;
  1035. }
  1036. lwsl_header("parser: %c\n", c1);
  1037. /* uppercase header names illegal */
  1038. if (c1 >= 'A' && c1 <= 'Z') {
  1039. lws_h2_goaway(nwsi,
  1040. H2_ERR_COMPRESSION_ERROR,
  1041. "Uppercase literal hpack hdr");
  1042. return 1;
  1043. }
  1044. plen = 1;
  1045. if (!h2n->unknown_header &&
  1046. lws_parse(wsi, &c1, &plen))
  1047. h2n->unknown_header = 1;
  1048. }
  1049. swallow:
  1050. (void)n;
  1051. } // for n
  1052. if (--h2n->hpack_len)
  1053. break;
  1054. /*
  1055. * The header (h2n->value = 0) or the payload (h2n->value = 1)
  1056. * is complete.
  1057. */
  1058. if (h2n->huff && (h2n->huff_pad > 7 ||
  1059. (h2n->zero_huff_padding && h2n->huff_pad))) {
  1060. lwsl_info("zero_huff_padding: %d huff_pad: %d\n",
  1061. h2n->zero_huff_padding, h2n->huff_pad);
  1062. lws_h2_goaway(nwsi, H2_ERR_COMPRESSION_ERROR,
  1063. "Huffman padding excessive or wrong");
  1064. return 1;
  1065. }
  1066. fin:
  1067. if (!h2n->value && (
  1068. h2n->hpack_type == HPKT_LITERAL_HDR_VALUE ||
  1069. h2n->hpack_type == HPKT_LITERAL_HDR_VALUE_INCR ||
  1070. h2n->hpack_type == HPKT_LITERAL_HDR_VALUE_NEVER)) {
  1071. h2n->hdr_idx = LWS_HPACK_IGNORE_ENTRY;
  1072. lwsl_header("wsi->parser_state: %d\n",
  1073. ah->parser_state);
  1074. if (ah->parser_state == WSI_TOKEN_NAME_PART) {
  1075. /* h2 headers come without the colon */
  1076. c1 = ':';
  1077. plen = 1;
  1078. n = lws_parse(wsi, &c1, &plen);
  1079. (void)n;
  1080. }
  1081. if (ah->parser_state == WSI_TOKEN_NAME_PART ||
  1082. #if defined(LWS_WITH_CUSTOM_HEADERS)
  1083. ah->parser_state == WSI_TOKEN_UNKNOWN_VALUE_PART ||
  1084. #endif
  1085. ah->parser_state == WSI_TOKEN_SKIPPING) {
  1086. h2n->unknown_header = 1;
  1087. ah->parser_state = -1;
  1088. wsi->seen_nonpseudoheader = 1;
  1089. }
  1090. }
  1091. /* we have the header */
  1092. if (!h2n->value) {
  1093. h2n->value = 1;
  1094. h2n->hpack = HPKS_HLEN;
  1095. h2n->huff_pad = 0;
  1096. h2n->zero_huff_padding = 0;
  1097. h2n->ext_count = 0;
  1098. break;
  1099. }
  1100. /*
  1101. * we have got both the header and value
  1102. */
  1103. m = -1;
  1104. switch (h2n->hpack_type) {
  1105. /*
  1106. * These are the only two that insert to the dyntable
  1107. */
  1108. /* NEW indexed hdr with value */
  1109. case HPKT_INDEXED_HDR_6_VALUE_INCR:
  1110. /* header length is determined by known index */
  1111. m = lws_token_from_index(wsi, h2n->hdr_idx, NULL, NULL,
  1112. &h2n->hpack_hdr_len);
  1113. if (m < 0)
  1114. /*
  1115. * The peer may only send known 6-bit indexes,
  1116. * there's still the possibility it sends an unset
  1117. * dynamic index that we can't succeed to look up
  1118. */
  1119. return 1;
  1120. goto add_it;
  1121. /* NEW literal hdr with value */
  1122. case HPKT_LITERAL_HDR_VALUE_INCR:
  1123. /*
  1124. * hdr is a new literal, so length is already in
  1125. * h2n->hpack_hdr_len
  1126. */
  1127. m = ah->parser_state;
  1128. if (h2n->unknown_header ||
  1129. ah->parser_state == WSI_TOKEN_NAME_PART ||
  1130. ah->parser_state == WSI_TOKEN_SKIPPING) {
  1131. if (h2n->first_hdr_char == ':') {
  1132. lwsl_info("HPKT_LITERAL_HDR_VALUE_INCR:"
  1133. " end state %d unk hdr %d\n",
  1134. ah->parser_state,
  1135. h2n->unknown_header);
  1136. /* unknown pseudoheaders are illegal */
  1137. lws_h2_goaway(nwsi,
  1138. H2_ERR_PROTOCOL_ERROR,
  1139. "Unknown pseudoheader");
  1140. return 1;
  1141. }
  1142. m = LWS_HPACK_IGNORE_ENTRY;
  1143. }
  1144. add_it:
  1145. /*
  1146. * mark us as having been set at the time of dynamic
  1147. * token insertion.
  1148. */
  1149. ah->frags[ah->nfrag].flags |= 1;
  1150. if (lws_dynamic_token_insert(wsi, h2n->hpack_hdr_len, m,
  1151. &ah->data[ah->frags[ah->nfrag].offset],
  1152. ah->frags[ah->nfrag].len)) {
  1153. lwsl_notice("%s: tok_insert fail\n", __func__);
  1154. return 1;
  1155. }
  1156. break;
  1157. default:
  1158. break;
  1159. }
  1160. if (h2n->hdr_idx != LWS_HPACK_IGNORE_ENTRY && lws_frag_end(wsi))
  1161. return 1;
  1162. if (h2n->hpack_type != HPKT_INDEXED_HDR_6_VALUE_INCR) {
  1163. if (h2n->hpack_type == HPKT_LITERAL_HDR_VALUE ||
  1164. h2n->hpack_type == HPKT_LITERAL_HDR_VALUE_INCR ||
  1165. h2n->hpack_type == HPKT_LITERAL_HDR_VALUE_NEVER) {
  1166. m = ah->parser_state;
  1167. if (m == 255)
  1168. m = -1;
  1169. } else
  1170. m = lws_token_from_index(wsi, h2n->hdr_idx,
  1171. NULL, NULL, NULL);
  1172. }
  1173. if (m != -1 && m != LWS_HPACK_IGNORE_ENTRY)
  1174. lws_dump_header(wsi, m);
  1175. if (lws_hpack_handle_pseudo_rules(nwsi, wsi, m))
  1176. return 1;
  1177. h2n->is_first_header_char = 1;
  1178. h2n->hpack = HPKS_TYPE;
  1179. break;
  1180. }
  1181. return 0;
  1182. }
  1183. static int
  1184. lws_h2_num_start(int starting_bits, unsigned long num)
  1185. {
  1186. unsigned int mask = (1 << starting_bits) - 1;
  1187. if (num < mask)
  1188. return (int)num;
  1189. return mask;
  1190. }
  1191. static int
  1192. lws_h2_num(int starting_bits, unsigned long num,
  1193. unsigned char **p, unsigned char *end)
  1194. {
  1195. unsigned int mask = (1 << starting_bits) - 1;
  1196. if (num < mask)
  1197. return 0;
  1198. num -= mask;
  1199. do {
  1200. if (num > 127)
  1201. *((*p)++) = 0x80 | (num & 0x7f);
  1202. else
  1203. *((*p)++) = 0x00 | (num & 0x7f);
  1204. if (*p >= end)
  1205. return 1;
  1206. num >>= 7;
  1207. } while (num);
  1208. return 0;
  1209. }
  1210. int lws_add_http2_header_by_name(struct lws *wsi, const unsigned char *name,
  1211. const unsigned char *value, int length,
  1212. unsigned char **p, unsigned char *end)
  1213. {
  1214. int len;
  1215. #if defined(_DEBUG)
  1216. /* value does not have to be NUL-terminated... %.*s not available on
  1217. * all platforms */
  1218. lws_strnncpy((char *)*p, (const char *)value, length,
  1219. lws_ptr_diff(end, (*p)));
  1220. lwsl_header("%s: %p %s:%s (len %d)\n", __func__, *p, name,
  1221. (const char *)*p, length);
  1222. #endif
  1223. len = (int)strlen((char *)name);
  1224. if (len)
  1225. if (name[len - 1] == ':')
  1226. len--;
  1227. if (wsi->mux_substream && !strncmp((const char *)name,
  1228. "transfer-encoding", len)) {
  1229. lwsl_header("rejecting %s\n", name);
  1230. return 0;
  1231. }
  1232. if (end - *p < len + length + 8)
  1233. return 1;
  1234. *((*p)++) = 0; /* literal hdr, literal name, */
  1235. *((*p)++) = 0 | lws_h2_num_start(7, len); /* non-HUF */
  1236. if (lws_h2_num(7, len, p, end))
  1237. return 1;
  1238. /* upper-case header names are verboten in h2, but OK on h1, so
  1239. * they're not illegal per se. Silently convert them for h2... */
  1240. while(len--)
  1241. *((*p)++) = tolower((int)*name++);
  1242. *((*p)++) = 0 | lws_h2_num_start(7, length); /* non-HUF */
  1243. if (lws_h2_num(7, length, p, end))
  1244. return 1;
  1245. memcpy(*p, value, length);
  1246. *p += length;
  1247. return 0;
  1248. }
  1249. int lws_add_http2_header_by_token(struct lws *wsi, enum lws_token_indexes token,
  1250. const unsigned char *value, int length,
  1251. unsigned char **p, unsigned char *end)
  1252. {
  1253. const unsigned char *name;
  1254. name = lws_token_to_string(token);
  1255. if (!name)
  1256. return 1;
  1257. return lws_add_http2_header_by_name(wsi, name, value, length, p, end);
  1258. }
  1259. int lws_add_http2_header_status(struct lws *wsi, unsigned int code,
  1260. unsigned char **p, unsigned char *end)
  1261. {
  1262. unsigned char status[10];
  1263. int n;
  1264. wsi->h2.send_END_STREAM = 0; // !!(code >= 400);
  1265. n = sprintf((char *)status, "%u", code);
  1266. if (lws_add_http2_header_by_token(wsi, WSI_TOKEN_HTTP_COLON_STATUS,
  1267. status, n, p, end))
  1268. return 1;
  1269. return 0;
  1270. }