Commit 4b8dd28f authored by Matija Obreza's avatar Matija Obreza
Browse files

Properly URL encode parameters when signing the AWS S3 request

parent c6b222cf
......@@ -60,8 +60,9 @@ public interface BytesStorageService {
* @param path the path
* @param filename the filename
* @return true, if successful
* @throws IOException
*/
boolean exists(String path, String filename);
boolean exists(String path, String filename) throws IOException;
/**
* List all filenames at specified path. Does not include subfolders.
......
......@@ -46,6 +46,7 @@ import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriUtils;
// TODO: Auto-generated Javadoc
/**
......@@ -54,6 +55,8 @@ import org.springframework.web.client.RestTemplate;
@Service("S3Storage")
public class S3StorageServiceImpl implements BytesStorageService {
private static final String URL_ENCODING = "UTF-8";
/** The Constant LOG. */
private final static Logger LOG = LoggerFactory.getLogger(S3StorageServiceImpl.class);
......@@ -86,7 +89,7 @@ public class S3StorageServiceImpl implements BytesStorageService {
/*
* (non-Javadoc)
*
*
* @see org.genesys2.server.filerepository.service.BytesStorageService#upsert (java.lang.String, java.lang.String,
* byte[])
*/
......@@ -113,7 +116,7 @@ public class S3StorageServiceImpl implements BytesStorageService {
/*
* (non-Javadoc)
*
*
* @see org.genesys2.server.filerepository.service.BytesStorageService#remove (java.lang.String, java.lang.String)
*/
@Override
......@@ -134,7 +137,7 @@ public class S3StorageServiceImpl implements BytesStorageService {
/*
* (non-Javadoc)
*
*
* @see org.genesys2.server.filerepository.service.BytesStorageService#get(java .lang.String, java.lang.String)
*/
@Override
......@@ -160,7 +163,11 @@ public class S3StorageServiceImpl implements BytesStorageService {
* @return the url
*/
private String getUrl(final String path, final String filename) {
return String.format("https://%s%s", getHost(), getPath(path) + filename);
String url=String.format("https://%s%s", getHost(), getPath(path) + filename);
if (LOG.isTraceEnabled()) {
LOG.trace("getUrl path={} filename={} result={}", path, filename, url);
}
return url;
}
/**
......@@ -193,9 +200,10 @@ public class S3StorageServiceImpl implements BytesStorageService {
* @param filePath the file path
* @param mediaType the media type
* @return the string to sign
* @throws UnsupportedEncodingException
*/
private String getStringToSign(final String method, final String date, final String filePath,
final MediaType mediaType) {
final MediaType mediaType) throws UnsupportedEncodingException {
// HTTP-Verb
final StringBuilder sb = new StringBuilder(method).append("\n");
......@@ -214,7 +222,8 @@ public class S3StorageServiceImpl implements BytesStorageService {
sb.append(date).append("\n");
// CanonicalizedResource
sb.append("/").append(bucket).append(filePath);
sb.append("/").append(UriUtils.encodePath(bucket, URL_ENCODING))
.append(UriUtils.encodePath(filePath, URL_ENCODING));
return sb.toString();
}
......@@ -282,28 +291,28 @@ public class S3StorageServiceImpl implements BytesStorageService {
// LOG.debug("==========================request
// end================================================");
final ClientHttpResponse response = execution.execute(request, body);
//
// StringBuilder inputStringBuilder = new StringBuilder();
// BufferedReader bufferedReader = new BufferedReader(new
// InputStreamReader(response.getBody(), "UTF-8"));
// String line = bufferedReader.readLine();
// while (line != null) {
// inputStringBuilder.append(line);
// inputStringBuilder.append('\n');
// line = bufferedReader.readLine();
// }
// LOG.debug("============================response
// begin==========================================");
// LOG.debug("status code: " + response.getStatusCode());
// LOG.debug("status text: " + response.getStatusText());
// LOG.debug("Response Body : " +
// inputStringBuilder.toString());
// LOG.debug("=======================response
// end=================================================");
return response;
});
final ClientHttpResponse response = execution.execute(request, body);
//
// StringBuilder inputStringBuilder = new StringBuilder();
// BufferedReader bufferedReader = new BufferedReader(new
// InputStreamReader(response.getBody(), "UTF-8"));
// String line = bufferedReader.readLine();
// while (line != null) {
// inputStringBuilder.append(line);
// inputStringBuilder.append('\n');
// line = bufferedReader.readLine();
// }
// LOG.debug("============================response
// begin==========================================");
// LOG.debug("status code: " + response.getStatusCode());
// LOG.debug("status text: " + response.getStatusText());
// LOG.debug("Response Body : " +
// inputStringBuilder.toString());
// LOG.debug("=======================response
// end=================================================");
return response;
});
restTemplate.setInterceptors(interceptors);
return restTemplate;
......@@ -315,10 +324,14 @@ public class S3StorageServiceImpl implements BytesStorageService {
* @param path the path
* @param filename the filename
* @return true, if successful
* @throws IOException
*/
@Override
public boolean exists(final String path, final String filename) {
public boolean exists(final String path, final String filename) throws IOException {
try {
if (LOG.isTraceEnabled()) {
LOG.trace("Fetching HEAD for url={}", getUrl(path, filename));
}
final HttpHeaders headers = restTemplate.headForHeaders(getUrl(path, filename));
if (LOG.isDebugEnabled()) {
headers.forEach((header, values) -> {
......@@ -364,9 +377,9 @@ public class S3StorageServiceImpl implements BytesStorageService {
if (listBucketResult.getContents() != null) {
listBucketResult.getContents().forEach(content -> {
LOG.debug("Object prefix={} len={} filename={}", content.getKey(), content.getSize(),
content.getKey().substring(s3prefix.length()));
});
LOG.debug("Object prefix={} len={} filename={}", content.getKey(), content.getSize(),
content.getKey().substring(s3prefix.length()));
});
}
}
......
......@@ -304,9 +304,10 @@ public class S3StorageServiceTest {
/**
* Ensure 404 exception is not thrown for non-existent file.
* @throws IOException
*/
@Test
public void testExistsWithoutExceptions() {
public void testExistsWithoutExceptions() throws IOException {
assertThat("File should not exist", bytesStorageService.exists(PATH, "file-should-not-exist"), is(false));
}
......@@ -329,4 +330,23 @@ public class S3StorageServiceTest {
assertThat("File must not exist", bytesStorageService.exists(PATH, FILENAME), is(false));
}
/**
* Ensure we are able to have a space in the repository path
*
* @throws IOException
*/
@Test
public void testSpaceInPath() throws IOException {
String pathWithSpace=PATH + "IRGC 11111/";
bytesStorageService.upsert(pathWithSpace, FILENAME, SOME_BYTES);
assertThat("File must exist", bytesStorageService.exists(pathWithSpace, FILENAME), is(true));
final List<String> x = bytesStorageService.listFiles(pathWithSpace);
assertThat("Size doesn't match", x, hasSize(1));
assertThat("File must not be missing from the list", x, contains(FILENAME));
bytesStorageService.remove(pathWithSpace, FILENAME);
assertThat("File must not exist", bytesStorageService.exists(pathWithSpace, FILENAME), is(false));
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment