1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
|
#ifndef AWS_COMMON_URI_H
#define AWS_COMMON_URI_H
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#include <aws/common/byte_buf.h>
AWS_PUSH_SANE_WARNING_LEVEL
/**
* Data representing a URI. uri_str is always allocated and filled in.
* The other portions are merely storing offsets into uri_str.
*/
struct aws_uri {
size_t self_size;
struct aws_allocator *allocator;
struct aws_byte_buf uri_str;
struct aws_byte_cursor scheme;
struct aws_byte_cursor authority;
struct aws_byte_cursor userinfo;
struct aws_byte_cursor user;
struct aws_byte_cursor password;
struct aws_byte_cursor host_name;
uint32_t port;
struct aws_byte_cursor path;
struct aws_byte_cursor query_string;
struct aws_byte_cursor path_and_query;
};
/**
* key/value pairs for a query string. If the query fragment was not in format key=value, the fragment value
* will be stored in key
*/
struct aws_uri_param {
struct aws_byte_cursor key;
struct aws_byte_cursor value;
};
/**
* Arguments for building a URI instance. All members must
* be initialized before passing them to aws_uri_init().
*
* query_string and query_params are exclusive to each other. If you set
* query_string, do not prepend it with '?'
*/
struct aws_uri_builder_options {
struct aws_byte_cursor scheme;
struct aws_byte_cursor path;
struct aws_byte_cursor host_name;
uint32_t port;
struct aws_array_list *query_params;
struct aws_byte_cursor query_string;
};
AWS_EXTERN_C_BEGIN
/**
* Parses 'uri_str' and initializes uri. Returns AWS_OP_SUCCESS, on success, AWS_OP_ERR on failure.
* After calling this function, the parts can be accessed.
*/
AWS_COMMON_API int aws_uri_init_parse(
struct aws_uri *uri,
struct aws_allocator *allocator,
const struct aws_byte_cursor *uri_str);
/**
* Initializes uri to values specified in options. Returns AWS_OP_SUCCESS, on success, AWS_OP_ERR on failure.
* After calling this function, the parts can be accessed.
*/
AWS_COMMON_API int aws_uri_init_from_builder_options(
struct aws_uri *uri,
struct aws_allocator *allocator,
struct aws_uri_builder_options *options);
AWS_COMMON_API void aws_uri_clean_up(struct aws_uri *uri);
/**
* Returns the scheme portion of the uri (e.g. http, https, ftp, ftps, etc...). If the scheme was not present
* in the uri, the returned value will be empty. It is the users job to determine the appropriate defaults
* if this field is empty, based on protocol, port, etc...
*/
AWS_COMMON_API const struct aws_byte_cursor *aws_uri_scheme(const struct aws_uri *uri);
/**
* Returns the authority portion of the uri (host[:port]). If it was not present, this was a request uri. In that
* case, the value will be empty.
*/
AWS_COMMON_API const struct aws_byte_cursor *aws_uri_authority(const struct aws_uri *uri);
/**
* Returns the path portion of the uri, including any leading '/'. If not present, this value will be empty.
*/
AWS_COMMON_API const struct aws_byte_cursor *aws_uri_path(const struct aws_uri *uri);
/**
* Returns the query string portion of the uri, minus the '?'. If not present, this value will be empty.
*/
AWS_COMMON_API const struct aws_byte_cursor *aws_uri_query_string(const struct aws_uri *uri);
/**
* Returns the 'host_name' portion of the authority. If no authority was present, this value will be empty.
*/
AWS_COMMON_API const struct aws_byte_cursor *aws_uri_host_name(const struct aws_uri *uri);
/**
* Returns the port portion of the authority if it was present, otherwise, returns 0.
* If this is 0, it is the users job to determine the correct port based on scheme and protocol.
*/
AWS_COMMON_API uint32_t aws_uri_port(const struct aws_uri *uri);
/**
* Returns the path and query portion of the uri (i.e., the thing you send across the wire).
*/
AWS_COMMON_API const struct aws_byte_cursor *aws_uri_path_and_query(const struct aws_uri *uri);
/**
* For iterating over the params in the query string.
* `param` is an in/out argument used to track progress, it MUST be zeroed out to start.
* If true is returned, `param` contains the value of the next param.
* If false is returned, there are no further params.
*
* Edge cases:
* 1) Entries without '=' sign are treated as having a key and no value.
* Example: First param in query string "a&b=c" has key="a" value=""
*
* 2) Blank entries are skipped.
* Example: The only param in query string "&&a=b" is key="a" value="b"
*/
AWS_COMMON_API bool aws_query_string_next_param(struct aws_byte_cursor query_string, struct aws_uri_param *param);
/**
* Parses query string and stores the parameters in 'out_params'. Returns AWS_OP_SUCCESS on success and
* AWS_OP_ERR on failure. The user is responsible for initializing out_params with item size of struct aws_query_param.
* The user is also responsible for cleaning up out_params when finished.
*/
AWS_COMMON_API int aws_query_string_params(struct aws_byte_cursor query_string, struct aws_array_list *out_params);
/**
* For iterating over the params in the uri query string.
* `param` is an in/out argument used to track progress, it MUST be zeroed out to start.
* If true is returned, `param` contains the value of the next param.
* If false is returned, there are no further params.
*
* Edge cases:
* 1) Entries without '=' sign are treated as having a key and no value.
* Example: First param in query string "a&b=c" has key="a" value=""
*
* 2) Blank entries are skipped.
* Example: The only param in query string "&&a=b" is key="a" value="b"
*/
AWS_COMMON_API bool aws_uri_query_string_next_param(const struct aws_uri *uri, struct aws_uri_param *param);
/**
* Parses query string and stores the parameters in 'out_params'. Returns AWS_OP_SUCCESS on success and
* AWS_OP_ERR on failure. The user is responsible for initializing out_params with item size of struct aws_query_param.
* The user is also responsible for cleaning up out_params when finished.
*/
AWS_COMMON_API int aws_uri_query_string_params(const struct aws_uri *uri, struct aws_array_list *out_params);
/**
* Writes the uri path encoding of a cursor to a buffer. This is the modified version of rfc3986 used by
* sigv4 signing.
*/
AWS_COMMON_API int aws_byte_buf_append_encoding_uri_path(
struct aws_byte_buf *buffer,
const struct aws_byte_cursor *cursor);
/**
* Writes the uri query param encoding (passthrough alnum + '-' '_' '~' '.') of a UTF-8 cursor to a buffer
* For example, reading "a b_c" would write "a%20b_c".
*/
AWS_COMMON_API int aws_byte_buf_append_encoding_uri_param(
struct aws_byte_buf *buffer,
const struct aws_byte_cursor *cursor);
/**
* Writes the uri decoding of a UTF-8 cursor to a buffer,
* replacing %xx escapes by their single byte equivalent.
* For example, reading "a%20b_c" would write "a b_c".
*/
AWS_COMMON_API int aws_byte_buf_append_decoding_uri(struct aws_byte_buf *buffer, const struct aws_byte_cursor *cursor);
AWS_EXTERN_C_END
AWS_POP_SANE_WARNING_LEVEL
#endif /* AWS_COMMON_URI_H */
|