1111
1212#include <stdio.h>
1313
14- // MQTT payload size https://docs.aws.amazon. com/general/latest/gr/iot-core.html#thing-limits
15- const size_t AWS_IOT_MAX_USERNAME_SIZE = 128 * 1024 ;
14+ // Use packet encoding limit for now: https://github. com/awslabs/aws-c-mqtt/blob/v0.13.3/source/packets.c#L26
15+ const size_t AWS_IOT_MAX_USERNAME_SIZE = UINT16_MAX ;
1616const size_t DEFAULT_QUERY_PARAM_COUNT = 10 ;
1717
1818// Build username query string from params_list, the caller is responsible to init and clean up output_username
@@ -25,6 +25,9 @@ int s_build_username_query(
2525 struct aws_byte_buf * output_username ,
2626 size_t * out_full_username_size ) {
2727
28+ AWS_ASSERT (base_username );
29+ AWS_ASSERT (params_list );
30+
2831 if (output_username ) {
2932 aws_byte_buf_write (output_username , base_username -> ptr , base_username_length );
3033 }
@@ -54,15 +57,17 @@ int s_build_username_query(
5457 }
5558
5659 if (output_username ) {
57- if (aws_byte_buf_append (output_username , & param .key ) ||
58- aws_byte_buf_append (output_username , & key_value_delim ) ||
59- aws_byte_buf_append (output_username , & param .value )) {
60+ if (param .key .len > 0 && (aws_byte_buf_append (output_username , & param .key ))) {
6061 return AWS_OP_ERR ;
6162 }
62- }
6363
64+ if (param .value .len > 0 && ((aws_byte_buf_append (output_username , & key_value_delim )) ||
65+ aws_byte_buf_append (output_username , & param .value ))) {
66+ return AWS_OP_ERR ;
67+ }
68+ }
6469 if (out_full_username_size ) {
65- * out_full_username_size += param .key .len + 1 + param .value .len ;
70+ * out_full_username_size += param .key .len + param . value . len > 0 ? 1 : 0 + param .value .len ;
6671 }
6772 }
6873
@@ -80,15 +85,16 @@ int aws_mqtt_append_sdk_metrics_to_username(
8085 if (!allocator ) {
8186 return aws_raise_error (AWS_ERROR_INVALID_ARGUMENT );
8287 }
88+ const struct aws_byte_cursor local_original_username =
89+ original_username == NULL ? aws_byte_cursor_from_c_str ("" ) : * original_username ;
8390
8491 if (!metrics ) {
8592 if (out_full_username_size ) {
86- * out_full_username_size = original_username -> len ;
93+ * out_full_username_size = local_original_username . len ;
8794 }
8895
89- if (output_username &&
90- aws_byte_buf_init (output_username , allocator , original_username -> len ) == AWS_OP_SUCCESS ) {
91- aws_byte_buf_write (output_username , original_username -> ptr , original_username -> len );
96+ if (output_username ) {
97+ return aws_byte_buf_init_copy_from_cursor (output_username , allocator , local_original_username );
9298 }
9399
94100 return AWS_OP_SUCCESS ;
@@ -98,12 +104,6 @@ int aws_mqtt_append_sdk_metrics_to_username(
98104 return AWS_OP_ERR ;
99105 }
100106
101- /* Build metrics string */
102- struct aws_byte_buf metrics_string ;
103- if (aws_byte_buf_init (& metrics_string , allocator , AWS_IOT_MAX_USERNAME_SIZE )) {
104- return AWS_OP_ERR ;
105- }
106-
107107 int result = AWS_OP_ERR ;
108108 // The length of the base username part not including query parameters
109109 size_t base_username_length = 0 ;
@@ -114,17 +114,23 @@ int aws_mqtt_append_sdk_metrics_to_username(
114114 struct aws_array_list params_list ;
115115 aws_array_list_init_dynamic (& params_list , allocator , DEFAULT_QUERY_PARAM_COUNT , sizeof (struct aws_uri_param ));
116116
117- if (original_username && original_username -> len > 0 ) {
118- struct aws_byte_cursor question_mark_find ;
117+ if (local_original_username . len > 0 ) {
118+ struct aws_byte_cursor question_mark_find = local_original_username ;
119119
120- if (AWS_OP_SUCCESS == aws_byte_cursor_find_exact (original_username , & question_mark_str , & question_mark_find )) {
121- base_username_length = question_mark_find .ptr - original_username -> ptr ;
120+ bool found_query = false;
121+ // Find last question mark
122+ while (AWS_OP_SUCCESS ==
123+ aws_byte_cursor_find_exact (& question_mark_find , & question_mark_str , & question_mark_find )) {
122124 // Advance cursor to skip the "?" character
123125 aws_byte_cursor_advance (& question_mark_find , 1 );
124- aws_byte_buf_append (& metrics_string , & question_mark_find );
126+ found_query = true;
127+ }
128+
129+ if (found_query ) {
130+ base_username_length = question_mark_find .ptr - local_original_username .ptr ;
125131 aws_query_string_params (question_mark_find , & params_list );
126132 } else {
127- base_username_length = original_username -> len ;
133+ base_username_length = local_original_username . len ;
128134 }
129135 }
130136
@@ -161,9 +167,9 @@ int aws_mqtt_append_sdk_metrics_to_username(
161167 }
162168
163169 // Rebuild metrics string from params_list
164- // First path to calculate total size
170+ // First parse to calculate total size
165171 size_t total_size = 0 ;
166- s_build_username_query (original_username , base_username_length , & params_list , NULL , & total_size );
172+ s_build_username_query (& local_original_username , base_username_length , & params_list , NULL , & total_size );
167173
168174 if (total_size > AWS_IOT_MAX_USERNAME_SIZE ) {
169175 goto cleanup ;
@@ -175,11 +181,10 @@ int aws_mqtt_append_sdk_metrics_to_username(
175181
176182 // build final output username
177183 if (s_build_username_query (
178- original_username , base_username_length , & params_list , output_username , out_full_username_size )) {
184+ & local_original_username , base_username_length , & params_list , output_username , out_full_username_size )) {
179185 goto cleanup ;
180186 }
181187
182- aws_byte_buf_clean_up (& metrics_string );
183188 result = AWS_OP_SUCCESS ;
184189
185190cleanup :
@@ -190,7 +195,6 @@ int aws_mqtt_append_sdk_metrics_to_username(
190195 if (result == AWS_OP_ERR && aws_byte_buf_is_valid (output_username )) {
191196 aws_byte_buf_clean_up (output_username );
192197 }
193- aws_byte_buf_clean_up (& metrics_string );
194198 return result ;
195199}
196200
@@ -237,35 +241,6 @@ struct aws_mqtt_iot_sdk_metrics_storage *aws_mqtt_iot_sdk_metrics_storage_new(
237241
238242 struct aws_mqtt_iot_sdk_metrics * storage_view = & metrics_storage -> storage_view ;
239243
240- // TODO Future Work: add metadata entries once we implemented the metadata feature
241- //
242- // if (aws_array_list_init_dynamic(
243- // &metrics_storage->metadata_entries,
244- // allocator,
245- // metrics_options->metadata_count,
246- // sizeof(struct aws_mqtt_metadata_entry))) {
247- // goto metrics_storage_error;
248- // }
249-
250- // for (size_t i = 0; i < metrics_options->metadata_count; ++i) {
251- // struct aws_mqtt_metadata_entry entry = metrics_options->metadata_entries[i];
252-
253- // if (aws_byte_buf_append_and_update(&metrics_storage->storage, &entry.key)) {
254- // goto metrics_storage_error;
255- // }
256-
257- // if (aws_byte_buf_append_and_update(&metrics_storage->storage, &entry.value)) {
258- // goto metrics_storage_error;
259- // }
260-
261- // if (aws_array_list_push_back(&metrics_storage->metadata_entries, &entry)) {
262- // goto metrics_storage_error;
263- // }
264- // }
265-
266- // storage_view->metadata_entries = metrics_storage->metadata_entries.data;
267- // storage_view->metadata_count = aws_array_list_length(&metrics_storage->metadata_entries);
268-
269244 if (metrics_options -> library_name .len > 0 ) {
270245 metrics_storage -> library_name = metrics_options -> library_name ;
271246 if (aws_byte_buf_append_and_update (& metrics_storage -> storage , & metrics_storage -> library_name )) {
@@ -285,9 +260,8 @@ struct aws_mqtt_iot_sdk_metrics_storage *aws_mqtt_iot_sdk_metrics_storage_new(
285260 if (aws_byte_buf_is_valid (& metrics_storage -> storage )) {
286261 aws_byte_buf_clean_up (& metrics_storage -> storage );
287262 }
288- if (metrics_options != NULL ) {
289- aws_mem_release (allocator , metrics_storage );
290- }
263+
264+ aws_mem_release (allocator , metrics_storage );
291265
292266 return NULL ;
293267}
@@ -314,13 +288,5 @@ int aws_mqtt_validate_iot_sdk_metrics_utf8(const struct aws_mqtt_iot_sdk_metrics
314288 return AWS_OP_ERR ;
315289 }
316290
317- // TODO: add metadata entries when enabled
318- // for (size_t i = 0; i < metrics->metadata_count; ++i) {
319- // if (aws_mqtt_validate_utf8_text(metrics->metadata_entries[i].key) ||
320- // aws_mqtt_validate_utf8_text(metrics->metadata_entries[i].value)) {
321- // return AWS_OP_ERR;
322- // }
323- // }
324-
325291 return AWS_OP_SUCCESS ;
326292}
0 commit comments