diff --git a/changelog.md b/changelog.md index af91b49773b8d..ce7596d5b89c2 100644 --- a/changelog.md +++ b/changelog.md @@ -84,6 +84,8 @@ parameter and result types, not just their source-level shape. Use - `std/pegs` now correctly lexes UTF-8 bytes inside bare identifier-style terminals, so case-insensitive matching of non-ASCII terms (e.g. ``\i café``) works without single-quoting. +- `std/uri`: The `?` operator now appends query parameters to an existing query + string instead of replacing it. Fixes [#19782](https://github.com/nim-lang/Nim/issues/19782). ## Language changes diff --git a/lib/pure/uri.nim b/lib/pure/uri.nim index e57587ba47f72..c20049de12389 100644 --- a/lib/pure/uri.nim +++ b/lib/pure/uri.nim @@ -487,11 +487,18 @@ func `/`*(x: Uri, path: string): Uri = func `?`*(u: Uri, query: openArray[(string, string)]): Uri = ## Concatenates the query parameters to the specified URI object. + ## If the URI already has a query string, the new parameters are appended. runnableExamples: let foo = parseUri("https://example.com") / "foo" ? {"bar": "qux"} assert $foo == "https://example.com/foo?bar=qux" + let bar = parseUri("https://example.com/foo?existing=1") ? {"bar": "qux"} + assert $bar == "https://example.com/foo?existing=1&bar=qux" result = u - result.query = encodeQuery(query) + let newQuery = encodeQuery(query) + if newQuery.len > 0: + if result.query.len > 0: + result.query.add('&') + result.query.add(newQuery) func `$`*(u: Uri): string = ## Returns the string representation of the specified URI object. diff --git a/tests/stdlib/turi.nim b/tests/stdlib/turi.nim index 9c717c5b159a8..71aea6af14e1f 100644 --- a/tests/stdlib/turi.nim +++ b/tests/stdlib/turi.nim @@ -289,6 +289,15 @@ template main() = var foo = parseUri("http://example.com") / "foo" ? {"do": "do", "bar": ""} var foo1 = parseUri("http://example.com/foo?do=do&bar") doAssert foo == foo1 + block: # issue #19782: appends to existing query string + var foo = parseUri("http://example.com/foo?existing=1") ? {"bar": "qux"} + doAssert $foo == "http://example.com/foo?existing=1&bar=qux" + block: # issue #19782: empty params list preserves existing query + var foo = parseUri("http://example.com/foo?existing=1") ? {:} + doAssert $foo == "http://example.com/foo?existing=1" + block: # issue #19782: empty params on uri without query is a no-op + var foo = parseUri("http://example.com/foo") ? {:} + doAssert $foo == "http://example.com/foo" block: # getDataUri, dataUriBase64 doAssert getDataUri("", "text/plain") == "data:text/plain;charset=utf-8;base64,"