diff --git a/R/req-url.R b/R/req-url.R index 66cc06aa..75fd87d7 100644 --- a/R/req-url.R +++ b/R/req-url.R @@ -98,10 +98,10 @@ req_url_path_append <- function(req, ...) { check_request(req) path <- dots_to_path(...) - url <- url_parse(req$url) - url$path <- paste0(sub("/$", "", url$path), path) - - req_url(req, url_build(url)) + # Keep verbatim url-encoding of input path + input <- curl::curl_parse_url(req$url, decode = FALSE)$path + path <- paste0(sub("/$", "", input), path) + req_url(req, curl::curl_modify_url(req$url, path = I(path))) } #' Get request URL diff --git a/tests/testthat/test-url.R b/tests/testthat/test-url.R index 50129172..488df78f 100644 --- a/tests/testthat/test-url.R +++ b/tests/testthat/test-url.R @@ -133,6 +133,18 @@ test_that("only modifies specified components", { expect_equal(url_modify(url, query = list(x=1)), "http://x.com/a%2Fb/?x=1") }) +test_that("appending to path does not normalise encoding", { + req <- request("http://x.com/a%2Fb/") + expect_equal( + req_url_path_append(req, "foo/bar")$url, + "http://x.com/a%2Fb/foo/bar" + ) + expect_equal( + req_url_path_append(req, "foo%2Fbar")$url, + "http://x.com/a%2Fb/foo%2Fbar" + ) +}) + # relative url ------------------------------------------------------------ test_that("can set relative urls", {