Skip to content
This repository was archived by the owner on Feb 26, 2025. It is now read-only.

Fixed URI encoding with special characters #117

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 24 additions & 11 deletions src/main/java/com/upplication/s3fs/S3Path.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
package com.upplication.s3fs;

import com.google.common.base.*;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.upplication.s3fs.attribute.S3BasicFileAttributes;
import static com.google.common.collect.Iterables.concat;
import static java.lang.String.format;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.file.*;
import java.net.URLEncoder;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.Iterator;
import java.util.List;

import static com.google.common.collect.Iterables.*;
import static java.lang.String.format;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.upplication.s3fs.attribute.S3BasicFileAttributes;

public class S3Path implements Path {

@@ -583,10 +589,17 @@ public int hashCode() {
* @return String
*/
private String encode(String uri) {
// remove special case URI starting with //
uri = uri.replace("//", "/");
uri = uri.replaceAll(" ", "%20");
return uri;
try {
// URL encode all characters, but then convert known allowed characters back
return URLEncoder.encode(uri, "UTF-8")
.replace("%3A", ":")
.replace("%2F", "/")
.replace("+", "%20");
} catch (UnsupportedEncodingException e) {
// This should never happen unless there is something
// fundamentally broken with the running JVM.
throw new RuntimeException(e);
}
}

/**
43 changes: 31 additions & 12 deletions src/test/java/com/upplication/s3fs/Path/ToUriTest.java
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
package com.upplication.s3fs.Path;

import com.google.common.collect.ImmutableMap;
import com.upplication.s3fs.S3FileSystem;
import com.upplication.s3fs.S3FileSystemProvider;
import com.upplication.s3fs.S3Path;
import com.upplication.s3fs.S3UnitTestBase;
import com.upplication.s3fs.util.S3EndpointConstant;
import org.junit.Before;
import org.junit.Test;
import static com.upplication.s3fs.AmazonS3Factory.ACCESS_KEY;
import static com.upplication.s3fs.AmazonS3Factory.SECRET_KEY;
import static com.upplication.s3fs.util.S3EndpointConstant.S3_GLOBAL_URI_TEST;
import static org.junit.Assert.assertEquals;

import java.io.IOException;
import java.net.URI;
import java.nio.file.FileSystem;
import java.nio.file.Path;
import java.util.Map;

import static com.upplication.s3fs.AmazonS3Factory.ACCESS_KEY;
import static com.upplication.s3fs.AmazonS3Factory.SECRET_KEY;
import static com.upplication.s3fs.util.S3EndpointConstant.*;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import com.google.common.collect.ImmutableMap;
import com.upplication.s3fs.S3FileSystem;
import com.upplication.s3fs.S3FileSystemProvider;
import com.upplication.s3fs.S3Path;
import com.upplication.s3fs.S3UnitTestBase;
import com.upplication.s3fs.util.S3EndpointConstant;

public class ToUriTest extends S3UnitTestBase {

@@ -50,6 +50,25 @@ public void toUri() {
assertEquals(path, pathActual);
}

@Test
public void toUriSpecialChars() {
Path path = getPath("/bucket/([fol! @#$%der])");
URI uri = path.toUri();

// the scheme is s3
assertEquals("s3", uri.getScheme());

// could get the correct fileSystem
S3FileSystem fs = s3fsProvider.getFileSystem(uri);
// the host is the endpoint specified in fileSystem
assertEquals(fs.getEndpoint(), uri.getHost());

// bucket name as first path
Path pathActual = fs.provider().getPath(uri);

assertEquals(path, pathActual);
}

@Test
public void toUriWithEndSlash() {
S3Path s3Path = getPath("/bucket/folder/");