@@ -38,6 +38,22 @@ struct aws_http_header {
3838 struct aws_byte_cursor value ;
3939};
4040
41+ /**
42+ * A transformable block of HTTP headers.
43+ * Provides a nice API for getting/setting header names and values.
44+ *
45+ * All strings are copied and stored within this datastructure.
46+ * The index of a given header may change any time headers are modified.
47+ * When iterating headers, the following ordering rules apply:
48+ *
49+ * - Headers with the same name will always be in the same order, relative to one another.
50+ * If "A: one" is added before "A: two", then "A: one" will always precede "A: two".
51+ *
52+ * - Headers with different names could be in any order, relative to one another.
53+ * If "A: one" is seen before "B: bee" in one iteration, you might see "B: bee" before "A: one" on the next.
54+ */
55+ struct aws_http_headers ;
56+
4157/**
4258 * Header block type.
4359 * INFORMATIONAL: Header block for 1xx informational (interim) responses.
@@ -272,22 +288,162 @@ struct aws_http_request_handler_options {
272288
273289AWS_EXTERN_C_BEGIN
274290
291+ /**
292+ * Return whether both names are equivalent.
293+ * This is a case-insensitive string comparison.
294+ *
295+ * Example Matches:
296+ * "Content-Length" == "content-length" // upper or lower case ok
297+
298+ * Example Mismatches:
299+ * "Content-Length" != " Content-Length" // leading whitespace bad
300+ */
301+ AWS_HTTP_API
302+ bool aws_http_header_name_eq (struct aws_byte_cursor name_a , struct aws_byte_cursor name_b );
303+
304+ /**
305+ * Create a new headers object.
306+ * The caller has a hold on the object and must call aws_http_headers_release() when they are done with it.
307+ */
308+ AWS_HTTP_API
309+ struct aws_http_headers * aws_http_headers_new (struct aws_allocator * allocator );
310+
311+ /**
312+ * Acquire a hold on the object, preventing it from being deleted until
313+ * aws_http_headers_release() is called by all those with a hold on it.
314+ */
315+ AWS_HTTP_API
316+ void aws_http_headers_acquire (struct aws_http_headers * headers );
317+
318+ /**
319+ * Release a hold on the object.
320+ * The object is deleted when all holds on it are released.
321+ */
322+ AWS_HTTP_API
323+ void aws_http_headers_release (struct aws_http_headers * headers );
324+
325+ /**
326+ * Add a header.
327+ * The underlying strings are copied.
328+ */
329+ AWS_HTTP_API
330+ int aws_http_headers_add (struct aws_http_headers * headers , struct aws_byte_cursor name , struct aws_byte_cursor value );
331+
332+ /**
333+ * Add an array of headers.
334+ * The underlying strings are copied.
335+ */
336+ AWS_HTTP_API
337+ int aws_http_headers_add_array (struct aws_http_headers * headers , const struct aws_http_header * array , size_t count );
338+
339+ /**
340+ * Set a header value.
341+ * The header is added if necessary and any existing values for this name are removed.
342+ * The underlying strings are copied.
343+ */
344+ AWS_HTTP_API
345+ int aws_http_headers_set (struct aws_http_headers * headers , struct aws_byte_cursor name , struct aws_byte_cursor value );
346+
347+ /**
348+ * Get the total number of headers.
349+ */
350+ AWS_HTTP_API
351+ size_t aws_http_headers_count (const struct aws_http_headers * headers );
352+
353+ /**
354+ * Get the header at the specified index.
355+ * The index of a given header may change any time headers are modified.
356+ * When iterating headers, the following ordering rules apply:
357+ *
358+ * - Headers with the same name will always be in the same order, relative to one another.
359+ * If "A: one" is added before "A: two", then "A: one" will always precede "A: two".
360+ *
361+ * - Headers with different names could be in any order, relative to one another.
362+ * If "A: one" is seen before "B: bee" in one iteration, you might see "B: bee" before "A: one" on the next.
363+ *
364+ * AWS_ERROR_INVALID_INDEX is raised if the index is invalid.
365+ */
366+ AWS_HTTP_API
367+ int aws_http_headers_get_index (
368+ const struct aws_http_headers * headers ,
369+ size_t index ,
370+ struct aws_http_header * out_header );
371+
372+ /**
373+ * Get the first value for this name, ignoring any additional values.
374+ * AWS_ERROR_HTTP_HEADER_NOT_FOUND is raised if the name is not found.
375+ */
376+ AWS_HTTP_API
377+ int aws_http_headers_get (
378+ const struct aws_http_headers * headers ,
379+ struct aws_byte_cursor name ,
380+ struct aws_byte_cursor * out_value );
381+
382+ /**
383+ * Remove all headers with this name.
384+ * AWS_ERROR_HTTP_HEADER_NOT_FOUND is raised if no headers with this name are found.
385+ */
386+ AWS_HTTP_API
387+ int aws_http_headers_erase (struct aws_http_headers * headers , struct aws_byte_cursor name );
388+
389+ /**
390+ * Remove the first header found with this name and value.
391+ * AWS_ERROR_HTTP_HEADER_NOT_FOUND is raised if no such header is found.
392+ */
393+ AWS_HTTP_API
394+ int aws_http_headers_erase_value (
395+ struct aws_http_headers * headers ,
396+ struct aws_byte_cursor name ,
397+ struct aws_byte_cursor value );
398+
399+ /**
400+ * Remove the header at the specified index.
401+ *
402+ * AWS_ERROR_INVALID_INDEX is raised if the index is invalid.
403+ */
404+ AWS_HTTP_API
405+ int aws_http_headers_erase_index (struct aws_http_headers * headers , size_t index );
406+
407+ /**
408+ * Clear all headers.
409+ */
410+ AWS_HTTP_API
411+ void aws_http_headers_clear (struct aws_http_headers * headers );
412+
275413/**
276414 * Create a new request message.
277415 * The message is blank, all properties (method, path, etc) must be set individually.
416+ *
417+ * The caller has a hold on the object and must call aws_http_message_release() when they are done with it.
278418 */
279419AWS_HTTP_API
280420struct aws_http_message * aws_http_message_new_request (struct aws_allocator * allocator );
281421
282422/**
283423 * Create a new response message.
284424 * The message is blank, all properties (status, headers, etc) must be set individually.
425+ *
426+ * The caller has a hold on the object and must call aws_http_message_release() when they are done with it.
285427 */
286428AWS_HTTP_API
287429struct aws_http_message * aws_http_message_new_response (struct aws_allocator * allocator );
288430
289431/**
290- * Destroy the message.
432+ * Acquire a hold on the object, preventing it from being deleted until
433+ * aws_http_message_release() is called by all those with a hold on it.
434+ */
435+ AWS_HTTP_API
436+ void aws_http_message_acquire (struct aws_http_message * message );
437+
438+ /**
439+ * Release a hold on the object.
440+ * The object is deleted when all holds on it are released.
441+ */
442+ AWS_HTTP_API
443+ void aws_http_message_release (struct aws_http_message * message );
444+
445+ /**
446+ * Deprecated. This is equivalent to aws_http_message_release().
291447 */
292448AWS_HTTP_API
293449void aws_http_message_destroy (struct aws_http_message * message );
@@ -355,6 +511,19 @@ struct aws_input_stream *aws_http_message_get_body_stream(const struct aws_http_
355511AWS_HTTP_API
356512void aws_http_message_set_body_stream (struct aws_http_message * message , struct aws_input_stream * body_stream );
357513
514+ /**
515+ * Get the message's aws_http_headers.
516+ *
517+ * This datastructure has more functions for inspecting and modifying headers than
518+ * are available on the aws_http_message datastructure.
519+ */
520+ struct aws_http_headers * aws_http_message_get_headers (struct aws_http_message * message );
521+
522+ /**
523+ * Get the message's const aws_http_headers.
524+ */
525+ const struct aws_http_headers * aws_http_message_get_const_headers (const struct aws_http_message * message );
526+
358527/**
359528 * Get the number of headers.
360529 */
@@ -394,14 +563,6 @@ int aws_http_message_add_header_array(
394563 const struct aws_http_header * headers ,
395564 size_t num_headers );
396565
397- /**
398- * Modify the header at the specified index.
399- * The message makes its own copy of the underlying strings.
400- * The previous strings may be destroyed.
401- */
402- AWS_HTTP_API
403- int aws_http_message_set_header (struct aws_http_message * message , struct aws_http_header header , size_t index );
404-
405566/**
406567 * Remove the header at the specified index.
407568 * Headers after this index are all shifted back one position.
0 commit comments