-
Notifications
You must be signed in to change notification settings - Fork 40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optimized Uri.withQuery #637
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Logic-wise makes sense to me.
UriSpec.scala already has some tests such as:
uri.withQuery(Query("param1" -> "val\"ue1")) shouldEqual Uri("http://host/path?param1=val%22ue1#fragment")
This is a good start, but perhaps it would be good to add some more test cases with Query
instances that are created with the other Query
constructors to validate that these also produce the correct results. I'm pretty convinced that this implementation will indeed behave correctly, but good to codify.
@@ -129,7 +129,8 @@ sealed abstract case class Uri(scheme: String, authority: Authority, path: Path, | |||
/** | |||
* Returns a copy of this Uri with the given query. | |||
*/ | |||
def withQuery(query: Query): Uri = copy(rawQueryString = if (query.isEmpty) None else Some(query.toString)) | |||
def withQuery(query: Query): Uri = | |||
createUnsafe(scheme, authority, path, if (query.isEmpty) None else Some(query.toString), fragment) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding a copyUnsafe
method and calling it here and also in all the other with...
methods (this assumes that the query stored inside Uri
is also already encoded).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm, thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fails to compile in scala 2.12 build
[error] /home/runner/work/pekko-http/pekko-http/http-core/src/test/scala/org/apache/pekko/http/scaladsl/model/UriSpec.scala:824:36: value addOne is not a member of scala.collection.mutable.Builder[(String, String),org.apache.pekko.http.scaladsl.model.Uri.Query]
[error] val query = Query.newBuilder.addOne("param1" -> "val\"ue1").result()
[error] ^
Error: value addOne is not a member of scala.collection.mutable.Builder[(String, String),org.apache.pekko.http.scaladsl.model.Uri.Query]
You need to avoid the addOne
function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the fast turnaround on the compile issue.
Uri.withQuery
receives aQuery
object, converts it to a string, and then calls theUri.copy
method which creates a newUri
object with the given query (TheUri
class holds the query as an un-parsed string).The
copy
method ends up inqueryString.map(new UriParser(_).parseRawQueryString())
which percent-encodes the query string.As in this flow, the query string is converted from a
Query
object, it is always percent-encoded, so the additional encoding operation is unnecessary. We can skip it by replacing the call tocopy
withcreateUnsafe
.