aboutsummaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
authoradamw <adam@warski.org>2017-08-02 14:02:13 +0200
committeradamw <adam@warski.org>2017-08-02 14:02:13 +0200
commit4fd5b1570c006a7ad5e022cadb9f41decf51d866 (patch)
treedc1b2fc77e622ca14b8278e54d4a3ad73aaeb71c /core/src
parente96f63034fbc0bb2c41550ddf7b37ed5ba6b89b2 (diff)
downloadsttp-4fd5b1570c006a7ad5e022cadb9f41decf51d866.tar.gz
sttp-4fd5b1570c006a7ad5e022cadb9f41decf51d866.tar.bz2
sttp-4fd5b1570c006a7ad5e022cadb9f41decf51d866.zip
Special encoding for fragment
Diffstat (limited to 'core/src')
-rw-r--r--core/src/main/scala/com/softwaremill/sttp/Uri.scala29
-rw-r--r--core/src/test/scala/com/softwaremill/sttp/UriTests.scala4
2 files changed, 23 insertions, 10 deletions
diff --git a/core/src/main/scala/com/softwaremill/sttp/Uri.scala b/core/src/main/scala/com/softwaremill/sttp/Uri.scala
index f66793a..ce758a1 100644
--- a/core/src/main/scala/com/softwaremill/sttp/Uri.scala
+++ b/core/src/main/scala/com/softwaremill/sttp/Uri.scala
@@ -123,7 +123,7 @@ case class Uri(scheme: String,
val queryS = encodeQueryFragments(queryFragments.toList,
previousWasPlain = true,
new StringBuilder())
- val fragS = fragment.fold("")("#" + _)
+ val fragS = fragment.fold("")("#" + encodeFragment(_))
s"$schemeS://$userInfoS$hostS$portS$pathPrefixS$pathS$queryPrefixS$queryS$fragS"
}
@@ -139,19 +139,30 @@ case class Uri(scheme: String,
else
URLEncoder.encode(String.valueOf(s), "UTF-8")
- private val relaxedQueryAllowedCharacters = {
- // https://stackoverflow.com/questions/2322764/what-characters-must-be-escaped-in-an-http-query-string
- val alphanum = (('a' to 'z') ++ ('A' to 'Z') ++ ('0' to '9')).toSet
- val special = Set('/', '?', ':', '@', '-', '.', '_', '~', '!', '$', '&',
- '\'', '(', ')', '*', '+', ',', ';', '=')
- alphanum ++ special
+ private object Rfc3986 {
+ val AlphaNum: Set[Char] =
+ (('a' to 'z') ++ ('A' to 'Z') ++ ('0' to '9')).toSet
+ val Unreserved: Set[Char] = AlphaNum ++ Set('-', '.', '_', '~')
+ val SubDelims: Set[Char] =
+ Set('!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=')
+ val PChar: Set[Char] = Unreserved ++ SubDelims ++ Set(':', '@')
+ val Query: Set[Char] = PChar ++ Set('/', '?')
+ val Fragment: Set[Char] = Query
}
- private def encodeQueryRelaxed(s: String): String = {
+ // https://stackoverflow.com/questions/2322764/what-characters-must-be-escaped-in-an-http-query-string
+ private def encodeQueryRelaxed(s: String): String =
+ encode(s, Rfc3986.Query)
+
+ // https://stackoverflow.com/questions/2053132/is-a-colon-safe-for-friendly-url-use/2053640#2053640
+ private def encodeFragment(s: String): String =
+ encode(s, Rfc3986.Fragment)
+
+ private def encode(s: String, allowedCharacters: Set[Char]): String = {
val sb = new StringBuilder()
// based on https://gist.github.com/teigen/5865923
for (c <- s) {
- if (relaxedQueryAllowedCharacters(c)) sb.append(c)
+ if (allowedCharacters(c)) sb.append(c)
else {
for (b <- c.toString.getBytes("UTF-8")) {
sb.append("%")
diff --git a/core/src/test/scala/com/softwaremill/sttp/UriTests.scala b/core/src/test/scala/com/softwaremill/sttp/UriTests.scala
index 26e7936..fb55468 100644
--- a/core/src/test/scala/com/softwaremill/sttp/UriTests.scala
+++ b/core/src/test/scala/com/softwaremill/sttp/UriTests.scala
@@ -39,7 +39,9 @@ class UriTests extends FunSuite with Matchers {
Nil,
Nil,
None) ->
- "http://us%26er:pa%20ss@example.com"
+ "http://us%26er:pa%20ss@example.com",
+ Uri("http", None, "example.com", None, Nil, Nil, Some("f:g/h i")) ->
+ "http://example.com#f:g/h%20i",
)
for {