diff options
author | adamw <adam@warski.org> | 2017-07-31 15:01:53 +0200 |
---|---|---|
committer | adamw <adam@warski.org> | 2017-07-31 15:01:53 +0200 |
commit | 1b4a5132c331965b09384ce0a99c495091e34f48 (patch) | |
tree | 4d4fcb431cfd81c585de9390ddd09fea7905b266 | |
parent | f34ad777382ca49c70a1dce655bfb6e483995716 (diff) | |
download | sttp-1b4a5132c331965b09384ce0a99c495091e34f48.tar.gz sttp-1b4a5132c331965b09384ce0a99c495091e34f48.tar.bz2 sttp-1b4a5132c331965b09384ce0a99c495091e34f48.zip |
Storing structured user info
3 files changed, 49 insertions, 36 deletions
diff --git a/core/src/main/scala/com/softwaremill/sttp/Uri.scala b/core/src/main/scala/com/softwaremill/sttp/Uri.scala index 6b2e840..1d4b0c6 100644 --- a/core/src/main/scala/com/softwaremill/sttp/Uri.scala +++ b/core/src/main/scala/com/softwaremill/sttp/Uri.scala @@ -2,7 +2,8 @@ package com.softwaremill.sttp import java.net.URLEncoder -import com.softwaremill.sttp.QueryFragment.{KeyValue, Plain} +import Uri.{QueryFragment, UserInfo} +import Uri.QueryFragment.{KeyValue, Plain} import scala.annotation.tailrec import scala.collection.immutable.Seq @@ -15,7 +16,7 @@ import scala.collection.immutable.Seq * added manually as part of the plain query fragment. */ case class Uri(scheme: String, - userInfo: Option[String], + userInfo: Option[UserInfo], host: String, port: Option[Int], path: Seq[String], @@ -37,9 +38,11 @@ case class Uri(scheme: String, def scheme(s: String): Uri = this.copy(scheme = s) - def userInfo(ui: String): Uri = this.copy(userInfo = Some(ui)) + def userInfo(username: String): Uri = + this.copy(userInfo = Some(UserInfo(username, None))) - def userInfo(ui: Option[String]): Uri = this.copy(userInfo = ui) + def userInfo(username: String, password: String): Uri = + this.copy(userInfo = Some(UserInfo(username, Some(password)))) def host(h: String): Uri = this.copy(host = h) @@ -92,10 +95,8 @@ case class Uri(scheme: String, def fragment(f: Option[String]): Uri = this.copy(fragment = f) override def toString: String = { - def encodeUserInfo(ui: String): String = ui.split(":", 2) match { - case Array(u) => encode(u) - case Array(u, p) => encode(u) + ":" + encode(p) - } + def encodeUserInfo(ui: UserInfo): String = + encode(ui.username) + ui.password.fold("")(":" + encode(_)) @tailrec def encodeQueryFragments(qfs: List[QueryFragment], @@ -165,31 +166,36 @@ case class Uri(scheme: String, } } -sealed trait QueryFragment -object QueryFragment { - - /** - * @param keyRelaxedEncoding See [[Plain.relaxedEncoding]] - * @param valueRelaxedEncoding See [[Plain.relaxedEncoding]] - */ - case class KeyValue(k: String, - v: String, - keyRelaxedEncoding: Boolean = false, - valueRelaxedEncoding: Boolean = false) - extends QueryFragment +object Uri { + sealed trait QueryFragment + object QueryFragment { + + /** + * @param keyRelaxedEncoding See [[Plain.relaxedEncoding]] + * @param valueRelaxedEncoding See [[Plain.relaxedEncoding]] + */ + case class KeyValue(k: String, + v: String, + keyRelaxedEncoding: Boolean = false, + valueRelaxedEncoding: Boolean = false) + extends QueryFragment + + /** + * A query fragment which will be inserted into the query, without and + * preceding or following separators. Allows constructing query strings + * which are not (only) &-separated key-value pairs. + * + * @param relaxedEncoding Should characters, which are allowed in the + * query string, but normally escaped be left unchanged. These characters + * are: + * {{{ + * /?:@-._~!$&()*+,;= + * }}} + * See: [[https://stackoverflow.com/questions/2322764/what-characters-must-be-escaped-in-an-http-query-string]] + */ + case class Plain(v: String, relaxedEncoding: Boolean = false) + extends QueryFragment + } - /** - * A query fragment which will be inserted into the query, without and - * preceding or following separators. Allows constructing query strings - * which are not (only) &-separated key-value pairs. - * - * @param relaxedEncoding Should characters, which are allowed in the query - * string, but normally escaped be left unchanged. These characters are: - * {{{ - * /?:@-._~!$&()*+,;= - * }}} - * See: [[https://stackoverflow.com/questions/2322764/what-characters-must-be-escaped-in-an-http-query-string]] - */ - case class Plain(v: String, relaxedEncoding: Boolean = false) - extends QueryFragment + case class UserInfo(username: String, password: Option[String]) } diff --git a/core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala b/core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala index 025f626..eec0b20 100644 --- a/core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala +++ b/core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala @@ -215,7 +215,7 @@ object UriInterpolator { } override def build: Uri = { - import com.softwaremill.sttp.{QueryFragment => QF} + import com.softwaremill.sttp.Uri.{QueryFragment => QF} val plainSeparator = QF.Plain("&", relaxedEncoding = true) var fragments: Vector[QF] = fs.flatMap { diff --git a/core/src/test/scala/com/softwaremill/sttp/UriTests.scala b/core/src/test/scala/com/softwaremill/sttp/UriTests.scala index e137d5c..628df6d 100644 --- a/core/src/test/scala/com/softwaremill/sttp/UriTests.scala +++ b/core/src/test/scala/com/softwaremill/sttp/UriTests.scala @@ -1,5 +1,6 @@ package com.softwaremill.sttp +import com.softwaremill.sttp.Uri.{QueryFragment, UserInfo} import org.scalatest.{FunSuite, Matchers} class UriTests extends FunSuite with Matchers { @@ -31,7 +32,13 @@ class UriTests extends FunSuite with Matchers { List(QF.KeyValue("p:1", "v&v"), QF.KeyValue("p2", "v v")), None) -> "http://exa%20mple.com/a%20b/z/%C4%85%3A%C4%99?p%3A1=v%26v&p2=v+v", - Uri("http", Some("us&er:pa ss"), "example.com", None, Nil, Nil, None) -> + Uri("http", + Some(UserInfo("us&er", Some("pa ss"))), + "example.com", + None, + Nil, + Nil, + None) -> "http://us%26er:pa%20ss@example.com", ) |