88#include <aws/common/encoding.h>
99#include <aws/common/logging.h>
1010
11+ static void s_lock_synced_data (struct aws_s3_upload_request_checksum_context * context ) {
12+ aws_mutex_lock (& context -> synced_data .lock );
13+ }
14+
15+ static void s_unlock_synced_data (struct aws_s3_upload_request_checksum_context * context ) {
16+ aws_mutex_unlock (& context -> synced_data .lock );
17+ }
18+
1119static void s_aws_s3_upload_request_checksum_context_destroy (void * context ) {
1220 struct aws_s3_upload_request_checksum_context * checksum_context = context ;
13- aws_byte_buf_clean_up (& checksum_context -> base64_checksum );
21+ aws_byte_buf_clean_up (& checksum_context -> synced_data .base64_checksum );
22+ aws_mutex_clean_up (& checksum_context -> synced_data .lock );
1423 aws_mem_release (checksum_context -> allocator , checksum_context );
1524}
1625
@@ -44,6 +53,10 @@ static struct aws_s3_upload_request_checksum_context *s_s3_upload_request_checks
4453 return NULL ;
4554 }
4655 context -> encoded_checksum_size = encoded_size ;
56+ if (!aws_mutex_init (& context -> synced_data .lock )) {
57+ aws_s3_upload_request_checksum_context_release (context );
58+ return NULL ;
59+ }
4760 return context ;
4861}
4962
@@ -54,7 +67,7 @@ struct aws_s3_upload_request_checksum_context *aws_s3_upload_request_checksum_co
5467 s_s3_upload_request_checksum_context_new_base (allocator , checksum_config );
5568 if (context && context -> encoded_checksum_size > 0 ) {
5669 /* Initial the buffer for checksum */
57- aws_byte_buf_init (& context -> base64_checksum , allocator , context -> encoded_checksum_size );
70+ aws_byte_buf_init (& context -> synced_data . base64_checksum , allocator , context -> encoded_checksum_size );
5871 }
5972 return context ;
6073}
@@ -79,8 +92,8 @@ struct aws_s3_upload_request_checksum_context *aws_s3_upload_request_checksum_co
7992 aws_s3_upload_request_checksum_context_release (context );
8093 return NULL ;
8194 }
82- aws_byte_buf_init_copy_from_cursor (& context -> base64_checksum , allocator , existing_base64_checksum );
83- context -> checksum_calculated = true;
95+ aws_byte_buf_init_copy_from_cursor (& context -> synced_data . base64_checksum , allocator , existing_base64_checksum );
96+ context -> synced_data . checksum_calculated = true;
8497 }
8598 return context ;
8699}
@@ -101,14 +114,18 @@ struct aws_s3_upload_request_checksum_context *aws_s3_upload_request_checksum_co
101114 return NULL ;
102115}
103116
104- bool aws_s3_upload_request_checksum_context_should_calculate (
105- const struct aws_s3_upload_request_checksum_context * context ) {
117+ bool aws_s3_upload_request_checksum_context_should_calculate (struct aws_s3_upload_request_checksum_context * context ) {
106118 if (!context || context -> algorithm == AWS_SCA_NONE ) {
107119 return false;
108120 }
109121
122+ bool should_calculate = false;
123+ s_lock_synced_data (context );
110124 /* If not previous calculated */
111- return !context -> checksum_calculated ;
125+ should_calculate = !context -> synced_data .checksum_calculated ;
126+ s_unlock_synced_data (context );
127+
128+ return should_calculate ;
112129}
113130
114131bool aws_s3_upload_request_checksum_context_should_add_header (
@@ -129,19 +146,46 @@ bool aws_s3_upload_request_checksum_context_should_add_trailer(
129146 return context -> location == AWS_SCL_TRAILER && context -> algorithm != AWS_SCA_NONE ;
130147}
131148
132- struct aws_byte_buf * aws_s3_upload_request_checksum_context_get_output_buffer (
133- struct aws_s3_upload_request_checksum_context * context ) {
149+ int aws_s3_upload_request_checksum_context_finalize_checksum (
150+ struct aws_s3_upload_request_checksum_context * context ,
151+ struct aws_byte_cursor raw_checksum_cursor ) {
134152 if (!context ) {
135- return NULL ;
153+ return aws_raise_error ( AWS_ERROR_INVALID_ARGUMENT ) ;
136154 }
137- return & context -> base64_checksum ;
155+ s_lock_synced_data (context );
156+ /* If not previous calculated */
157+ if (!context -> synced_data .checksum_calculated ) {
158+ AWS_ASSERT (context -> synced_data .base64_checksum .len == 0 );
159+
160+ if (aws_base64_encode (& raw_checksum_cursor , & context -> synced_data .base64_checksum )) {
161+ aws_byte_buf_reset (& context -> synced_data .base64_checksum , false);
162+ AWS_LOGF_ERROR (
163+ AWS_LS_S3_GENERAL ,
164+ "Failed to base64 encode for the checksum. Raw checksum length: %zu. Output buffer capacity: %zu "
165+ "length %zu" ,
166+ raw_checksum_cursor .len ,
167+ context -> synced_data .base64_checksum .capacity ,
168+ context -> synced_data .base64_checksum .len );
169+ s_unlock_synced_data (context );
170+ return AWS_OP_ERR ;
171+ }
172+ context -> synced_data .checksum_calculated = true;
173+ }
174+ s_unlock_synced_data (context );
175+ return AWS_OP_SUCCESS ;
138176}
139177
140178struct aws_byte_cursor aws_s3_upload_request_checksum_context_get_checksum_cursor (
141- const struct aws_s3_upload_request_checksum_context * context ) {
179+ struct aws_s3_upload_request_checksum_context * context ) {
142180 struct aws_byte_cursor checksum_cursor = {0 };
143- if (!context || ! context -> checksum_calculated ) {
181+ if (!context ) {
144182 return checksum_cursor ;
145183 }
146- return aws_byte_cursor_from_buf (& context -> base64_checksum );
184+ s_lock_synced_data (context );
185+ /* If not previous calculated */
186+ if (context -> synced_data .checksum_calculated ) {
187+ checksum_cursor = aws_byte_cursor_from_buf (& context -> synced_data .base64_checksum );
188+ }
189+ s_unlock_synced_data (context );
190+ return checksum_cursor ;
147191}
0 commit comments