diff --git a/src/main/java/com/emc/object/s3/S3SignerV2.java b/src/main/java/com/emc/object/s3/S3SignerV2.java index e4bb727c..e9e26ba6 100644 --- a/src/main/java/com/emc/object/s3/S3SignerV2.java +++ b/src/main/java/com/emc/object/s3/S3SignerV2.java @@ -82,7 +82,7 @@ public URL generatePresignedUrl(PresignedUrlRequest request) { URI uri = s3Config.resolvePath(request.getPath(), null); // don't care about the query string yet // must construct both the final URL and the resource for signing - String resource = "/" + request.getBucketName() + uri.getPath(); + String resource = "/" + request.getBucketName() + RestUtil.getEncodedPath(uri); // insert namespace in host if (namespace != null) { diff --git a/src/main/java/com/emc/object/s3/jersey/ErrorFilter.java b/src/main/java/com/emc/object/s3/jersey/ErrorFilter.java index a2ac46f7..7804fcab 100755 --- a/src/main/java/com/emc/object/s3/jersey/ErrorFilter.java +++ b/src/main/java/com/emc/object/s3/jersey/ErrorFilter.java @@ -70,6 +70,11 @@ public ClientResponse handle(ClientRequest request) throws ClientHandlerExceptio throw parseErrorResponse(new InputStreamReader(response.getEntityInputStream()), response.getStatus()); } else { // No response entity. Don't try to parse it. + try { + response.close(); + } catch (Throwable t) { + log.warn("could not close response after error", t); + } Response.StatusType st = response.getStatusInfo(); throw new S3Exception(st.getReasonPhrase(), st.getStatusCode(), guessStatus(st.getStatusCode()), response.getHeaders().getFirst("x-amz-request-id")); diff --git a/src/main/java/com/emc/object/s3/request/GetObjectRequest.java b/src/main/java/com/emc/object/s3/request/GetObjectRequest.java index bda0a23a..8ce2f36c 100644 --- a/src/main/java/com/emc/object/s3/request/GetObjectRequest.java +++ b/src/main/java/com/emc/object/s3/request/GetObjectRequest.java @@ -69,7 +69,7 @@ public Map> getHeaders() { if (ifModifiedSince != null) RestUtil.putSingle(headers, RestUtil.HEADER_IF_MODIFIED_SINCE, RestUtil.headerFormat(ifModifiedSince)); if (ifUnmodifiedSince != null) - RestUtil.putSingle(headers, RestUtil.HEADER_IF_UNMODIFIED_SINE, RestUtil.headerFormat(ifUnmodifiedSince)); + RestUtil.putSingle(headers, RestUtil.HEADER_IF_UNMODIFIED_SINCE, RestUtil.headerFormat(ifUnmodifiedSince)); if (ifMatch != null) RestUtil.putSingle(headers, RestUtil.HEADER_IF_MATCH, ifMatch); if (ifNoneMatch != null) RestUtil.putSingle(headers, RestUtil.HEADER_IF_NONE_MATCH, ifNoneMatch); return headers; diff --git a/src/main/java/com/emc/object/s3/request/PutObjectRequest.java b/src/main/java/com/emc/object/s3/request/PutObjectRequest.java index afac6f89..80c4126c 100644 --- a/src/main/java/com/emc/object/s3/request/PutObjectRequest.java +++ b/src/main/java/com/emc/object/s3/request/PutObjectRequest.java @@ -72,7 +72,7 @@ public Map> getHeaders() { if (ifModifiedSince != null) RestUtil.putSingle(headers, RestUtil.HEADER_IF_MODIFIED_SINCE, RestUtil.headerFormat(ifModifiedSince)); if (ifUnmodifiedSince != null) - RestUtil.putSingle(headers, RestUtil.HEADER_IF_UNMODIFIED_SINE, RestUtil.headerFormat(ifUnmodifiedSince)); + RestUtil.putSingle(headers, RestUtil.HEADER_IF_UNMODIFIED_SINCE, RestUtil.headerFormat(ifUnmodifiedSince)); if (ifMatch != null) RestUtil.putSingle(headers, RestUtil.HEADER_IF_MATCH, ifMatch); if (ifNoneMatch != null) RestUtil.putSingle(headers, RestUtil.HEADER_IF_NONE_MATCH, ifNoneMatch); if (acl != null) headers.putAll(acl.toHeaders()); diff --git a/src/main/java/com/emc/object/util/RestUtil.java b/src/main/java/com/emc/object/util/RestUtil.java index 8d5e10f9..1cbc6818 100644 --- a/src/main/java/com/emc/object/util/RestUtil.java +++ b/src/main/java/com/emc/object/util/RestUtil.java @@ -54,7 +54,7 @@ public final class RestUtil { public static final String HEADER_IF_MATCH = "If-Match"; public static final String HEADER_IF_MODIFIED_SINCE = "If-Modified-Since"; public static final String HEADER_IF_NONE_MATCH = "If-None-Match"; - public static final String HEADER_IF_UNMODIFIED_SINE = "If-Unmodified-Since"; + public static final String HEADER_IF_UNMODIFIED_SINCE = "If-Unmodified-Since"; public static final String HEADER_LAST_MODIFIED = "Last-Modified"; public static final String HEADER_RANGE = "Range"; public static final String HEADER_USER_AGENT = "User-Agent"; diff --git a/src/test/java/com/emc/object/s3/S3JerseyClientTest.java b/src/test/java/com/emc/object/s3/S3JerseyClientTest.java index 32453a8c..12142054 100644 --- a/src/test/java/com/emc/object/s3/S3JerseyClientTest.java +++ b/src/test/java/com/emc/object/s3/S3JerseyClientTest.java @@ -2114,6 +2114,16 @@ public void testPreSignedUrl() throws Exception { url.toString()); } + @Test + public void testPreSignedUrlWithChinese() throws Exception { + S3Client tempClient = new S3JerseyClient(new S3Config(new URI("https://s3.amazonaws.com")).withUseVHost(true) + .withIdentity("stu").withSecretKey("/QcPo5pEvQh7EOHKs2XjzCARrt7HokZhlpdGKbHs")); + URL url = tempClient.getPresignedUrl("test-bucket", "解析依頼C1B068.txt", new Date(1500998758000L)); + Assert.assertEquals("https://test-bucket.s3.amazonaws.com/%E8%A7%A3%E6%9E%90%E4%BE%9D%E9%A0%BCC1B068.txt" + + "?AWSAccessKeyId=stu&Expires=1500998758&Signature=AjZv1TlZgGqlbNsLiYKFkV6gaqg%3D", + url.toString()); + } + @Test public void testStaleReadsAllowed() throws Exception { // there's no way to test the result, so if no error is returned, assume success @@ -2304,6 +2314,17 @@ public void run() { Assert.assertTrue(Math.abs(Math.round(faultRate * (float) requests) - failures.get()) <= requests / 10); // within 10% } + @Test + public void testCifsEcs() { + String key = "_$folder$"; + + PutObjectRequest request = new PutObjectRequest(getTestBucket(), key, new byte[0]); + // for some stupid reason, Jersey always uses chunked transfer with "identity" content-encoding + request.withObjectMetadata(new S3ObjectMetadata().withContentEncoding("identity")); + client.putObject(request); + Assert.assertNotNull(client.getObjectMetadata(getTestBucket(), key)); + } + protected void assertAclEquals(AccessControlList acl1, AccessControlList acl2) { Assert.assertEquals(acl1.getOwner(), acl2.getOwner()); Assert.assertEquals(acl1.getGrants(), acl2.getGrants()); diff --git a/src/test/java/com/emc/object/s3/S3MetadataSearchTest.java b/src/test/java/com/emc/object/s3/S3MetadataSearchTest.java index 6c34b218..9073969a 100644 --- a/src/test/java/com/emc/object/s3/S3MetadataSearchTest.java +++ b/src/test/java/com/emc/object/s3/S3MetadataSearchTest.java @@ -25,10 +25,11 @@ public S3Client createS3Client() throws Exception { } private final MetadataSearchKey[] bucketMetadataSearchKeys = new MetadataSearchKey[] { + new MetadataSearchKey("ObjectName", MetadataSearchDatatype.string), new MetadataSearchKey("x-amz-meta-datetime1", MetadataSearchDatatype.datetime), new MetadataSearchKey("x-amz-meta-decimal1", MetadataSearchDatatype.decimal), new MetadataSearchKey("x-amz-meta-integer1", MetadataSearchDatatype.integer), - new MetadataSearchKey("x-amz-meta-string1", MetadataSearchDatatype.string), + new MetadataSearchKey("x-amz-meta-string1", MetadataSearchDatatype.string) }; @Override @@ -95,13 +96,11 @@ public int compare(MetadataSearchKey o1, MetadataSearchKey o2) { @Test public void testObjectName() throws Exception { - String bucket = "name-test"; - - QueryObjectsRequest request = new QueryObjectsRequest(bucket) + QueryObjectsRequest request = new QueryObjectsRequest(getTestBucket()) .withQuery("ObjectName>''"); QueryObjectsResult result = client.queryObjects(request); - Assert.assertEquals(bucket, result.getBucketName()); + Assert.assertEquals(getTestBucket(), result.getBucketName()); } @Test