Merge branch '7.0.x'

This commit is contained in:
rstoyanchev
2026-08-07 10:32:13 +03:00
5 changed files with 28 additions and 11 deletions
@@ -24,6 +24,7 @@ import org.jspecify.annotations.Nullable;
import org.springframework.core.log.LogDelegateFactory;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Parser for URIs based on RFC 3986 syntax.
@@ -545,7 +546,8 @@ abstract class RfcUriParser {
public InternalParser capturePort() {
verify(this.openCurlyBracketCount == 0, this, "Bad authority");
this.port = captureComponent("port");
String value = captureComponent("port");
this.port = (StringUtils.hasText(value) ? value : null);
return this;
}
@@ -73,7 +73,7 @@ public interface UriBuilder {
/**
* Set the URI port. Use this method only when the port needs to be
* parameterized with a URI variable. Otherwise use {@link #port(int)}.
* Passing {@code null} will clear the port of this builder.
* Passing {@code null} or an empty String will clear the port of this builder.
* @param port the URI port
*/
UriBuilder port(@Nullable String port);
@@ -513,7 +513,7 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable {
@Override
public UriComponentsBuilder port(@Nullable String port) {
this.port = port;
this.port = (StringUtils.hasText(port) ? port : null);
if (port != null) {
resetSchemeSpecificPart();
}
@@ -937,11 +937,17 @@ class UriComponentsBuilderTests {
@ParameterizedTest
@EnumSource
void verifyInvalidPort(ParserType parserType) {
String url = "http://localhost:XXX/path";
assertThatIllegalArgumentException()
.isThrownBy(() -> UriComponentsBuilder.fromUriString(url, parserType).build().toUri());
assertThatIllegalArgumentException()
.isThrownBy(() -> UriComponentsBuilder.fromUriString(url, parserType).build().toUri());
assertThatIllegalArgumentException().isThrownBy(() ->
UriComponentsBuilder.fromUriString("http://localhost:XXX/path", parserType).build().toUri());
}
@ParameterizedTest // gh-37117
@EnumSource
void verifyEmptyPort(ParserType parserType) {
URI uri = UriComponentsBuilder.fromUriString("http://localhost:/path", parserType).build().toUri();
assertThat(uri.getHost()).isEqualTo("localhost");
assertThat(uri.getPort()).isEqualTo(-1);
assertThat(uri.getPath()).isEqualTo("/path");
}
@ParameterizedTest // gh-27039
@@ -196,21 +196,30 @@ class UriComponentsTests {
@ParameterizedTest // gh-28521
@EnumSource
void invalidPort(ParserType parserType) {
void invalidPortParsed(ParserType parserType) {
assertThatExceptionOfType(InvalidUrlException.class)
.isThrownBy(() -> fromUriString("https://example.com:XXX/bar", parserType));
assertExceptionsForInvalidPort(fromUriString("https://example.com/bar", parserType).port("XXX").build());
}
private void assertExceptionsForInvalidPort(UriComponents uriComponents) {
@Test
void invalidPortSet() {
UriComponents uriComponents = fromUriString("https://example.com/bar").port("XXX").build();
assertThatIllegalStateException()
.isThrownBy(uriComponents::getPort)
.withMessage("The port must be an integer: XXX");
assertThatIllegalStateException()
.isThrownBy(uriComponents::toUri)
.withMessage("The port must be an integer: XXX");
}
@Test // gh-37117
void emptyPortSet() {
UriComponents uriComponents = fromUriString("https://example.com/bar").port("").build();
assertThat(uriComponents.getPort()).isEqualTo(-1);
}
@Test
void expandEncoded() {
assertThatIllegalStateException().isThrownBy(() ->