HADOOP-14114 S3A can no longer handle unencoded + in URIs. Contributed by Sean Mackrory.
(cherry picked from commit ff87ca8441
)
This commit is contained in:
parent
650ff95e00
commit
c6d7da2112
|
@ -48,6 +48,13 @@ public final class S3xLoginHelper {
|
||||||
"The Filesystem URI contains login details."
|
"The Filesystem URI contains login details."
|
||||||
+" This is insecure and may be unsupported in future.";
|
+" This is insecure and may be unsupported in future.";
|
||||||
|
|
||||||
|
public static final String PLUS_WARNING =
|
||||||
|
"Secret key contains a special character that should be URL encoded! " +
|
||||||
|
"Attempting to resolve...";
|
||||||
|
|
||||||
|
public static final String PLUS_UNENCODED = "+";
|
||||||
|
public static final String PLUS_ENCODED = "%2B";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build the filesystem URI. This can include stripping down of part
|
* Build the filesystem URI. This can include stripping down of part
|
||||||
* of the URI.
|
* of the URI.
|
||||||
|
@ -112,7 +119,13 @@ public final class S3xLoginHelper {
|
||||||
int loginSplit = login.indexOf(':');
|
int loginSplit = login.indexOf(':');
|
||||||
if (loginSplit > 0) {
|
if (loginSplit > 0) {
|
||||||
String user = login.substring(0, loginSplit);
|
String user = login.substring(0, loginSplit);
|
||||||
String password = URLDecoder.decode(login.substring(loginSplit + 1),
|
String encodedPassword = login.substring(loginSplit + 1);
|
||||||
|
if (encodedPassword.contains(PLUS_UNENCODED)) {
|
||||||
|
LOG.warn(PLUS_WARNING);
|
||||||
|
encodedPassword = encodedPassword.replaceAll("\\" + PLUS_UNENCODED,
|
||||||
|
PLUS_ENCODED);
|
||||||
|
}
|
||||||
|
String password = URLDecoder.decode(encodedPassword,
|
||||||
"UTF-8");
|
"UTF-8");
|
||||||
return new Login(user, password);
|
return new Login(user, password);
|
||||||
} else if (loginSplit == 0) {
|
} else if (loginSplit == 0) {
|
||||||
|
|
|
@ -32,9 +32,13 @@ public class TestS3xLoginHelper extends Assert {
|
||||||
public static final String BUCKET = "s3a://bucket";
|
public static final String BUCKET = "s3a://bucket";
|
||||||
private static final URI ENDPOINT = uri(BUCKET);
|
private static final URI ENDPOINT = uri(BUCKET);
|
||||||
public static final String S = "%2f";
|
public static final String S = "%2f";
|
||||||
|
public static final String P = "%2b";
|
||||||
|
public static final String P_RAW = "+";
|
||||||
public static final String USER = "user";
|
public static final String USER = "user";
|
||||||
public static final String PASS = "pass";
|
public static final String PASS = "pass";
|
||||||
public static final String PASLASHSLASH = "pa" + S + S;
|
public static final String PASLASHSLASH = "pa" + S + S;
|
||||||
|
public static final String PAPLUS = "pa" + P;
|
||||||
|
public static final String PAPLUS_RAW = "pa" + P_RAW;
|
||||||
|
|
||||||
public static final URI WITH_USER_AND_PASS = uri("s3a://user:pass@bucket");
|
public static final URI WITH_USER_AND_PASS = uri("s3a://user:pass@bucket");
|
||||||
public static final Path PATH_WITH_LOGIN =
|
public static final Path PATH_WITH_LOGIN =
|
||||||
|
@ -42,6 +46,10 @@ public class TestS3xLoginHelper extends Assert {
|
||||||
|
|
||||||
public static final URI WITH_SLASH_IN_PASS = uri(
|
public static final URI WITH_SLASH_IN_PASS = uri(
|
||||||
"s3a://user:" + PASLASHSLASH + "@bucket");
|
"s3a://user:" + PASLASHSLASH + "@bucket");
|
||||||
|
public static final URI WITH_PLUS_IN_PASS = uri(
|
||||||
|
"s3a://user:" + PAPLUS + "@bucket");
|
||||||
|
public static final URI WITH_PLUS_RAW_IN_PASS = uri(
|
||||||
|
"s3a://user:" + PAPLUS_RAW + "@bucket");
|
||||||
public static final URI USER_NO_PASS = uri("s3a://user@bucket");
|
public static final URI USER_NO_PASS = uri("s3a://user@bucket");
|
||||||
public static final URI WITH_USER_AND_COLON = uri("s3a://user:@bucket");
|
public static final URI WITH_USER_AND_COLON = uri("s3a://user:@bucket");
|
||||||
public static final URI NO_USER = uri("s3a://:pass@bucket");
|
public static final URI NO_USER = uri("s3a://:pass@bucket");
|
||||||
|
@ -116,6 +124,16 @@ public class TestS3xLoginHelper extends Assert {
|
||||||
assertMatchesLogin(USER, "pa//", WITH_SLASH_IN_PASS);
|
assertMatchesLogin(USER, "pa//", WITH_SLASH_IN_PASS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLoginWithPlusInPass() throws Throwable {
|
||||||
|
assertMatchesLogin(USER, "pa+", WITH_PLUS_IN_PASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLoginWithPlusRawInPass() throws Throwable {
|
||||||
|
assertMatchesLogin(USER, "pa+", WITH_PLUS_RAW_IN_PASS);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLoginWithUser() throws Throwable {
|
public void testLoginWithUser() throws Throwable {
|
||||||
assertMatchesLogin(USER, "", USER_NO_PASS);
|
assertMatchesLogin(USER, "", USER_NO_PASS);
|
||||||
|
@ -151,6 +169,16 @@ public class TestS3xLoginHelper extends Assert {
|
||||||
assertMatchesEndpoint(WITH_SLASH_IN_PASS);
|
assertMatchesEndpoint(WITH_SLASH_IN_PASS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFsUriWithPlusInPass() throws Throwable {
|
||||||
|
assertMatchesEndpoint(WITH_PLUS_IN_PASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFsUriWithPlusRawInPass() throws Throwable {
|
||||||
|
assertMatchesEndpoint(WITH_PLUS_RAW_IN_PASS);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFsUriWithUser() throws Throwable {
|
public void testFsUriWithUser() throws Throwable {
|
||||||
assertMatchesEndpoint(USER_NO_PASS);
|
assertMatchesEndpoint(USER_NO_PASS);
|
||||||
|
|
Loading…
Reference in New Issue