diff --git a/NAMESPACE b/NAMESPACE index 01598d8b..3bc4cdde 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -67,6 +67,7 @@ export(req_cookies_set) export(req_dry_run) export(req_error) export(req_headers) +export(req_headers_redacted) export(req_method) export(req_oauth) export(req_oauth_auth_code) diff --git a/NEWS.md b/NEWS.md index 409052fe..9a9a63c0 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,6 @@ # httr2 (development version) +* New `req_headers_redacted()` provides a user-friendlier way to set redacted headers (#561). * `resp_link_url()` now works if there are multiple `Link` headers (#587). * New `url_modify()` makes it easier to modify an existing url (#464). * New `req_url_relative()` for constructing relative urls (#449). diff --git a/R/req-headers.R b/R/req-headers.R index e9435873..3d099cc8 100644 --- a/R/req-headers.R +++ b/R/req-headers.R @@ -1,7 +1,12 @@ #' Modify request headers #' +#' @description #' `req_headers()` allows you to set the value of any header. #' +#' `req_headers_redacted()` is a variation that adds "redacted" headers, which +#' httr2 avoids printing on the console. This is good practice for +#' authentication headers to avoid accidentally leaking them in log files. +#' #' @param .req A [request]. #' @param ... <[`dynamic-dots`][rlang::dyn-dots]> Name-value pairs of headers #' and their values. @@ -46,13 +51,16 @@ #' # If you have headers in a list, use !!! #' headers <- list(HeaderOne = "one", HeaderTwo = "two") #' req |> -#' req_headers(!!!headers, HeaderThree = "three") |> -#' req_dry_run() -#' -#' # Use `.redact` to hide a header in the output -#' req |> -#' req_headers(Secret = "this-is-private", Public = "but-this-is-not", .redact = "Secret") |> +#' req_headers(!!!headers, HeaderThree = "three") |> #' req_dry_run() +#' +#' # Use `req_headers_redacted()`` to hide a header in the output +#' req_secret <- req |> +#' req_headers_redacted(Secret = "this-is-private") |> +#' req_headers(Public = "but-this-is-not") +#' +#' req_secret +#' req_secret |> req_dry_run() req_headers <- function(.req, ..., .redact = NULL) { check_request(.req) @@ -68,3 +76,12 @@ req_headers <- function(.req, ..., .redact = NULL) { .req } + +#' @export +#' @rdname req_headers +req_headers_redacted <- function(.req, ...) { + check_request(.req) + + dots <- list(...) + req_headers(.req, !!!dots, .redact = names(dots)) +} diff --git a/man/req_headers.Rd b/man/req_headers.Rd index c16d6932..c78d5cdb 100644 --- a/man/req_headers.Rd +++ b/man/req_headers.Rd @@ -2,9 +2,12 @@ % Please edit documentation in R/req-headers.R \name{req_headers} \alias{req_headers} +\alias{req_headers_redacted} \title{Modify request headers} \usage{ req_headers(.req, ..., .redact = NULL) + +req_headers_redacted(.req, ...) } \arguments{ \item{.req}{A \link{request}.} @@ -25,6 +28,10 @@ A modified HTTP \link{request}. } \description{ \code{req_headers()} allows you to set the value of any header. + +\code{req_headers_redacted()} is a variation that adds "redacted" headers, which +httr2 avoids printing on the console. This is good practice for +authentication headers to avoid accidentally leaking them in log files. } \examples{ req <- request("http://example.com") @@ -59,11 +66,14 @@ req |> # If you have headers in a list, use !!! headers <- list(HeaderOne = "one", HeaderTwo = "two") req |> - req_headers(!!!headers, HeaderThree = "three") |> - req_dry_run() - -# Use `.redact` to hide a header in the output -req |> - req_headers(Secret = "this-is-private", Public = "but-this-is-not", .redact = "Secret") |> + req_headers(!!!headers, HeaderThree = "three") |> req_dry_run() + +# Use `req_headers_redacted()`` to hide a header in the output +req_secret <- req |> + req_headers_redacted(Secret = "this-is-private") |> + req_headers(Public = "but-this-is-not") + +req_secret +req_secret |> req_dry_run() } diff --git a/tests/testthat/test-req-headers.R b/tests/testthat/test-req-headers.R index 036a6790..1b7f3883 100644 --- a/tests/testthat/test-req-headers.R +++ b/tests/testthat/test-req-headers.R @@ -30,6 +30,8 @@ test_that("can control which headers to redact", { expect_redact(req_headers(req, a = 1L, b = 2L, .redact = c("a", "b")), c("a", "b")) expect_redact(req_headers(req, a = 1L, b = 2L, .redact = "a"), "a") + expect_redact(req_headers_redacted(req, a = 1L, b = 2L), c("a", "b")) + expect_snapshot(error = TRUE, { req_headers(req, a = 1L, b = 2L, .redact = 1L) })