Skip to content

UriComponentsBuilder.fromUriString may not parse correctly when there is no path [SPR-11970] #16586

Closed
@spring-projects-issues

Description

@spring-projects-issues

Kazuki Shimizu opened SPR-11970 and commented

e.g.) "http://example.com?..." and "http://example.com/?..." has different behavior.

For following example...
If not specify path in uri, string of up to '@' in the query parameters is recognized as a UserInfo.

Test code

	public static void main(String[] args) throws URISyntaxException,
			UnsupportedEncodingException {

		UriComponentsBuilder builder = UriComponentsBuilder.newInstance();
		builder.uri(new URI("http://example.com"));
		builder.queryParam("key1 ", "value1 ");
		builder.queryParam("key2+", "value2+");
		builder.queryParam("key3&", "value3&");
		builder.queryParam("key4=", "value4=");
		// parameters that not require encoding
		builder.queryParam(
				"key5abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~:@/?!$'()*,;",
				"value5abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~:@/?!$'()*,;");

		UriComponents uriComponents = builder.build().encode("UTF-8");
		String uriString = uriComponents.toUriString();

		System.out.println("----- Before -------");
		System.out.println("UriString :" + uriString);
		System.out.println("Scheme :" + uriComponents.getScheme());
		System.out.println("UserInfo :" + uriComponents.getUserInfo());
		System.out.println("Host :" + uriComponents.getHost());
		System.out.println("Port :" + uriComponents.getPort());
		System.out.println("Path :" + uriComponents.getPath());
		System.out.println("Query :" + uriComponents.getQuery());
		System.out.println("Fragment :" + uriComponents.getFragment());
		System.out.println("QueryParams :" + uriComponents.getQueryParams());

		builder = UriComponentsBuilder.fromUriString(uriString);
		uriComponents = builder.build();
		uriString = uriComponents.toUriString();

		System.out.println("----- After -------");
		System.out.println("UriString :" + uriString);
		System.out.println("Scheme :" + uriComponents.getScheme());
		System.out.println("UserInfo :" + uriComponents.getUserInfo());
		System.out.println("Host :" + uriComponents.getHost());
		System.out.println("Port :" + uriComponents.getPort());
		System.out.println("Path :" + uriComponents.getPath());
		System.out.println("Query :" + uriComponents.getQuery());
		System.out.println("Fragment :" + uriComponents.getFragment());
		System.out.println("QueryParams :" + uriComponents.getQueryParams());
	}

Console

----- Before -------
UriString :http://example.com?key1%20=value1%20&key2%2B=value2%2B&key3%26=value3%26&key4%3D=value4%3D&key5abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~:@/?!$'()*,;=value5abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~:@/?!$'()*,;
Scheme :http
UserInfo :null
Host :example.com
Port :-1
Path :null
Query :key1%20=value1%20&key2%2B=value2%2B&key3%26=value3%26&key4%3D=value4%3D&key5abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~:@/?!$'()*,;=value5abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~:@/?!$'()*,;
Fragment :null
QueryParams :{key1%20=[value1%20], key2%2B=[value2%2B], key3%26=[value3%26], key4%3D=[value4%3D], key5abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~:@/?!$'()*,;=[value5abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~:@/?!$'()*,;]}
----- After -------
UriString :http://example.com?key1%20=value1%20&key2%2B=value2%2B&key3%26=value3%26&key4%3D=value4%3D&key5abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~:@/?!$'()*,;=value5abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~:@/?!$'()*,;
Scheme :http
UserInfo :example.com?key1%20=value1%20&key2%2B=value2%2B&key3%26=value3%26&key4%3D=value4%3D&key5abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~:
Host :
Port :-1
Path :/
Query :!$'()*,;=value5abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~:@/?!$'()*,;
Fragment :null
QueryParams :{!$'()*,;=[value5abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~:@/?!$'()*,;]}

If specify path in uri, result are following.
Before and after is same. (this behavior is correct.)

----- Before -------
UriString :http://example.com/?key1%20=value1%20&key2%2B=value2%2B&key3%26=value3%26&key4%3D=value4%3D&key5abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~:@/?!$'()*,;=value5abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~:@/?!$'()*,;
Scheme :http
UserInfo :null
Host :example.com
Port :-1
Path :/
Query :key1%20=value1%20&key2%2B=value2%2B&key3%26=value3%26&key4%3D=value4%3D&key5abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~:@/?!$'()*,;=value5abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~:@/?!$'()*,;
Fragment :null
QueryParams :{key1%20=[value1%20], key2%2B=[value2%2B], key3%26=[value3%26], key4%3D=[value4%3D], key5abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~:@/?!$'()*,;=[value5abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~:@/?!$'()*,;]}
----- After -------
UriString :http://example.com/?key1%20=value1%20&key2%2B=value2%2B&key3%26=value3%26&key4%3D=value4%3D&key5abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~:@/?!$'()*,;=value5abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~:@/?!$'()*,;
Scheme :http
UserInfo :null
Host :example.com
Port :-1
Path :/
Query :key1%20=value1%20&key2%2B=value2%2B&key3%26=value3%26&key4%3D=value4%3D&key5abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~:@/?!$'()*,;=value5abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~:@/?!$'()*,;
Fragment :null
QueryParams :{key1%20=[value1%20], key2%2B=[value2%2B], key3%26=[value3%26], key4%3D=[value4%3D], key5abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~:@/?!$'()*,;=[value5abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~:@/?!$'()*,;]}

Affects: 3.2.9, 4.0.5

Backported to: 3.2.11

Metadata

Metadata

Assignees

Labels

in: webIssues in web modules (web, webmvc, webflux, websocket)status: backportedAn issue that has been backported to maintenance branchestype: bugA general bug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions