request_response.c 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228
  1. /**
  2. * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3. * SPDX-License-Identifier: Apache-2.0.
  4. */
  5. #include <aws/common/array_list.h>
  6. #include <aws/common/mutex.h>
  7. #include <aws/common/string.h>
  8. #include <aws/http/private/connection_impl.h>
  9. #include <aws/http/private/request_response_impl.h>
  10. #include <aws/http/private/strutil.h>
  11. #include <aws/http/server.h>
  12. #include <aws/http/status_code.h>
  13. #include <aws/io/logging.h>
  14. #include <aws/io/stream.h>
  15. #ifdef _MSC_VER
  16. # pragma warning(disable : 4204) /* non-constant aggregate initializer */
  17. #endif
  18. enum {
  19. /* Initial capacity for the aws_http_message.headers array_list. */
  20. AWS_HTTP_REQUEST_NUM_RESERVED_HEADERS = 16,
  21. };
  22. bool aws_http_header_name_eq(struct aws_byte_cursor name_a, struct aws_byte_cursor name_b) {
  23. return aws_byte_cursor_eq_ignore_case(&name_a, &name_b);
  24. }
  25. /**
  26. * -- Data Structure Notes --
  27. * Headers are stored in a linear array, rather than a hash-table of arrays.
  28. * The linear array was simpler to implement and may be faster due to having fewer allocations.
  29. * The API has been designed so we can swap out the implementation later if desired.
  30. *
  31. * -- String Storage Notes --
  32. * We use a single allocation to hold the name and value of each aws_http_header.
  33. * We could optimize storage by using something like a string pool. If we do this, be sure to maintain
  34. * the address of existing strings when adding new strings (a dynamic aws_byte_buf would not suffice).
  35. */
  36. struct aws_http_headers {
  37. struct aws_allocator *alloc;
  38. struct aws_array_list array_list; /* Contains aws_http_header */
  39. struct aws_atomic_var refcount;
  40. };
  41. struct aws_http_headers *aws_http_headers_new(struct aws_allocator *allocator) {
  42. AWS_PRECONDITION(allocator);
  43. struct aws_http_headers *headers = aws_mem_calloc(allocator, 1, sizeof(struct aws_http_headers));
  44. if (!headers) {
  45. goto alloc_failed;
  46. }
  47. headers->alloc = allocator;
  48. aws_atomic_init_int(&headers->refcount, 1);
  49. if (aws_array_list_init_dynamic(
  50. &headers->array_list, allocator, AWS_HTTP_REQUEST_NUM_RESERVED_HEADERS, sizeof(struct aws_http_header))) {
  51. goto array_list_failed;
  52. }
  53. return headers;
  54. array_list_failed:
  55. aws_mem_release(headers->alloc, headers);
  56. alloc_failed:
  57. return NULL;
  58. }
  59. void aws_http_headers_release(struct aws_http_headers *headers) {
  60. AWS_PRECONDITION(!headers || headers->alloc);
  61. if (!headers) {
  62. return;
  63. }
  64. size_t prev_refcount = aws_atomic_fetch_sub(&headers->refcount, 1);
  65. if (prev_refcount == 1) {
  66. aws_http_headers_clear(headers);
  67. aws_array_list_clean_up(&headers->array_list);
  68. aws_mem_release(headers->alloc, headers);
  69. } else {
  70. AWS_ASSERT(prev_refcount != 0);
  71. }
  72. }
  73. void aws_http_headers_acquire(struct aws_http_headers *headers) {
  74. AWS_PRECONDITION(headers);
  75. aws_atomic_fetch_add(&headers->refcount, 1);
  76. }
  77. static int s_http_headers_add_header_impl(
  78. struct aws_http_headers *headers,
  79. const struct aws_http_header *header_orig,
  80. bool front) {
  81. AWS_PRECONDITION(headers);
  82. AWS_PRECONDITION(header_orig);
  83. AWS_PRECONDITION(aws_byte_cursor_is_valid(&header_orig->name) && aws_byte_cursor_is_valid(&header_orig->value));
  84. struct aws_http_header header_copy = *header_orig;
  85. if (header_copy.name.len == 0) {
  86. return aws_raise_error(AWS_ERROR_HTTP_INVALID_HEADER_NAME);
  87. }
  88. /* Whitespace around header values is ignored (RFC-7230 - Section 3.2).
  89. * Trim it off here, so anyone querying this value has an easier time. */
  90. header_copy.value = aws_strutil_trim_http_whitespace(header_copy.value);
  91. size_t total_len;
  92. if (aws_add_size_checked(header_copy.name.len, header_copy.value.len, &total_len)) {
  93. return AWS_OP_ERR;
  94. }
  95. /* Store our own copy of the strings.
  96. * We put the name and value into the same allocation. */
  97. uint8_t *strmem = aws_mem_acquire(headers->alloc, total_len);
  98. struct aws_byte_buf strbuf = aws_byte_buf_from_empty_array(strmem, total_len);
  99. aws_byte_buf_append_and_update(&strbuf, &header_copy.name);
  100. aws_byte_buf_append_and_update(&strbuf, &header_copy.value);
  101. if (front) {
  102. if (aws_array_list_push_front(&headers->array_list, &header_copy)) {
  103. goto error;
  104. }
  105. } else {
  106. if (aws_array_list_push_back(&headers->array_list, &header_copy)) {
  107. goto error;
  108. }
  109. }
  110. return AWS_OP_SUCCESS;
  111. error:
  112. aws_mem_release(headers->alloc, strmem);
  113. return AWS_OP_ERR;
  114. }
  115. int aws_http_headers_add_header(struct aws_http_headers *headers, const struct aws_http_header *header) {
  116. /* Add pseudo headers to the front and not checking any violation until we send the header to the wire */
  117. bool pseudo = aws_strutil_is_http_pseudo_header_name(header->name);
  118. bool front = false;
  119. if (pseudo && aws_http_headers_count(headers)) {
  120. struct aws_http_header last_header;
  121. /* TODO: instead if checking the last header, maybe we can add the pseudo headers to the end of the existing
  122. * pseudo headers, which needs to insert to the middle of the array list. */
  123. AWS_ZERO_STRUCT(last_header);
  124. aws_http_headers_get_index(headers, aws_http_headers_count(headers) - 1, &last_header);
  125. front = !aws_strutil_is_http_pseudo_header_name(last_header.name);
  126. }
  127. return s_http_headers_add_header_impl(headers, header, front);
  128. }
  129. int aws_http_headers_add(struct aws_http_headers *headers, struct aws_byte_cursor name, struct aws_byte_cursor value) {
  130. struct aws_http_header header = {.name = name, .value = value};
  131. return aws_http_headers_add_header(headers, &header);
  132. }
  133. void aws_http_headers_clear(struct aws_http_headers *headers) {
  134. AWS_PRECONDITION(headers);
  135. struct aws_http_header *header = NULL;
  136. const size_t count = aws_http_headers_count(headers);
  137. for (size_t i = 0; i < count; ++i) {
  138. aws_array_list_get_at_ptr(&headers->array_list, (void **)&header, i);
  139. AWS_ASSUME(header);
  140. /* Storage for name & value is in the same allocation */
  141. aws_mem_release(headers->alloc, header->name.ptr);
  142. }
  143. aws_array_list_clear(&headers->array_list);
  144. }
  145. /* Does not check index */
  146. static void s_http_headers_erase_index(struct aws_http_headers *headers, size_t index) {
  147. struct aws_http_header *header = NULL;
  148. aws_array_list_get_at_ptr(&headers->array_list, (void **)&header, index);
  149. AWS_ASSUME(header);
  150. /* Storage for name & value is in the same allocation */
  151. aws_mem_release(headers->alloc, header->name.ptr);
  152. aws_array_list_erase(&headers->array_list, index);
  153. }
  154. int aws_http_headers_erase_index(struct aws_http_headers *headers, size_t index) {
  155. AWS_PRECONDITION(headers);
  156. if (index >= aws_http_headers_count(headers)) {
  157. return aws_raise_error(AWS_ERROR_INVALID_INDEX);
  158. }
  159. s_http_headers_erase_index(headers, index);
  160. return AWS_OP_SUCCESS;
  161. }
  162. /* Erase entries with name, stop at end_index */
  163. static int s_http_headers_erase(
  164. struct aws_http_headers *headers,
  165. struct aws_byte_cursor name,
  166. size_t start_index,
  167. size_t end_index) {
  168. bool erased_any = false;
  169. struct aws_http_header *header = NULL;
  170. /* Iterating in reverse is simpler */
  171. for (size_t n = end_index; n > start_index; --n) {
  172. const size_t i = n - 1;
  173. aws_array_list_get_at_ptr(&headers->array_list, (void **)&header, i);
  174. AWS_ASSUME(header);
  175. if (aws_http_header_name_eq(header->name, name)) {
  176. s_http_headers_erase_index(headers, i);
  177. erased_any = true;
  178. }
  179. }
  180. if (!erased_any) {
  181. return aws_raise_error(AWS_ERROR_HTTP_HEADER_NOT_FOUND);
  182. }
  183. return AWS_OP_SUCCESS;
  184. }
  185. int aws_http_headers_erase(struct aws_http_headers *headers, struct aws_byte_cursor name) {
  186. AWS_PRECONDITION(headers);
  187. AWS_PRECONDITION(aws_byte_cursor_is_valid(&name));
  188. return s_http_headers_erase(headers, name, 0, aws_http_headers_count(headers));
  189. }
  190. int aws_http_headers_erase_value(
  191. struct aws_http_headers *headers,
  192. struct aws_byte_cursor name,
  193. struct aws_byte_cursor value) {
  194. AWS_PRECONDITION(headers);
  195. AWS_PRECONDITION(aws_byte_cursor_is_valid(&name) && aws_byte_cursor_is_valid(&value));
  196. struct aws_http_header *header = NULL;
  197. const size_t count = aws_http_headers_count(headers);
  198. for (size_t i = 0; i < count; ++i) {
  199. aws_array_list_get_at_ptr(&headers->array_list, (void **)&header, i);
  200. AWS_ASSUME(header);
  201. if (aws_http_header_name_eq(header->name, name) && aws_byte_cursor_eq(&header->value, &value)) {
  202. s_http_headers_erase_index(headers, i);
  203. return AWS_OP_SUCCESS;
  204. }
  205. }
  206. return aws_raise_error(AWS_ERROR_HTTP_HEADER_NOT_FOUND);
  207. }
  208. int aws_http_headers_add_array(struct aws_http_headers *headers, const struct aws_http_header *array, size_t count) {
  209. AWS_PRECONDITION(headers);
  210. AWS_PRECONDITION(AWS_MEM_IS_READABLE(array, count));
  211. const size_t orig_count = aws_http_headers_count(headers);
  212. for (size_t i = 0; i < count; ++i) {
  213. if (aws_http_headers_add_header(headers, &array[i])) {
  214. goto error;
  215. }
  216. }
  217. return AWS_OP_SUCCESS;
  218. error:
  219. /* Erase headers from the end until we're back to our previous state */
  220. for (size_t new_count = aws_http_headers_count(headers); new_count > orig_count; --new_count) {
  221. s_http_headers_erase_index(headers, new_count - 1);
  222. }
  223. return AWS_OP_ERR;
  224. }
  225. int aws_http_headers_set(struct aws_http_headers *headers, struct aws_byte_cursor name, struct aws_byte_cursor value) {
  226. AWS_PRECONDITION(headers);
  227. AWS_PRECONDITION(aws_byte_cursor_is_valid(&name) && aws_byte_cursor_is_valid(&value));
  228. const size_t prev_count = aws_http_headers_count(headers);
  229. bool pseudo = aws_strutil_is_http_pseudo_header_name(name);
  230. const size_t start = pseudo ? 1 : 0;
  231. struct aws_http_header header = {.name = name, .value = value};
  232. if (s_http_headers_add_header_impl(headers, &header, pseudo)) {
  233. return AWS_OP_ERR;
  234. }
  235. /* Erase pre-existing headers AFTER add, in case name or value was referencing their memory. */
  236. s_http_headers_erase(headers, name, start, prev_count);
  237. return AWS_OP_SUCCESS;
  238. }
  239. size_t aws_http_headers_count(const struct aws_http_headers *headers) {
  240. AWS_PRECONDITION(headers);
  241. return aws_array_list_length(&headers->array_list);
  242. }
  243. int aws_http_headers_get_index(
  244. const struct aws_http_headers *headers,
  245. size_t index,
  246. struct aws_http_header *out_header) {
  247. AWS_PRECONDITION(headers);
  248. AWS_PRECONDITION(out_header);
  249. return aws_array_list_get_at(&headers->array_list, out_header, index);
  250. }
  251. /* RFC-9110 - 5.3
  252. * A recipient MAY combine multiple field lines within a field section that
  253. * have the same field name into one field line, without changing the semantics
  254. * of the message, by appending each subsequent field line value to the initial
  255. * field line value in order, separated by a comma (",") and optional whitespace
  256. * (OWS, defined in Section 5.6.3). For consistency, use comma SP. */
  257. AWS_HTTP_API
  258. struct aws_string *aws_http_headers_get_all(const struct aws_http_headers *headers, struct aws_byte_cursor name) {
  259. AWS_PRECONDITION(headers);
  260. AWS_PRECONDITION(aws_byte_cursor_is_valid(&name));
  261. struct aws_string *value_str = NULL;
  262. const struct aws_byte_cursor separator = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL(", ");
  263. struct aws_byte_buf value_builder;
  264. aws_byte_buf_init(&value_builder, headers->alloc, 0);
  265. bool found = false;
  266. struct aws_http_header *header = NULL;
  267. const size_t count = aws_http_headers_count(headers);
  268. for (size_t i = 0; i < count; ++i) {
  269. aws_array_list_get_at_ptr(&headers->array_list, (void **)&header, i);
  270. if (aws_http_header_name_eq(name, header->name)) {
  271. if (!found) {
  272. found = true;
  273. } else {
  274. aws_byte_buf_append_dynamic(&value_builder, &separator);
  275. }
  276. aws_byte_buf_append_dynamic(&value_builder, &header->value);
  277. }
  278. }
  279. if (found) {
  280. value_str = aws_string_new_from_buf(headers->alloc, &value_builder);
  281. } else {
  282. aws_raise_error(AWS_ERROR_HTTP_HEADER_NOT_FOUND);
  283. }
  284. aws_byte_buf_clean_up(&value_builder);
  285. return value_str;
  286. }
  287. int aws_http_headers_get(
  288. const struct aws_http_headers *headers,
  289. struct aws_byte_cursor name,
  290. struct aws_byte_cursor *out_value) {
  291. AWS_PRECONDITION(headers);
  292. AWS_PRECONDITION(out_value);
  293. AWS_PRECONDITION(aws_byte_cursor_is_valid(&name));
  294. struct aws_http_header *header = NULL;
  295. const size_t count = aws_http_headers_count(headers);
  296. for (size_t i = 0; i < count; ++i) {
  297. aws_array_list_get_at_ptr(&headers->array_list, (void **)&header, i);
  298. AWS_ASSUME(header);
  299. if (aws_http_header_name_eq(header->name, name)) {
  300. *out_value = header->value;
  301. return AWS_OP_SUCCESS;
  302. }
  303. }
  304. return aws_raise_error(AWS_ERROR_HTTP_HEADER_NOT_FOUND);
  305. }
  306. bool aws_http_headers_has(const struct aws_http_headers *headers, struct aws_byte_cursor name) {
  307. struct aws_byte_cursor out_value;
  308. if (aws_http_headers_get(headers, name, &out_value)) {
  309. return false;
  310. }
  311. return true;
  312. }
  313. int aws_http2_headers_get_request_method(
  314. const struct aws_http_headers *h2_headers,
  315. struct aws_byte_cursor *out_method) {
  316. return aws_http_headers_get(h2_headers, aws_http_header_method, out_method);
  317. }
  318. int aws_http2_headers_get_request_scheme(
  319. const struct aws_http_headers *h2_headers,
  320. struct aws_byte_cursor *out_scheme) {
  321. return aws_http_headers_get(h2_headers, aws_http_header_scheme, out_scheme);
  322. }
  323. int aws_http2_headers_get_request_authority(
  324. const struct aws_http_headers *h2_headers,
  325. struct aws_byte_cursor *out_authority) {
  326. return aws_http_headers_get(h2_headers, aws_http_header_authority, out_authority);
  327. }
  328. int aws_http2_headers_get_request_path(const struct aws_http_headers *h2_headers, struct aws_byte_cursor *out_path) {
  329. return aws_http_headers_get(h2_headers, aws_http_header_path, out_path);
  330. }
  331. int aws_http2_headers_get_response_status(const struct aws_http_headers *h2_headers, int *out_status_code) {
  332. struct aws_byte_cursor status_code_cur;
  333. int return_code = aws_http_headers_get(h2_headers, aws_http_header_status, &status_code_cur);
  334. if (return_code == AWS_OP_SUCCESS) {
  335. uint64_t code_val_u64;
  336. if (aws_byte_cursor_utf8_parse_u64(status_code_cur, &code_val_u64)) {
  337. return AWS_OP_ERR;
  338. }
  339. *out_status_code = (int)code_val_u64;
  340. }
  341. return return_code;
  342. }
  343. int aws_http2_headers_set_request_method(struct aws_http_headers *h2_headers, struct aws_byte_cursor method) {
  344. return aws_http_headers_set(h2_headers, aws_http_header_method, method);
  345. }
  346. int aws_http2_headers_set_request_scheme(struct aws_http_headers *h2_headers, struct aws_byte_cursor scheme) {
  347. return aws_http_headers_set(h2_headers, aws_http_header_scheme, scheme);
  348. }
  349. int aws_http2_headers_set_request_authority(struct aws_http_headers *h2_headers, struct aws_byte_cursor authority) {
  350. return aws_http_headers_set(h2_headers, aws_http_header_authority, authority);
  351. }
  352. int aws_http2_headers_set_request_path(struct aws_http_headers *h2_headers, struct aws_byte_cursor path) {
  353. return aws_http_headers_set(h2_headers, aws_http_header_path, path);
  354. }
  355. int aws_http2_headers_set_response_status(struct aws_http_headers *h2_headers, int status_code) {
  356. /* Status code must fit in 3 digits */
  357. if (status_code < 0 || status_code > 999) {
  358. return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
  359. }
  360. char status_code_str[4] = "000";
  361. snprintf(status_code_str, sizeof(status_code_str), "%03d", status_code);
  362. struct aws_byte_cursor status_code_cur = aws_byte_cursor_from_c_str(status_code_str);
  363. return aws_http_headers_set(h2_headers, aws_http_header_status, status_code_cur);
  364. }
  365. struct aws_http_message {
  366. struct aws_allocator *allocator;
  367. struct aws_http_headers *headers;
  368. struct aws_input_stream *body_stream;
  369. struct aws_atomic_var refcount;
  370. enum aws_http_version http_version;
  371. /* Data specific to the request or response subclasses */
  372. union {
  373. struct aws_http_message_request_data {
  374. struct aws_string *method;
  375. struct aws_string *path;
  376. } request;
  377. struct aws_http_message_response_data {
  378. int status;
  379. } response;
  380. } subclass_data;
  381. struct aws_http_message_request_data *request_data;
  382. struct aws_http_message_response_data *response_data;
  383. };
  384. static int s_set_string_from_cursor(
  385. struct aws_string **dst,
  386. struct aws_byte_cursor cursor,
  387. struct aws_allocator *alloc) {
  388. AWS_PRECONDITION(dst);
  389. /* If the cursor is empty, set dst to NULL */
  390. struct aws_string *new_str;
  391. if (cursor.len) {
  392. new_str = aws_string_new_from_cursor(alloc, &cursor);
  393. if (!new_str) {
  394. return AWS_OP_ERR;
  395. }
  396. } else {
  397. new_str = NULL;
  398. }
  399. /* Replace existing value */
  400. aws_string_destroy(*dst);
  401. *dst = new_str;
  402. return AWS_OP_SUCCESS;
  403. }
  404. static struct aws_http_message *s_message_new_common(
  405. struct aws_allocator *allocator,
  406. struct aws_http_headers *existing_headers) {
  407. /* allocation cannot fail */
  408. struct aws_http_message *message = aws_mem_calloc(allocator, 1, sizeof(struct aws_http_message));
  409. message->allocator = allocator;
  410. aws_atomic_init_int(&message->refcount, 1);
  411. if (existing_headers) {
  412. message->headers = existing_headers;
  413. aws_http_headers_acquire(message->headers);
  414. } else {
  415. message->headers = aws_http_headers_new(allocator);
  416. if (!message->headers) {
  417. goto error;
  418. }
  419. }
  420. return message;
  421. error:
  422. aws_http_message_destroy(message);
  423. return NULL;
  424. }
  425. static struct aws_http_message *s_message_new_request_common(
  426. struct aws_allocator *allocator,
  427. struct aws_http_headers *existing_headers,
  428. enum aws_http_version version) {
  429. struct aws_http_message *message = s_message_new_common(allocator, existing_headers);
  430. if (message) {
  431. message->request_data = &message->subclass_data.request;
  432. message->http_version = version;
  433. }
  434. return message;
  435. }
  436. struct aws_http_message *aws_http_message_new_request_with_headers(
  437. struct aws_allocator *allocator,
  438. struct aws_http_headers *existing_headers) {
  439. AWS_PRECONDITION(allocator);
  440. AWS_PRECONDITION(existing_headers);
  441. return s_message_new_request_common(allocator, existing_headers, AWS_HTTP_VERSION_1_1);
  442. }
  443. struct aws_http_message *aws_http_message_new_request(struct aws_allocator *allocator) {
  444. AWS_PRECONDITION(allocator);
  445. return s_message_new_request_common(allocator, NULL, AWS_HTTP_VERSION_1_1);
  446. }
  447. struct aws_http_message *aws_http2_message_new_request(struct aws_allocator *allocator) {
  448. AWS_PRECONDITION(allocator);
  449. return s_message_new_request_common(allocator, NULL, AWS_HTTP_VERSION_2);
  450. }
  451. static struct aws_http_message *s_http_message_new_response_common(
  452. struct aws_allocator *allocator,
  453. enum aws_http_version version) {
  454. AWS_PRECONDITION(allocator);
  455. struct aws_http_message *message = s_message_new_common(allocator, NULL);
  456. if (message) {
  457. message->response_data = &message->subclass_data.response;
  458. message->response_data->status = AWS_HTTP_STATUS_CODE_UNKNOWN;
  459. message->http_version = version;
  460. }
  461. return message;
  462. }
  463. struct aws_http_message *aws_http_message_new_response(struct aws_allocator *allocator) {
  464. AWS_PRECONDITION(allocator);
  465. return s_http_message_new_response_common(allocator, AWS_HTTP_VERSION_1_1);
  466. }
  467. struct aws_http_message *aws_http2_message_new_response(struct aws_allocator *allocator) {
  468. AWS_PRECONDITION(allocator);
  469. return s_http_message_new_response_common(allocator, AWS_HTTP_VERSION_2);
  470. }
  471. void aws_http_message_destroy(struct aws_http_message *message) {
  472. aws_http_message_release(message);
  473. }
  474. struct aws_http_message *aws_http_message_release(struct aws_http_message *message) {
  475. /* Note that release() may also be used by new() functions to clean up if something goes wrong */
  476. AWS_PRECONDITION(!message || message->allocator);
  477. if (!message) {
  478. return NULL;
  479. }
  480. size_t prev_refcount = aws_atomic_fetch_sub(&message->refcount, 1);
  481. if (prev_refcount == 1) {
  482. if (message->request_data) {
  483. aws_string_destroy(message->request_data->method);
  484. aws_string_destroy(message->request_data->path);
  485. }
  486. aws_http_headers_release(message->headers);
  487. aws_input_stream_release(message->body_stream);
  488. aws_mem_release(message->allocator, message);
  489. } else {
  490. AWS_ASSERT(prev_refcount != 0);
  491. }
  492. return NULL;
  493. }
  494. struct aws_http_message *aws_http_message_acquire(struct aws_http_message *message) {
  495. if (message != NULL) {
  496. aws_atomic_fetch_add(&message->refcount, 1);
  497. }
  498. return message;
  499. }
  500. bool aws_http_message_is_request(const struct aws_http_message *message) {
  501. AWS_PRECONDITION(message);
  502. return message->request_data;
  503. }
  504. bool aws_http_message_is_response(const struct aws_http_message *message) {
  505. AWS_PRECONDITION(message);
  506. return message->response_data;
  507. }
  508. enum aws_http_version aws_http_message_get_protocol_version(const struct aws_http_message *message) {
  509. AWS_PRECONDITION(message);
  510. return message->http_version;
  511. }
  512. int aws_http_message_set_request_method(struct aws_http_message *request_message, struct aws_byte_cursor method) {
  513. AWS_PRECONDITION(request_message);
  514. AWS_PRECONDITION(aws_byte_cursor_is_valid(&method));
  515. AWS_PRECONDITION(request_message->request_data);
  516. if (request_message->request_data) {
  517. switch (request_message->http_version) {
  518. case AWS_HTTP_VERSION_1_1:
  519. return s_set_string_from_cursor(
  520. &request_message->request_data->method, method, request_message->allocator);
  521. case AWS_HTTP_VERSION_2:
  522. return aws_http2_headers_set_request_method(request_message->headers, method);
  523. default:
  524. return aws_raise_error(AWS_ERROR_UNIMPLEMENTED);
  525. }
  526. }
  527. return aws_raise_error(AWS_ERROR_INVALID_STATE);
  528. }
  529. int aws_http_message_get_request_method(
  530. const struct aws_http_message *request_message,
  531. struct aws_byte_cursor *out_method) {
  532. AWS_PRECONDITION(request_message);
  533. AWS_PRECONDITION(out_method);
  534. AWS_PRECONDITION(request_message->request_data);
  535. int error = AWS_ERROR_HTTP_DATA_NOT_AVAILABLE;
  536. if (request_message->request_data) {
  537. switch (request_message->http_version) {
  538. case AWS_HTTP_VERSION_1_1:
  539. if (request_message->request_data->method) {
  540. *out_method = aws_byte_cursor_from_string(request_message->request_data->method);
  541. return AWS_OP_SUCCESS;
  542. }
  543. break;
  544. case AWS_HTTP_VERSION_2:
  545. return aws_http2_headers_get_request_method(request_message->headers, out_method);
  546. default:
  547. error = AWS_ERROR_UNIMPLEMENTED;
  548. }
  549. }
  550. AWS_ZERO_STRUCT(*out_method);
  551. return aws_raise_error(error);
  552. }
  553. int aws_http_message_set_request_path(struct aws_http_message *request_message, struct aws_byte_cursor path) {
  554. AWS_PRECONDITION(request_message);
  555. AWS_PRECONDITION(aws_byte_cursor_is_valid(&path));
  556. AWS_PRECONDITION(request_message->request_data);
  557. if (request_message->request_data) {
  558. switch (request_message->http_version) {
  559. case AWS_HTTP_VERSION_1_1:
  560. return s_set_string_from_cursor(&request_message->request_data->path, path, request_message->allocator);
  561. case AWS_HTTP_VERSION_2:
  562. return aws_http2_headers_set_request_path(request_message->headers, path);
  563. default:
  564. return aws_raise_error(AWS_ERROR_UNIMPLEMENTED);
  565. }
  566. }
  567. return aws_raise_error(AWS_ERROR_INVALID_STATE);
  568. }
  569. int aws_http_message_get_request_path(
  570. const struct aws_http_message *request_message,
  571. struct aws_byte_cursor *out_path) {
  572. AWS_PRECONDITION(request_message);
  573. AWS_PRECONDITION(out_path);
  574. AWS_PRECONDITION(request_message->request_data);
  575. if (request_message->request_data) {
  576. switch (request_message->http_version) {
  577. case AWS_HTTP_VERSION_1_1:
  578. if (request_message->request_data->path) {
  579. *out_path = aws_byte_cursor_from_string(request_message->request_data->path);
  580. return AWS_OP_SUCCESS;
  581. }
  582. break;
  583. case AWS_HTTP_VERSION_2:
  584. return aws_http2_headers_get_request_path(request_message->headers, out_path);
  585. default:
  586. return aws_raise_error(AWS_ERROR_UNIMPLEMENTED);
  587. }
  588. }
  589. AWS_ZERO_STRUCT(*out_path);
  590. return aws_raise_error(AWS_ERROR_HTTP_DATA_NOT_AVAILABLE);
  591. }
  592. int aws_http_message_get_response_status(const struct aws_http_message *response_message, int *out_status_code) {
  593. AWS_PRECONDITION(response_message);
  594. AWS_PRECONDITION(out_status_code);
  595. AWS_PRECONDITION(response_message->response_data);
  596. *out_status_code = AWS_HTTP_STATUS_CODE_UNKNOWN;
  597. if (response_message->response_data) {
  598. switch (response_message->http_version) {
  599. case AWS_HTTP_VERSION_1_1:
  600. if (response_message->response_data->status != AWS_HTTP_STATUS_CODE_UNKNOWN) {
  601. *out_status_code = response_message->response_data->status;
  602. return AWS_OP_SUCCESS;
  603. }
  604. break;
  605. case AWS_HTTP_VERSION_2:
  606. return aws_http2_headers_get_response_status(response_message->headers, out_status_code);
  607. default:
  608. return aws_raise_error(AWS_ERROR_UNIMPLEMENTED);
  609. }
  610. }
  611. return aws_raise_error(AWS_ERROR_HTTP_DATA_NOT_AVAILABLE);
  612. }
  613. int aws_http_message_set_response_status(struct aws_http_message *response_message, int status_code) {
  614. AWS_PRECONDITION(response_message);
  615. AWS_PRECONDITION(response_message->response_data);
  616. if (response_message->response_data) {
  617. /* Status code must be printable with exactly 3 digits */
  618. if (status_code >= 0 && status_code <= 999) {
  619. switch (response_message->http_version) {
  620. case AWS_HTTP_VERSION_1_1:
  621. response_message->response_data->status = status_code;
  622. return AWS_OP_SUCCESS;
  623. case AWS_HTTP_VERSION_2:
  624. return aws_http2_headers_set_response_status(response_message->headers, status_code);
  625. default:
  626. return aws_raise_error(AWS_ERROR_UNIMPLEMENTED);
  627. }
  628. }
  629. return aws_raise_error(AWS_ERROR_HTTP_INVALID_STATUS_CODE);
  630. }
  631. return aws_raise_error(AWS_ERROR_INVALID_STATE);
  632. }
  633. void aws_http_message_set_body_stream(struct aws_http_message *message, struct aws_input_stream *body_stream) {
  634. AWS_PRECONDITION(message);
  635. /* release previous stream, if any */
  636. aws_input_stream_release(message->body_stream);
  637. message->body_stream = body_stream;
  638. if (message->body_stream) {
  639. aws_input_stream_acquire(message->body_stream);
  640. }
  641. }
  642. int aws_http1_stream_write_chunk(struct aws_http_stream *http1_stream, const struct aws_http1_chunk_options *options) {
  643. AWS_PRECONDITION(http1_stream);
  644. AWS_PRECONDITION(http1_stream->vtable);
  645. AWS_PRECONDITION(options);
  646. if (!http1_stream->vtable->http1_write_chunk) {
  647. AWS_LOGF_TRACE(
  648. AWS_LS_HTTP_STREAM,
  649. "id=%p: HTTP/1 stream only function invoked on other stream, ignoring call.",
  650. (void *)http1_stream);
  651. return aws_raise_error(AWS_ERROR_INVALID_STATE);
  652. }
  653. return http1_stream->vtable->http1_write_chunk(http1_stream, options);
  654. }
  655. int aws_http2_stream_write_data(
  656. struct aws_http_stream *http2_stream,
  657. const struct aws_http2_stream_write_data_options *options) {
  658. AWS_PRECONDITION(http2_stream);
  659. AWS_PRECONDITION(http2_stream->vtable);
  660. AWS_PRECONDITION(http2_stream->vtable->http2_write_data);
  661. AWS_PRECONDITION(options);
  662. return http2_stream->vtable->http2_write_data(http2_stream, options);
  663. }
  664. int aws_http1_stream_add_chunked_trailer(
  665. struct aws_http_stream *http1_stream,
  666. const struct aws_http_headers *trailing_headers) {
  667. AWS_PRECONDITION(http1_stream);
  668. AWS_PRECONDITION(http1_stream->vtable);
  669. AWS_PRECONDITION(trailing_headers);
  670. if (!http1_stream->vtable->http1_add_trailer) {
  671. AWS_LOGF_TRACE(
  672. AWS_LS_HTTP_STREAM,
  673. "id=%p: HTTP/1 stream only function invoked on other stream, ignoring call.",
  674. (void *)http1_stream);
  675. return aws_raise_error(AWS_ERROR_INVALID_STATE);
  676. }
  677. return http1_stream->vtable->http1_add_trailer(http1_stream, trailing_headers);
  678. }
  679. struct aws_input_stream *aws_http_message_get_body_stream(const struct aws_http_message *message) {
  680. AWS_PRECONDITION(message);
  681. return message->body_stream;
  682. }
  683. struct aws_http_headers *aws_http_message_get_headers(const struct aws_http_message *message) {
  684. AWS_PRECONDITION(message);
  685. return message->headers;
  686. }
  687. const struct aws_http_headers *aws_http_message_get_const_headers(const struct aws_http_message *message) {
  688. AWS_PRECONDITION(message);
  689. return message->headers;
  690. }
  691. int aws_http_message_add_header(struct aws_http_message *message, struct aws_http_header header) {
  692. return aws_http_headers_add(message->headers, header.name, header.value);
  693. }
  694. int aws_http_message_add_header_array(
  695. struct aws_http_message *message,
  696. const struct aws_http_header *headers,
  697. size_t num_headers) {
  698. return aws_http_headers_add_array(message->headers, headers, num_headers);
  699. }
  700. int aws_http_message_erase_header(struct aws_http_message *message, size_t index) {
  701. return aws_http_headers_erase_index(message->headers, index);
  702. }
  703. size_t aws_http_message_get_header_count(const struct aws_http_message *message) {
  704. return aws_http_headers_count(message->headers);
  705. }
  706. int aws_http_message_get_header(
  707. const struct aws_http_message *message,
  708. struct aws_http_header *out_header,
  709. size_t index) {
  710. return aws_http_headers_get_index(message->headers, index, out_header);
  711. }
  712. struct aws_http_stream *aws_http_connection_make_request(
  713. struct aws_http_connection *client_connection,
  714. const struct aws_http_make_request_options *options) {
  715. AWS_PRECONDITION(client_connection);
  716. AWS_PRECONDITION(aws_http_connection_is_client(client_connection));
  717. AWS_PRECONDITION(options);
  718. if (options->self_size == 0 || !options->request || !aws_http_message_is_request(options->request)) {
  719. AWS_LOGF_ERROR(
  720. AWS_LS_HTTP_CONNECTION,
  721. "id=%p: Cannot create client request, options are invalid.",
  722. (void *)client_connection);
  723. aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
  724. return NULL;
  725. }
  726. /* Connection owns stream, and must outlive stream */
  727. aws_http_connection_acquire(client_connection);
  728. struct aws_http_stream *stream = client_connection->vtable->make_request(client_connection, options);
  729. if (!stream) {
  730. aws_http_connection_release(client_connection);
  731. return NULL;
  732. }
  733. return stream;
  734. }
  735. struct aws_http_message *aws_http2_message_new_from_http1(
  736. struct aws_allocator *alloc,
  737. const struct aws_http_message *http1_msg) {
  738. struct aws_http_headers *old_headers = aws_http_message_get_headers(http1_msg);
  739. struct aws_http_header header_iter;
  740. struct aws_byte_buf lower_name_buf;
  741. AWS_ZERO_STRUCT(lower_name_buf);
  742. struct aws_http_message *message = aws_http_message_is_request(http1_msg) ? aws_http2_message_new_request(alloc)
  743. : aws_http2_message_new_response(alloc);
  744. if (!message) {
  745. return NULL;
  746. }
  747. struct aws_http_headers *copied_headers = message->headers;
  748. AWS_LOGF_TRACE(AWS_LS_HTTP_GENERAL, "Creating HTTP/2 message from HTTP/1 message id: %p", (void *)http1_msg);
  749. /* Set pseudo headers from HTTP/1.1 message */
  750. if (aws_http_message_is_request(http1_msg)) {
  751. struct aws_byte_cursor method;
  752. if (aws_http_message_get_request_method(http1_msg, &method)) {
  753. AWS_LOGF_ERROR(
  754. AWS_LS_HTTP_GENERAL,
  755. "Failed to create HTTP/2 message from HTTP/1 message, ip: %p, due to no method found.",
  756. (void *)http1_msg);
  757. /* error will happen when the request is invalid */
  758. aws_raise_error(AWS_ERROR_HTTP_INVALID_METHOD);
  759. goto error;
  760. }
  761. /* Use add instead of set method to avoid push front to the array list */
  762. if (aws_http_headers_add(copied_headers, aws_http_header_method, method)) {
  763. goto error;
  764. }
  765. AWS_LOGF_TRACE(
  766. AWS_LS_HTTP_GENERAL,
  767. "Added header to new HTTP/2 header - \"%.*s\": \"%.*s\" ",
  768. (int)aws_http_header_method.len,
  769. aws_http_header_method.ptr,
  770. (int)method.len,
  771. method.ptr);
  772. /**
  773. * we set a default value, "https", for now.
  774. * TODO: as we support prior knowledge, we may also want to support http?
  775. */
  776. struct aws_byte_cursor scheme_cursor = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("https");
  777. if (aws_http_headers_add(copied_headers, aws_http_header_scheme, scheme_cursor)) {
  778. goto error;
  779. }
  780. AWS_LOGF_TRACE(
  781. AWS_LS_HTTP_GENERAL,
  782. "Added header to new HTTP/2 header - \"%.*s\": \"%.*s\" ",
  783. (int)aws_http_header_scheme.len,
  784. aws_http_header_scheme.ptr,
  785. (int)scheme_cursor.len,
  786. scheme_cursor.ptr);
  787. /**
  788. * An intermediary that forwards a request over HTTP/2 MUST construct an ":authority" pseudo-header field using
  789. * the authority information from the control data of the original request. (RFC=9113 8.3.1)
  790. */
  791. struct aws_byte_cursor host_value;
  792. AWS_ZERO_STRUCT(host_value);
  793. if (aws_http_headers_get(http1_msg->headers, aws_byte_cursor_from_c_str("host"), &host_value) ==
  794. AWS_OP_SUCCESS) {
  795. if (aws_http_headers_add(copied_headers, aws_http_header_authority, host_value)) {
  796. goto error;
  797. }
  798. AWS_LOGF_TRACE(
  799. AWS_LS_HTTP_GENERAL,
  800. "Added header to new HTTP/2 header - \"%.*s\": \"%.*s\" ",
  801. (int)aws_http_header_authority.len,
  802. aws_http_header_authority.ptr,
  803. (int)host_value.len,
  804. host_value.ptr);
  805. }
  806. /* TODO: If the host headers is missing, the target URI could be the other source of the authority information
  807. */
  808. struct aws_byte_cursor path_cursor;
  809. if (aws_http_message_get_request_path(http1_msg, &path_cursor)) {
  810. AWS_LOGF_ERROR(
  811. AWS_LS_HTTP_GENERAL,
  812. "Failed to create HTTP/2 message from HTTP/1 message, ip: %p, due to no path found.",
  813. (void *)http1_msg);
  814. aws_raise_error(AWS_ERROR_HTTP_INVALID_PATH);
  815. goto error;
  816. }
  817. if (aws_http_headers_add(copied_headers, aws_http_header_path, path_cursor)) {
  818. goto error;
  819. }
  820. AWS_LOGF_TRACE(
  821. AWS_LS_HTTP_GENERAL,
  822. "Added header to new HTTP/2 header - \"%.*s\": \"%.*s\" ",
  823. (int)aws_http_header_path.len,
  824. aws_http_header_path.ptr,
  825. (int)path_cursor.len,
  826. path_cursor.ptr);
  827. } else {
  828. int status = 0;
  829. if (aws_http_message_get_response_status(http1_msg, &status)) {
  830. AWS_LOGF_ERROR(
  831. AWS_LS_HTTP_GENERAL,
  832. "Failed to create HTTP/2 response message from HTTP/1 response message, ip: %p, due to no status "
  833. "found.",
  834. (void *)http1_msg);
  835. /* error will happen when the request is invalid */
  836. aws_raise_error(AWS_ERROR_HTTP_INVALID_STATUS_CODE);
  837. goto error;
  838. }
  839. if (aws_http2_headers_set_response_status(copied_headers, status)) {
  840. goto error;
  841. }
  842. AWS_LOGF_TRACE(
  843. AWS_LS_HTTP_GENERAL,
  844. "Added header to new HTTP/2 header - \"%.*s\": \"%d\" ",
  845. (int)aws_http_header_status.len,
  846. aws_http_header_status.ptr,
  847. status);
  848. }
  849. if (aws_byte_buf_init(&lower_name_buf, alloc, 256)) {
  850. goto error;
  851. }
  852. for (size_t iter = 0; iter < aws_http_headers_count(old_headers); iter++) {
  853. aws_byte_buf_reset(&lower_name_buf, false);
  854. bool copy_header = true;
  855. /* name should be converted to lower case */
  856. if (aws_http_headers_get_index(old_headers, iter, &header_iter)) {
  857. goto error;
  858. }
  859. /* append lower case name to the buffer */
  860. aws_byte_buf_append_with_lookup(&lower_name_buf, &header_iter.name, aws_lookup_table_to_lower_get());
  861. struct aws_byte_cursor lower_name_cursor = aws_byte_cursor_from_buf(&lower_name_buf);
  862. enum aws_http_header_name name_enum = aws_http_lowercase_str_to_header_name(lower_name_cursor);
  863. switch (name_enum) {
  864. case AWS_HTTP_HEADER_TRANSFER_ENCODING:
  865. case AWS_HTTP_HEADER_UPGRADE:
  866. case AWS_HTTP_HEADER_KEEP_ALIVE:
  867. case AWS_HTTP_HEADER_PROXY_CONNECTION:
  868. case AWS_HTTP_HEADER_HOST:
  869. /**
  870. * An intermediary transforming an HTTP/1.x message to HTTP/2 MUST remove connection-specific header
  871. * fields as discussed in Section 7.6.1 of [HTTP]. (RFC=9113 8.2.2)
  872. */
  873. AWS_LOGF_TRACE(
  874. AWS_LS_HTTP_GENERAL,
  875. "Skip connection-specific headers - \"%.*s\" ",
  876. (int)lower_name_cursor.len,
  877. lower_name_cursor.ptr);
  878. copy_header = false;
  879. break;
  880. default:
  881. break;
  882. }
  883. if (copy_header) {
  884. if (aws_http_headers_add(copied_headers, lower_name_cursor, header_iter.value)) {
  885. goto error;
  886. }
  887. AWS_LOGF_TRACE(
  888. AWS_LS_HTTP_GENERAL,
  889. "Added header to new HTTP/2 header - \"%.*s\": \"%.*s\" ",
  890. (int)lower_name_cursor.len,
  891. lower_name_cursor.ptr,
  892. (int)header_iter.value.len,
  893. header_iter.value.ptr);
  894. }
  895. }
  896. aws_byte_buf_clean_up(&lower_name_buf);
  897. aws_http_message_set_body_stream(message, aws_http_message_get_body_stream(http1_msg));
  898. return message;
  899. error:
  900. aws_http_message_release(message);
  901. aws_byte_buf_clean_up(&lower_name_buf);
  902. return NULL;
  903. }
  904. int aws_http_stream_activate(struct aws_http_stream *stream) {
  905. AWS_PRECONDITION(stream);
  906. AWS_PRECONDITION(stream->vtable);
  907. AWS_PRECONDITION(stream->vtable->activate);
  908. /* make sure it's actually a client calling us. This is always a programmer bug, so just assert and die. */
  909. AWS_PRECONDITION(aws_http_connection_is_client(stream->owning_connection));
  910. return stream->vtable->activate(stream);
  911. }
  912. struct aws_http_stream *aws_http_stream_new_server_request_handler(
  913. const struct aws_http_request_handler_options *options) {
  914. AWS_PRECONDITION(options);
  915. if (options->self_size == 0 || !options->server_connection ||
  916. !aws_http_connection_is_server(options->server_connection)) {
  917. AWS_LOGF_ERROR(
  918. AWS_LS_HTTP_CONNECTION,
  919. "id=%p: Cannot create server request handler stream, options are invalid.",
  920. (void *)options->server_connection);
  921. aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
  922. return NULL;
  923. }
  924. return options->server_connection->vtable->new_server_request_handler_stream(options);
  925. }
  926. int aws_http_stream_send_response(struct aws_http_stream *stream, struct aws_http_message *response) {
  927. AWS_PRECONDITION(stream);
  928. AWS_PRECONDITION(response);
  929. AWS_PRECONDITION(aws_http_message_is_response(response));
  930. return stream->owning_connection->vtable->stream_send_response(stream, response);
  931. }
  932. void aws_http_stream_release(struct aws_http_stream *stream) {
  933. if (!stream) {
  934. return;
  935. }
  936. size_t prev_refcount = aws_atomic_fetch_sub(&stream->refcount, 1);
  937. if (prev_refcount == 1) {
  938. AWS_LOGF_TRACE(AWS_LS_HTTP_STREAM, "id=%p: Final stream refcount released.", (void *)stream);
  939. void *user_data = stream->user_data;
  940. aws_http_on_stream_destroy_fn *on_destroy_callback = stream->on_destroy;
  941. struct aws_http_connection *owning_connection = stream->owning_connection;
  942. stream->vtable->destroy(stream);
  943. if (on_destroy_callback) {
  944. /* info user that destroy completed. */
  945. on_destroy_callback(user_data);
  946. }
  947. /* Connection needed to outlive stream, but it's free to go now */
  948. aws_http_connection_release(owning_connection);
  949. } else {
  950. AWS_ASSERT(prev_refcount != 0);
  951. AWS_LOGF_TRACE(
  952. AWS_LS_HTTP_STREAM, "id=%p: Stream refcount released, %zu remaining.", (void *)stream, prev_refcount - 1);
  953. }
  954. }
  955. struct aws_http_connection *aws_http_stream_get_connection(const struct aws_http_stream *stream) {
  956. AWS_ASSERT(stream);
  957. return stream->owning_connection;
  958. }
  959. int aws_http_stream_get_incoming_response_status(const struct aws_http_stream *stream, int *out_status) {
  960. AWS_ASSERT(stream && stream->client_data);
  961. if (stream->client_data->response_status == (int)AWS_HTTP_STATUS_CODE_UNKNOWN) {
  962. AWS_LOGF_ERROR(AWS_LS_HTTP_STREAM, "id=%p: Status code not yet received.", (void *)stream);
  963. return aws_raise_error(AWS_ERROR_HTTP_DATA_NOT_AVAILABLE);
  964. }
  965. *out_status = stream->client_data->response_status;
  966. return AWS_OP_SUCCESS;
  967. }
  968. int aws_http_stream_get_incoming_request_method(
  969. const struct aws_http_stream *stream,
  970. struct aws_byte_cursor *out_method) {
  971. AWS_ASSERT(stream && stream->server_data);
  972. if (!stream->server_data->request_method_str.ptr) {
  973. AWS_LOGF_ERROR(AWS_LS_HTTP_STREAM, "id=%p: Request method not yet received.", (void *)stream);
  974. return aws_raise_error(AWS_ERROR_HTTP_DATA_NOT_AVAILABLE);
  975. }
  976. *out_method = stream->server_data->request_method_str;
  977. return AWS_OP_SUCCESS;
  978. }
  979. int aws_http_stream_get_incoming_request_uri(const struct aws_http_stream *stream, struct aws_byte_cursor *out_uri) {
  980. AWS_ASSERT(stream && stream->server_data);
  981. if (!stream->server_data->request_path.ptr) {
  982. AWS_LOGF_ERROR(AWS_LS_HTTP_STREAM, "id=%p: Request URI not yet received.", (void *)stream);
  983. return aws_raise_error(AWS_ERROR_HTTP_DATA_NOT_AVAILABLE);
  984. }
  985. *out_uri = stream->server_data->request_path;
  986. return AWS_OP_SUCCESS;
  987. }
  988. void aws_http_stream_update_window(struct aws_http_stream *stream, size_t increment_size) {
  989. stream->vtable->update_window(stream, increment_size);
  990. }
  991. uint32_t aws_http_stream_get_id(const struct aws_http_stream *stream) {
  992. return stream->id;
  993. }
  994. int aws_http2_stream_reset(struct aws_http_stream *http2_stream, uint32_t http2_error) {
  995. AWS_PRECONDITION(http2_stream);
  996. AWS_PRECONDITION(http2_stream->vtable);
  997. if (!http2_stream->vtable->http2_reset_stream) {
  998. AWS_LOGF_TRACE(
  999. AWS_LS_HTTP_STREAM,
  1000. "id=%p: HTTP/2 stream only function invoked on other stream, ignoring call.",
  1001. (void *)http2_stream);
  1002. return aws_raise_error(AWS_ERROR_INVALID_STATE);
  1003. }
  1004. return http2_stream->vtable->http2_reset_stream(http2_stream, http2_error);
  1005. }
  1006. int aws_http2_stream_get_received_reset_error_code(struct aws_http_stream *http2_stream, uint32_t *out_http2_error) {
  1007. AWS_PRECONDITION(http2_stream);
  1008. AWS_PRECONDITION(http2_stream->vtable);
  1009. AWS_PRECONDITION(out_http2_error);
  1010. if (!http2_stream->vtable->http2_get_received_error_code) {
  1011. AWS_LOGF_TRACE(
  1012. AWS_LS_HTTP_STREAM,
  1013. "id=%p: HTTP/2 stream only function invoked on other stream, ignoring call.",
  1014. (void *)http2_stream);
  1015. return aws_raise_error(AWS_ERROR_INVALID_STATE);
  1016. }
  1017. return http2_stream->vtable->http2_get_received_error_code(http2_stream, out_http2_error);
  1018. }
  1019. int aws_http2_stream_get_sent_reset_error_code(struct aws_http_stream *http2_stream, uint32_t *out_http2_error) {
  1020. AWS_PRECONDITION(http2_stream);
  1021. AWS_PRECONDITION(http2_stream->vtable);
  1022. AWS_PRECONDITION(out_http2_error);
  1023. if (!http2_stream->vtable->http2_get_sent_error_code) {
  1024. AWS_LOGF_TRACE(
  1025. AWS_LS_HTTP_STREAM,
  1026. "id=%p: HTTP/2 stream only function invoked on other stream, ignoring call.",
  1027. (void *)http2_stream);
  1028. return aws_raise_error(AWS_ERROR_INVALID_STATE);
  1029. }
  1030. return http2_stream->vtable->http2_get_sent_error_code(http2_stream, out_http2_error);
  1031. }