diff options
author | adamw <adam@warski.org> | 2017-11-25 10:59:09 +0100 |
---|---|---|
committer | adamw <adam@warski.org> | 2017-11-25 10:59:09 +0100 |
commit | 2db11d0cdcc2e6bc0ad2fd321d9c15693ee71876 (patch) | |
tree | 0274e89c469eee44ab74e843d8bb89f4afaca53d /core | |
parent | 7611a82978da965d133d78dc8787b8edefee1661 (diff) | |
download | sttp-2db11d0cdcc2e6bc0ad2fd321d9c15693ee71876.tar.gz sttp-2db11d0cdcc2e6bc0ad2fd321d9c15693ee71876.tar.bz2 sttp-2db11d0cdcc2e6bc0ad2fd321d9c15693ee71876.zip |
Special case in the uri interpolator which allows embedding host with the port included
Diffstat (limited to 'core')
-rw-r--r-- | core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala | 21 | ||||
-rw-r--r-- | core/src/test/scala/com/softwaremill/sttp/UriInterpolatorTests.scala | 4 |
2 files changed, 22 insertions, 3 deletions
diff --git a/core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala b/core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala index fe19358..f0dbcba 100644 --- a/core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala +++ b/core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala @@ -42,6 +42,7 @@ object UriInterpolator { while (strings.hasNext) { val nextExpression = expressions.next() + val nextExpressionStr = nextExpression.toString // special case: the interpolation starts with an expression, which // contains a whole URI. In this case, parsing the expression as if @@ -49,7 +50,7 @@ object UriInterpolator { // way it's possible to extend existing URIs. Without special-casing // the embedded URI would be escaped and become part of the host // as a whole. - if (tokens == Vector(StringToken("")) && nextExpression.toString.contains( + if (tokens == Vector(StringToken("")) && nextExpressionStr.contains( "://")) { def tokenizeExpressionAsString(): Unit = { val (nextTokenizer, nextTokens) = @@ -305,7 +306,23 @@ object UriInterpolator { } } - private def hostPortFromTokens(u: Uri, hpTokens: Vector[Token]): Uri = { + private def hostPortFromTokens(u: Uri, + rawHpTokens: Vector[Token]): Uri = { + // Special case: if the host/port part contains an expression token, + // which has a string representation which contains a colon (:), then + // we assume that the intention was to embed the port and host separately, + // not to escape the colon in the host name. + val hpTokens = rawHpTokens.flatMap { + case e: ExpressionToken => + val es = tokensToString(Vector(e)) + es.split(":", 2) match { + case Array(_) => Vector(e) + case Array(h, p) => + Vector(StringToken(h), ColonInAuthority, StringToken(p)) + } + case t => Vector(t) + } + split(hpTokens, Set[Token](ColonInAuthority)) match { case Left(tt) => hostFromTokens(u, tt) case Right((hostTokens, _, portTokens)) => diff --git a/core/src/test/scala/com/softwaremill/sttp/UriInterpolatorTests.scala b/core/src/test/scala/com/softwaremill/sttp/UriInterpolatorTests.scala index 4f0c66f..e35a9d6 100644 --- a/core/src/test/scala/com/softwaremill/sttp/UriInterpolatorTests.scala +++ b/core/src/test/scala/com/softwaremill/sttp/UriInterpolatorTests.scala @@ -61,7 +61,9 @@ class UriInterpolatorTests extends FunSuite with Matchers { (uri"http://example.com:${8080}", s"http://example.com:8080"), (uri"http://example.com:${8080}/x", s"http://example.com:8080/x"), (uri"http://example.com:${Some(8080)}/x", s"http://example.com:8080/x"), - (uri"http://example.com:$None/x", s"http://example.com/x") + (uri"http://example.com:$None/x", s"http://example.com/x"), + (uri"http://${"example.com:8080"}", s"http://example.com:8080"), + (uri"http://${"example.com:8080"}:$None", s"http://example.com:8080") ), "path" -> List( (uri"http://example.com/$v1", s"http://example.com/$v1"), |