@@ -50,30 +50,33 @@ object UriEncode {
5050 def pchar = unreserved ++ (
5151 ':' :: '@' :: '&' :: '=' :: '+' :: '$' :: ',' :: Nil
5252 )
53- val segmentValid = (';' +: pchar).toSet
53+ val segmentValid : Set [ Char ] = (';' +: pchar).toSet
5454
55- private val validMarkers = (0 to segmentValid.max.toInt).map(i => segmentValid(i.toChar)).toArray
56- private def isValidChar (ch : Char ) = (ch < validMarkers.length) && validMarkers(ch.toInt)
55+ // There are likely more optimal ways of doing this calculation, however
56+ // it seems unlikely that long path segments are often on the hot path
57+ // of a request in such a way that they can't be cached. If that proves
58+ // not to be true, then we can revisit.
59+ private def isValidChar (b : Byte ) = {
60+ segmentValid.contains(b.toChar)
61+ }
5762
5863 def path (pathSegment : String , encoding : String = " UTF-8" ) = {
59- if (pathSegment.forall(isValidChar)) {
64+ val pathBytes = pathSegment.getBytes(encoding)
65+
66+ if (pathBytes.forall(isValidChar)) {
6067 pathSegment
61- }
62- else {
68+ } else {
6369 val sb = new StringBuilder (pathSegment.length << 1 )
6470
65- pathSegment foreach { ch =>
66- if (isValidChar(ch)) {
67- sb.append(ch)
68- }
69- else {
70- ch.toString.getBytes(encoding) foreach { b =>
71- val hi = (b >>> 4 ) & 0xf
72- val lo = b & 0xf
73- sb.append('%' )
74- .append((if (hi > 9 ) hi + '7' else hi + '0' ).toChar)
75- .append((if (lo > 9 ) lo + '7' else lo + '0' ).toChar)
76- }
71+ pathBytes.foreach { b =>
72+ if (isValidChar(b)) {
73+ sb.append(b.toChar)
74+ } else {
75+ val hi = (b >>> 4 ) & 0xf
76+ val lo = b & 0xf
77+ sb.append('%' )
78+ .append((if (hi > 9 ) hi + '7' else hi + '0' ).toChar)
79+ .append((if (lo > 9 ) lo + '7' else lo + '0' ).toChar)
7780 }
7881 }
7982
0 commit comments