33import com .google .common .base .Charsets ;
44import com .google .common .base .Function ;
55import com .google .common .base .Joiner ;
6+ import com .google .common .base .Strings ;
7+ import com .google .common .collect .Lists ;
68import com .google .common .hash .HashFunction ;
79import com .google .common .hash .Hashing ;
810import com .google .common .io .CharStreams ;
1921import java .io .InputStreamReader ;
2022import java .util .Arrays ;
2123import java .util .Collections ;
22- import java .util .Comparator ;
2324import java .util .Date ;
2425import java .util .HashMap ;
2526import java .util .List ;
@@ -80,19 +81,19 @@ public Map<String, Object> getClaims() {
8081
8182 // Normalize all the headers
8283 Header [] lowercaseHeaders = LOWERCASE_KEYS .apply (headers );
83- Arrays .sort (lowercaseHeaders , new Comparator <Header >() {
84- @ Override
85- public int compare (Header o1 , Header o2 ) {
86- return o1 .getName ().compareTo (o2 .getName ());
87- }
88- });
84+ Map <String , List <String >> combinedHeaders = COMBINE_HEADERS .apply (lowercaseHeaders );
8985
9086 // Add the headers that we care about
91- for (Header header : lowercaseHeaders ) {
92- if (signedHeaders .contains (header .getName ().toLowerCase ())) {
93- signature .append (header .getName ().toLowerCase ().trim ())
87+ for (String header : signedHeaders ) {
88+ String lowercase = header .toLowerCase ().trim ();
89+
90+ if (combinedHeaders .containsKey (lowercase )) {
91+ List <String > values = combinedHeaders .get (lowercase );
92+ Collections .sort (values );
93+
94+ signature .append (lowercase )
9495 .append (":" )
95- .append (header . getValue (). trim ( ))
96+ .append (Joiner . on ( ',' ). join ( values ))
9697 .append (NEW_LINE );
9798 }
9899 }
@@ -102,8 +103,10 @@ public int compare(Header o1, Header o2) {
102103 signature .append (includedHeaders ).append (NEW_LINE );
103104
104105 // Hash and hex the request payload
105- String hashedPayload = HASH_FUNCTION .hashString (requestBody , Charsets .UTF_8 ).toString ();
106- signature .append (hashedPayload ).append (NEW_LINE );
106+ if (!Strings .isNullOrEmpty (requestBody )) {
107+ String hashedPayload = HASH_FUNCTION .hashString (requestBody , Charsets .UTF_8 ).toString ();
108+ signature .append (hashedPayload );
109+ }
107110
108111 // Hash and hex the canonical request
109112 String hashedSignature = HASH_FUNCTION .hashString (signature .toString (), Charsets .UTF_8 ).toString ();
@@ -143,6 +146,23 @@ public static ValidationToken fromHttpRequest(
143146 return builder .build ();
144147 }
145148
149+ private static Function <Header [], Map <String , List <String >>> COMBINE_HEADERS = new Function <Header [], Map <String , List <String >>>() {
150+ @ Override
151+ public Map <String , List <String >> apply (Header [] headers ) {
152+ Map <String , List <String >> combinedHeaders = new HashMap <>();
153+
154+ for (Header header : headers ) {
155+ if (combinedHeaders .containsKey (header .getName ())) {
156+ combinedHeaders .get (header .getName ()).add (header .getValue ());
157+ } else {
158+ combinedHeaders .put (header .getName (), Lists .newArrayList (header .getValue ()));
159+ }
160+ }
161+
162+ return combinedHeaders ;
163+ }
164+ };
165+
146166 private static Function <Header [], Header []> LOWERCASE_KEYS = new Function <Header [], Header []>() {
147167 @ Override
148168 public Header [] apply (Header [] headers ) {
0 commit comments