Make UriComponentsBuilder.fromOriginHeader() IPv6 compliant

Issue: SPR-13525
This commit is contained in:
Sebastien Deleuze
2015-10-01 11:14:38 +02:00
parent b7c2881a4f
commit 1c6febc45c
2 changed files with 24 additions and 19 deletions

View File

@@ -338,31 +338,28 @@ public class UriComponentsBuilder implements Cloneable {
/**
* Create an instance by parsing the "origin" header of an HTTP request.
* Create an instance by parsing the "Origin" header of an HTTP request.
* @see <a href="https://tools.ietf.org/html/rfc6454">RFC 6454</a>
*/
public static UriComponentsBuilder fromOriginHeader(String origin) {
UriComponentsBuilder builder = UriComponentsBuilder.newInstance();
if (StringUtils.hasText(origin)) {
int schemaIdx = origin.indexOf("://");
String schema = (schemaIdx != -1 ? origin.substring(0, schemaIdx) : "http");
builder.scheme(schema);
String hostString = (schemaIdx != -1 ? origin.substring(schemaIdx + 3) : origin);
// Handling of invalid origins as described in SPR-13478
int firstSlashIdx = hostString.indexOf("/");
if (firstSlashIdx != -1) {
hostString = hostString.substring(0, firstSlashIdx);
Matcher matcher = URI_PATTERN.matcher(origin);
if (matcher.matches()) {
UriComponentsBuilder builder = new UriComponentsBuilder();
String scheme = matcher.group(2);
String host = matcher.group(6);
String port = matcher.group(8);
if (StringUtils.hasLength(scheme)) {
builder.scheme(scheme);
}
if (hostString.contains(":")) {
String[] hostAndPort = StringUtils.split(hostString, ":");
builder.host(hostAndPort[0]);
builder.port(Integer.parseInt(hostAndPort[1]));
}
else {
builder.host(hostString);
builder.host(host);
if (StringUtils.hasLength(port)) {
builder.port(port);
}
return builder;
}
else {
throw new IllegalArgumentException("[" + origin + "] is not a valid \"Origin\" header value");
}
return builder;
}

View File

@@ -142,6 +142,14 @@ public class WebUtilsTests {
assertFalse(checkSameOrigin("mydomain2.com", -1, "http://mydomain1.com:80/"));
assertFalse(checkSameOrigin("mydomain2.com", -1, "http://mydomain1.com/path"));
assertFalse(checkSameOrigin("mydomain2.com", -1, "http://mydomain1.com:80/path"));
// Handling of IPv6 hosts as described in SPR-13525
assertTrue(checkSameOrigin("[::1]", -1, "http://[::1]"));
assertTrue(checkSameOrigin("[::1]", 8080, "http://[::1]:8080"));
assertTrue(checkSameOrigin("[2001:0db8:0000:85a3:0000:0000:ac1f:8001]", -1, "http://[2001:0db8:0000:85a3:0000:0000:ac1f:8001]"));
assertTrue(checkSameOrigin("[2001:0db8:0000:85a3:0000:0000:ac1f:8001]", 8080, "http://[2001:0db8:0000:85a3:0000:0000:ac1f:8001]:8080"));
assertFalse(checkSameOrigin("[::1]", -1, "http://[::1]:8080"));
assertFalse(checkSameOrigin("[::1]", 8080, "http://[2001:0db8:0000:85a3:0000:0000:ac1f:8001]:8080"));
}