From 96e45da5c0b3c32e03e2055eef0f45161e08d803 Mon Sep 17 00:00:00 2001 From: Josiah Parry Date: Mon, 16 Sep 2024 16:57:27 -0700 Subject: [PATCH] add validation to url_build closes https://github.com/r-lib/httr2/issues/482 --- R/url.R | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ man/url_parse.Rd | 4 ++++ 2 files changed, 52 insertions(+) diff --git a/R/url.R b/R/url.R index 8ffab225..7deef19e 100644 --- a/R/url.R +++ b/R/url.R @@ -11,6 +11,11 @@ #' * `url_parse()` returns a URL: a S3 list with class `httr2_url` #' and elements `scheme`, `hostname`, `port`, `path`, `fragment`, `query`, #' `username`, `password`. +#' +#' @details +#' `url_build()` accepts a named list. Valid element names are `scheme`, `hostname`, `port`, `path`, `fragment`, `query`, +#' `username`, `password`. +#' #' @export #' @examples #' url_parse("http://google.com/") @@ -112,6 +117,49 @@ print.httr2_url <- function(x, ...) { #' @export #' @rdname url_parse url_build <- function(url) { + + valid_url_parts <- c( + "query", + "username", + "password", + "hostname", + "port", + "authority", + "path", + "scheme", + "fragment" + ) + + + if (!rlang::is_list(url)) { + cli::cli_abort("Expected {.cls} found {obj_type_friendly(url)}") + } + + if (!rlang::is_named(url)) { + cli::cli_abort( + c( + "{.arg url} must be a named list", + i = "url elements can be any of {.val {valid_url_parts}}" + ) + ) + } + + # extract names from the url list + url_names <- rlang::names2(url) + + # identify which ones are invalid + invalid_elements <- !url_names %in% valid_url_parts + + # check that the elements are named appropriately + if (anyNA(invalid_elements)) { + cli::cli_abort( + c( + "Invalid url elements in {.arg url}", + i = "Found {.val {url_names[invalid_elements]}} but expected one of {.arg {valid_url_parts}}" + ) + ) + } + if (!is.null(url$query)) { query <- query_build(url$query) } else { diff --git a/man/url_parse.Rd b/man/url_parse.Rd index 15a8d0aa..88b2460c 100644 --- a/man/url_parse.Rd +++ b/man/url_parse.Rd @@ -26,6 +26,10 @@ and elements \code{scheme}, \code{hostname}, \code{port}, \code{path}, \code{fra the reverse, converting a list of pieces into a string URL. See \href{https://datatracker.ietf.org/doc/html/rfc3986}{RFC 3986} for the details of the parsing algorithm. } +\details{ +\code{url_build()} accepts a named list. Valid element names are \code{scheme}, \code{hostname}, \code{port}, \code{path}, \code{fragment}, \code{query}, +\code{username}, \code{password}. +} \examples{ url_parse("http://google.com/") url_parse("http://google.com:80/")