@@ -85,18 +85,16 @@ static int hmac_sha256_sign(unsigned char out[32],
8585
8686static int kv_key_cmp (const void * a_arg , const void * b_arg )
8787{
88+ int ret ;
8889 struct flb_kv * kv_a = * (struct flb_kv * * ) a_arg ;
8990 struct flb_kv * kv_b = * (struct flb_kv * * ) b_arg ;
9091
91- return strcmp (kv_a -> key , kv_b -> key );
92- }
93-
94- static int kv_val_cmp (const void * a_arg , const void * b_arg )
95- {
96- struct flb_kv * kv_a = * (struct flb_kv * * ) a_arg ;
97- struct flb_kv * kv_b = * (struct flb_kv * * ) b_arg ;
92+ ret = strcmp (kv_a -> key , kv_b -> key );
93+ if (ret == 0 ) {
94+ ret = strcmp (kv_a -> val , kv_b -> val );
95+ }
9896
99- return strcmp ( kv_a -> val , kv_b -> val ) ;
97+ return ret ;
10098}
10199
102100static inline int to_encode (char c )
@@ -218,6 +216,49 @@ static flb_sds_t uri_encode(const char *uri, size_t len)
218216 return buf ;
219217}
220218
219+ /*
220+ * Encodes URI parameters, which can not have "/" characters in them
221+ * (This happens in an STS request, the role ARN has a slash and is
222+ * given as a query parameter).
223+ */
224+ static flb_sds_t uri_encode_params (const char * uri , size_t len )
225+ {
226+ int i ;
227+ flb_sds_t buf = NULL ;
228+ flb_sds_t tmp = NULL ;
229+
230+ buf = flb_sds_create_size (len * 2 );
231+ if (!buf ) {
232+ flb_error ("[signv4] cannot allocate buffer for URI encoding" );
233+ return NULL ;
234+ }
235+
236+ for (i = 0 ; i < len ; i ++ ) {
237+ if (to_encode (uri [i ]) == FLB_TRUE || uri [i ] == '/' ) {
238+ tmp = flb_sds_printf (& buf , "%%%02X" , (unsigned char ) * (uri + i ));
239+ if (!tmp ) {
240+ flb_error ("[signv4] error formatting special character" );
241+ flb_sds_destroy (buf );
242+ return NULL ;
243+ }
244+ buf = tmp ;
245+ continue ;
246+ }
247+
248+ /* Direct assignment, just copy the character */
249+ if (buf ) {
250+ tmp = flb_sds_cat (buf , uri + i , 1 );
251+ if (!tmp ) {
252+ flb_error ("[signv4] error composing outgoing buffer" );
253+ flb_sds_destroy (buf );
254+ return NULL ;
255+ }
256+ }
257+ }
258+
259+ return buf ;
260+ }
261+
221262/*
222263 * Convert URL encoded params (query string or POST payload) to a sorted
223264 * key/value linked list
@@ -261,9 +302,9 @@ static flb_sds_t url_params_format(char *params)
261302 p ++ ;
262303
263304 /* URI encode every key and value */
264- key = uri_encode (e -> str , len );
305+ key = uri_encode_params (e -> str , len );
265306 len ++ ;
266- val = uri_encode (p , flb_sds_len (e -> str ) - len );
307+ val = uri_encode_params (p , flb_sds_len (e -> str ) - len );
267308 if (!key || !val ) {
268309 flb_error ("[signv4] error encoding uri for query string" );
269310 if (key ) {
@@ -315,9 +356,6 @@ static flb_sds_t url_params_format(char *params)
315356 /* sort headers by key */
316357 qsort (arr , items , sizeof (struct flb_kv * ), kv_key_cmp );
317358
318- /* re-sort by values (duplicated keys) */
319- qsort (arr , items , sizeof (struct flb_kv * ), kv_val_cmp );
320-
321359 /* Format query string parameters */
322360 buf = flb_sds_create_size (items * 64 );
323361 if (!buf ) {
0 commit comments