1616
1717package io .minio ;
1818
19- import com .google .common .io .BaseEncoding ;
19+ import com .fasterxml .jackson .core .JsonProcessingException ;
20+ import com .fasterxml .jackson .databind .ObjectMapper ;
2021import io .minio .credentials .Credentials ;
2122import java .nio .charset .StandardCharsets ;
2223import java .security .InvalidKeyException ;
2324import java .security .NoSuchAlgorithmException ;
2425import java .time .ZonedDateTime ;
2526import java .util .Arrays ;
27+ import java .util .Base64 ;
2628import java .util .HashMap ;
2729import java .util .LinkedHashMap ;
30+ import java .util .LinkedList ;
2831import java .util .List ;
2932import java .util .Map ;
3033import javax .annotation .Nonnull ;
@@ -48,6 +51,7 @@ public class PostPolicy {
4851 private static final String ALGORITHM = "AWS4-HMAC-SHA256" ;
4952 private static final String EQ = "eq" ;
5053 private static final String STARTS_WITH = "starts-with" ;
54+ private static final ObjectMapper objectMapper = new ObjectMapper ();
5155
5256 private String bucketName ;
5357 private ZonedDateTime expiration ;
@@ -90,7 +94,6 @@ public void addEqualsCondition(@Nonnull String element, @Nonnull String value) {
9094 throw new IllegalArgumentException (element + " cannot be set" );
9195 }
9296
93- if ("key" .equals (element )) value = S3Escaper .encodePath (value );
9497 conditions .get (EQ ).put (element , value );
9598 }
9699
@@ -124,7 +127,6 @@ public void addStartsWithCondition(@Nonnull String element, @Nonnull String valu
124127 throw new IllegalArgumentException (element + " cannot be set" );
125128 }
126129
127- if ("key" .equals (element )) value = S3Escaper .encodePath (value );
128130 conditions .get (STARTS_WITH ).put (element , value );
129131 }
130132
@@ -161,22 +163,6 @@ public void removeContentLengthRangeCondition() {
161163 this .upperLimit = null ;
162164 }
163165
164- private String quote (String value ) {
165- return "\" " + value + "\" " ;
166- }
167-
168- private StringBuilder addCondition (
169- StringBuilder sb , String condition , String element , String value , boolean isEnd ) {
170- sb .append (" [" )
171- .append (quote (condition ))
172- .append (", " )
173- .append (quote ("$" + element ))
174- .append (", " )
175- .append (quote (value ))
176- .append ("]" );
177- return isEnd ? sb : sb .append (",\n " );
178- }
179-
180166 /**
181167 * Return form-data of this post policy. The returned map contains x-amz-algorithm,
182168 * x-amz-credential, x-amz-security-token, x-amz-date, policy and x-amz-signature.
@@ -195,43 +181,42 @@ public Map<String, String> formData(@Nonnull Credentials creds, @Nonnull String
195181 throw new IllegalArgumentException ("key condition must be set" );
196182 }
197183
198- StringBuilder sb = new StringBuilder ().append ("{\n " );
199- sb .append (" " )
200- .append (quote ("expiration" ))
201- .append (": " )
202- .append (quote (expiration .format (Time .EXPIRATION_DATE_FORMAT )))
203- .append (",\n " );
204- sb .append (" " ).append (quote ("conditions" )).append (": [\n " );
205- addCondition (sb , "eq" , "bucket" , bucketName , false );
184+ Map <String , Object > policyMap = new HashMap <>();
185+ policyMap .put ("expiration" , expiration .format (Time .EXPIRATION_DATE_FORMAT ));
186+ List <List <Object >> conditionList = new LinkedList <>();
187+ conditionList .add (Arrays .asList (new Object [] {"eq" , "$bucket" , bucketName }));
206188 for (Map .Entry <String , Map <String , String >> condition : conditions .entrySet ()) {
207189 for (Map .Entry <String , String > entry : condition .getValue ().entrySet ()) {
208- addCondition (sb , condition .getKey (), entry .getKey (), entry .getValue (), false );
190+ conditionList .add (
191+ Arrays .asList (
192+ new Object [] {condition .getKey (), "$" + entry .getKey (), entry .getValue ()}));
209193 }
210194 }
211195 if (lowerLimit != null && upperLimit != null ) {
212- sb .append (" [" )
213- .append (quote ("content-length-range" ))
214- .append (", " )
215- .append (lowerLimit .toString ())
216- .append (", " )
217- .append (upperLimit .toString ())
218- .append ("],\n " );
196+ conditionList .add (
197+ Arrays .asList (new Object [] {"content-length-range" , lowerLimit , upperLimit }));
219198 }
220-
221199 ZonedDateTime utcNow = ZonedDateTime .now (Time .UTC );
222200 String credential = Signer .credential (creds .accessKey (), utcNow , region );
223201 String amzDate = utcNow .format (Time .AMZ_DATE_FORMAT );
224202
225- addCondition ( sb , "eq" , "x-amz-algorithm" , ALGORITHM , false );
226- addCondition ( sb , "eq" , "x-amz-credential" , credential , false );
203+ conditionList . add ( Arrays . asList ( new Object [] { "eq" , "$ x-amz-algorithm" , ALGORITHM }) );
204+ conditionList . add ( Arrays . asList ( new Object [] { "eq" , "$ x-amz-credential" , credential }) );
227205 if (creds .sessionToken () != null ) {
228- addCondition (sb , "eq" , "x-amz-security-token" , creds .sessionToken (), false );
206+ conditionList .add (
207+ Arrays .asList (new Object [] {"eq" , "$x-amz-security-token" , creds .sessionToken ()}));
208+ }
209+ conditionList .add (Arrays .asList (new Object [] {"eq" , "$x-amz-date" , amzDate }));
210+ policyMap .put ("conditions" , conditionList );
211+
212+ byte [] policyBytes = null ;
213+ try {
214+ policyBytes = objectMapper .writeValueAsString (policyMap ).getBytes (StandardCharsets .UTF_8 );
215+ } catch (JsonProcessingException e ) {
216+ throw new RuntimeException (e );
229217 }
230- addCondition (sb , "eq" , "x-amz-date" , amzDate , true );
231- sb .append (" ]\n " );
232- sb .append ("}" );
233218
234- String policy = BaseEncoding . base64 ().encode ( sb . toString (). getBytes ( StandardCharsets . UTF_8 ) );
219+ String policy = Base64 . getEncoder ().encodeToString ( policyBytes );
235220 String signature = Signer .postPresignV4 (policy , creds .secretKey (), utcNow , region );
236221
237222 Map <String , String > formData = new HashMap <>();
0 commit comments