=htc #19650 expse effectivePort on Uri, better port handling
* =htc #19650 Public access to effectivePort in Uri * =htc #19650 normalize port as late as possible
This commit is contained in:
parent
14320f4801
commit
0aea3af0ad
5 changed files with 48 additions and 26 deletions
|
|
@ -53,7 +53,7 @@ object WebSocketClientBlueprint {
|
|||
val valve = StreamUtils.OneTimeValve()
|
||||
|
||||
val (initialRequest, key) = Handshake.Client.buildRequest(uri, extraHeaders, subprotocol.toList, settings.websocketRandomFactory())
|
||||
val hostHeader = Host(uri.authority)
|
||||
val hostHeader = Host(uri.authority.normalizedFor(uri.scheme))
|
||||
val renderedInitialRequest =
|
||||
HttpRequestRendererFactory.renderStrict(RequestRenderingContext(initialRequest, hostHeader), settings, log)
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ case class JavaUri(uri: sm.Uri) extends jm.Uri {
|
|||
|
||||
def scheme(): String = uri.scheme
|
||||
def host(): jm.Host = uri.authority.host
|
||||
def port(): Int = uri.authority.port
|
||||
def port(): Int = uri.effectivePort
|
||||
def userInfo(): String = uri.authority.userinfo
|
||||
|
||||
def path(): String = uri.path.toString
|
||||
|
|
|
|||
|
|
@ -43,13 +43,11 @@ sealed abstract case class Uri(scheme: String, authority: Authority, path: Path,
|
|||
def queryString(charset: Charset = UTF8): Option[String] = rawQueryString.map(s ⇒ decode(s, charset))
|
||||
|
||||
/**
|
||||
* INTERNAL API
|
||||
*
|
||||
* The effective port of this Uri given the currently set authority and scheme values.
|
||||
* If the authority has an explicitly set port (i.e. a non-zero port value) then this port
|
||||
* is the effective port. Otherwise the default port for the current scheme is returned.
|
||||
*/
|
||||
private[akka] def effectivePort: Int = if (authority.port != 0) authority.port else defaultPorts(scheme)
|
||||
def effectivePort: Int = if (authority.port != 0) authority.port else defaultPorts(scheme)
|
||||
|
||||
/**
|
||||
* Returns a copy of this Uri with the given components.
|
||||
|
|
@ -210,7 +208,7 @@ object Uri {
|
|||
|
||||
/**
|
||||
* Creates a new Uri instance from the given components.
|
||||
* All components are verified and normalized.
|
||||
* All components are verified and normalized except the authority which is kept as provided.
|
||||
* If the given combination of components does not constitute a valid URI as defined by
|
||||
* http://tools.ietf.org/html/rfc3986 the method throws an `IllegalUriException`.
|
||||
*/
|
||||
|
|
@ -219,7 +217,7 @@ object Uri {
|
|||
val p = verifyPath(path, scheme, authority.host)
|
||||
create(
|
||||
scheme = normalizeScheme(scheme),
|
||||
authority = authority.normalizedFor(scheme),
|
||||
authority = authority,
|
||||
path = if (scheme.isEmpty) p else collapseDotSegments(p),
|
||||
queryString = queryString,
|
||||
fragment = fragment)
|
||||
|
|
@ -277,8 +275,11 @@ object Uri {
|
|||
* If strict is `false`, accepts unencoded visible 7-bit ASCII characters in addition to the RFC.
|
||||
* If the given string is not a valid URI the method throws an `IllegalUriException`.
|
||||
*/
|
||||
def normalize(uri: ParserInput, charset: Charset = UTF8, mode: Uri.ParsingMode = Uri.ParsingMode.Relaxed): String =
|
||||
UriRendering.renderUri(new StringRendering, apply(uri, charset, mode), charset).get
|
||||
def normalize(uri: ParserInput, charset: Charset = UTF8, mode: Uri.ParsingMode = Uri.ParsingMode.Relaxed): String = {
|
||||
val parsed = apply(uri, charset, mode)
|
||||
val normalized = parsed.copy(authority = parsed.authority.normalizedFor(parsed.scheme))
|
||||
UriRendering.renderUri(new StringRendering, normalized, charset).get
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a set of URI components to an "effective HTTP request URI" as defined by
|
||||
|
|
@ -307,6 +308,10 @@ object Uri {
|
|||
|
||||
def httpScheme(securedConnection: Boolean = false) = if (securedConnection) "https" else "http"
|
||||
|
||||
/**
|
||||
* @param port A port number that may be `0` to signal the default port of for scheme.
|
||||
* In general what you want is not the value of this field but [[Uri.effectivePort]].
|
||||
*/
|
||||
final case class Authority(host: Host, port: Int = 0, userinfo: String = "") {
|
||||
def isEmpty = equals(Authority.Empty)
|
||||
def nonEmpty = !isEmpty
|
||||
|
|
@ -742,7 +747,7 @@ object Uri {
|
|||
|
||||
private[http] def create(scheme: String, userinfo: String, host: Host, port: Int, path: Path, queryString: Option[String],
|
||||
fragment: Option[String]): Uri =
|
||||
create(scheme, Authority(host, normalizePort(port, scheme), userinfo), path, queryString, fragment)
|
||||
create(scheme, Authority(host, port, userinfo), path, queryString, fragment)
|
||||
|
||||
private[http] def create(scheme: String, authority: Authority, path: Path, queryString: Option[String],
|
||||
fragment: Option[String]): Uri =
|
||||
|
|
|
|||
|
|
@ -382,7 +382,7 @@ class UriSpec extends WordSpec with Matchers {
|
|||
|
||||
// empty host
|
||||
Uri("http://:8000/foo") shouldEqual Uri("http", Authority(Host.Empty, 8000), Path / "foo")
|
||||
Uri("http://:80/foo") shouldEqual Uri("http", Authority.Empty, Path / "foo")
|
||||
Uri("http://:80/foo") shouldEqual Uri("http", Authority(Host.Empty, 80), Path / "foo")
|
||||
}
|
||||
|
||||
"properly complete a normalization cycle" in {
|
||||
|
|
@ -571,38 +571,55 @@ class UriSpec extends WordSpec with Matchers {
|
|||
}
|
||||
|
||||
"provide sugar for fluent transformations" in {
|
||||
val uri = Uri("http://host:80/path?query#fragment")
|
||||
val uri = Uri("http://host/path?query#fragment")
|
||||
val explicitDefault = Uri("http://host:80/path?query#fragment")
|
||||
val nonDefaultUri = Uri("http://host:6060/path?query#fragment")
|
||||
|
||||
uri.withScheme("https") shouldEqual Uri("https://host/path?query#fragment")
|
||||
explicitDefault.withScheme("https") shouldEqual Uri("https://host:80/path?query#fragment")
|
||||
nonDefaultUri.withScheme("https") shouldEqual Uri("https://host:6060/path?query#fragment")
|
||||
|
||||
uri.withAuthority(Authority(Host("other"), 3030)) shouldEqual Uri("http://other:3030/path?query#fragment")
|
||||
uri.withAuthority(Host("other"), 3030) shouldEqual Uri("http://other:3030/path?query#fragment")
|
||||
uri.withAuthority("other", 3030) shouldEqual Uri("http://other:3030/path?query#fragment")
|
||||
|
||||
uri.withHost(Host("other")) shouldEqual Uri("http://other:80/path?query#fragment")
|
||||
uri.withHost("other") shouldEqual Uri("http://other:80/path?query#fragment")
|
||||
uri.withHost(Host("other")) shouldEqual Uri("http://other/path?query#fragment")
|
||||
explicitDefault.withHost(Host("other")) shouldEqual Uri("http://other:80/path?query#fragment")
|
||||
uri.withHost("other") shouldEqual Uri("http://other/path?query#fragment")
|
||||
explicitDefault.withHost("other") shouldEqual Uri("http://other:80/path?query#fragment")
|
||||
uri.withPort(90) shouldEqual Uri("http://host:90/path?query#fragment")
|
||||
explicitDefault.withPort(90) shouldEqual Uri("http://host:90/path?query#fragment")
|
||||
|
||||
uri.withPath(Path("/newpath")) shouldEqual Uri("http://host/newpath?query#fragment")
|
||||
uri.withUserInfo("someInfo") shouldEqual Uri("http://someInfo@host:80/path?query#fragment")
|
||||
explicitDefault.withPath(Path("/newpath")) shouldEqual Uri("http://host:80/newpath?query#fragment")
|
||||
|
||||
uri.withQuery(Query("param1" -> "value1")) shouldEqual Uri("http://host:80/path?param1=value1#fragment")
|
||||
uri.withQuery(Query(Map("param1" -> "value1"))) shouldEqual Uri("http://host:80/path?param1=value1#fragment")
|
||||
uri.withRawQueryString("param1=value1") shouldEqual Uri("http://host:80/path?param1=value1#fragment")
|
||||
uri.withUserInfo("someInfo") shouldEqual Uri("http://someInfo@host/path?query#fragment")
|
||||
explicitDefault.withUserInfo("someInfo") shouldEqual Uri("http://someInfo@host:80/path?query#fragment")
|
||||
|
||||
uri.withFragment("otherFragment") shouldEqual Uri("http://host:80/path?query#otherFragment")
|
||||
uri.withQuery(Query("param1" -> "value1")) shouldEqual Uri("http://host/path?param1=value1#fragment")
|
||||
uri.withQuery(Query(Map("param1" -> "value1"))) shouldEqual Uri("http://host/path?param1=value1#fragment")
|
||||
uri.withRawQueryString("param1=value1") shouldEqual Uri("http://host/path?param1=value1#fragment")
|
||||
|
||||
uri.withFragment("otherFragment") shouldEqual Uri("http://host/path?query#otherFragment")
|
||||
}
|
||||
|
||||
"return the correct effective port" in {
|
||||
80 shouldEqual Uri("http://host/").effectivePort
|
||||
21 shouldEqual Uri("ftp://host/").effectivePort
|
||||
9090 shouldEqual Uri("http://host:9090/").effectivePort
|
||||
443 shouldEqual Uri("https://host/").effectivePort
|
||||
Uri("http://host/").effectivePort shouldEqual 80
|
||||
Uri("ftp://host/").effectivePort shouldEqual 21
|
||||
Uri("http://host:9090/").effectivePort shouldEqual 9090
|
||||
Uri("https://host/").effectivePort shouldEqual 443
|
||||
|
||||
4450 shouldEqual Uri("https://host/").withPort(4450).effectivePort
|
||||
4450 shouldEqual Uri("https://host:3030/").withPort(4450).effectivePort
|
||||
Uri("https://host/").withPort(4450).effectivePort shouldEqual 4450
|
||||
Uri("https://host:3030/").withPort(4450).effectivePort shouldEqual 4450
|
||||
}
|
||||
|
||||
"keep the specified authority port" in {
|
||||
Uri("example.com").withPort(0).authority.port shouldEqual 0
|
||||
Uri("example.com").withPort(80).authority.port shouldEqual 80
|
||||
Uri("http://example.com").withPort(80).authority.port shouldEqual 80
|
||||
Uri("http://example.com").withPort(0).authority.port shouldEqual 0
|
||||
Uri("https://example.com").withPort(0).authority.port shouldEqual 0
|
||||
Uri("https://example.com").withPort(443).authority.port shouldEqual 443
|
||||
}
|
||||
|
||||
"properly render as HTTP request target origin forms" in {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue