From 71ba2d047d003968ffdefcb9cd4fb5dac9ea745c Mon Sep 17 00:00:00 2001 From: Hadley Wickham Date: Wed, 21 Jan 2026 08:32:21 -0600 Subject: [PATCH 1/2] Switch to httr2 Fixes #2602 --- DESCRIPTION | 2 +- R/check-mac.R | 22 ++++++++-------------- R/release.R | 36 ++++++++++++------------------------ R/run-source.R | 6 ++---- inst/WORDLIST | 1 + 5 files changed, 24 insertions(+), 43 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 7db0adf59..ec2cea7ed 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -51,7 +51,7 @@ Suggests: foghorn (>= 1.4.2), gh (>= 1.3.0), gmailr (>= 1.0.1), - httr (>= 1.4.3), + httr2 (>= 1.0.0), knitr (>= 1.39), lintr (>= 3.0.0), MASS, diff --git a/R/check-mac.R b/R/check-mac.R index b4ed56d06..e73613a96 100644 --- a/R/check-mac.R +++ b/R/check-mac.R @@ -55,27 +55,21 @@ check_mac_release <- function( url <- "https://mac.r-project.org/macbuilder/v1/submit" - rlang::check_installed("httr") - body <- list(pkgfile = httr::upload_file(built_path)) + rlang::check_installed("httr2") + body <- list(pkgfile = curl::form_file(built_path)) if (length(dep_built_paths) > 0) { - uploads <- lapply(dep_built_paths, httr::upload_file) + uploads <- lapply(dep_built_paths, curl::form_file) names(uploads) <- rep("depfiles", length(uploads)) body <- append(body, uploads) } - res <- httr::POST( - url, - body = body, - headers = list( - "Content-Type" = "multipart/form-data" - ), - encode = "multipart" - ) - - httr::stop_for_status(res, task = "Uploading package") + req <- httr2::request(url) |> + httr2::req_body_multipart(!!!body) |> + httr2::req_headers(Accept = "application/json") + resp <- httr2::req_perform(req) - response_url <- httr::content(res)$url + response_url <- httr2::resp_body_json(resp)$url if (!quiet) { time <- strftime(Sys.time() + 10 * 60, "%I:%M %p") diff --git a/R/release.R b/R/release.R index 65c6c8c11..cb8e0eb3e 100644 --- a/R/release.R +++ b/R/release.R @@ -297,35 +297,20 @@ upload_cran <- function(pkg, built_path, call = parent.frame()) { # Initial upload --------- cli::cli_inform(c(i = "Uploading package & comments")) - rlang::check_installed("httr") + rlang::check_installed("httr2") body <- list( pkg_id = "", name = maint$name, email = maint$email, - uploaded_file = httr::upload_file(built_path, "application/x-gzip"), + uploaded_file = curl::form_file(built_path, "application/x-gzip"), comment = comments, upload = "Upload package" ) - r <- httr::POST(cran_submission_url, body = body) - - # If a 404 likely CRAN is closed for maintenance, try to get the message - if (httr::status_code(r) == 404) { - msg <- "" - try({ - r2 <- httr::GET(sub("index2", "index", cran_submission_url)) - msg <- extract_cran_msg(httr::content(r2, "text")) - }) - cli::cli_abort( - c( - "*" = "Submission failed", - "x" = msg - ), - call = call - ) - } + req <- httr2::request(cran_submission_url) |> + httr2::req_body_multipart(!!!body) - httr::stop_for_status(r) - new_url <- httr::parse_url(r$url) + httr2::resp_check_status(resp) + new_url <- httr2::url_parse(httr2::resp_url(resp)) # Confirmation ----------- cli::cli_inform(c(i = "Confirming submission")) @@ -336,9 +321,12 @@ upload_cran <- function(pkg, built_path, call = parent.frame()) { policy_check = "1/", submit = "Submit package" ) - r <- httr::POST(cran_submission_url, body = body) - httr::stop_for_status(r) - new_url <- httr::parse_url(r$url) + req <- do.call( + httr2::req_body_multipart, + c(list(httr2::request(cran_submission_url)), body) + ) + resp <- httr2::req_perform(req) + new_url <- httr2::url_parse(httr2::resp_url(resp)) if (new_url$query$submit == "1") { cli::cli_inform(c( "v" = "Package submission successful", diff --git a/R/run-source.R b/R/run-source.R index 262a79804..e46c28170 100644 --- a/R/run-source.R +++ b/R/run-source.R @@ -31,14 +31,12 @@ source_url <- function(url, ..., sha1 = NULL) { stopifnot(is.character(url), length(url) == 1) rlang::check_installed("digest") - rlang::check_installed("httr") + rlang::check_installed("httr2") temp_file <- file_temp() on.exit(file_delete(temp_file), add = TRUE) - request <- httr::GET(url) - httr::stop_for_status(request) - writeBin(httr::content(request, type = "raw"), temp_file) + httr2::req_perform(httr2::request(url), path = temp_file) check_sha1(temp_file, sha1) diff --git a/inst/WORDLIST b/inst/WORDLIST index 365d8944e..b37bb45f4 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -96,6 +96,7 @@ hadley http https httr +httr2 hunspell importFrom initialising From d87d654df8baa6ed84874f21d08ba0309e578334 Mon Sep 17 00:00:00 2001 From: Hadley Wickham Date: Thu, 12 Feb 2026 15:53:50 -0600 Subject: [PATCH 2/2] Polishing --- R/release.R | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/R/release.R b/R/release.R index 92fce6530..1c5e07c39 100644 --- a/R/release.R +++ b/R/release.R @@ -289,14 +289,17 @@ extract_cran_msg <- function(msg) { } upload_cran <- function(pkg, built_path, call = parent.frame()) { + check_installed("httr2") + pkg <- as.package(pkg) maint <- maintainer(pkg) comments <- cran_comments(pkg, call = call) # Initial upload --------- cli::cli_inform(c(i = "Uploading package & comments")) - check_installed("httr2") - body <- list( + req <- httr2::request(cran_submission_url) + req <- httr2::req_body_multipart( + req, pkg_id = "", name = maint$name, email = maint$email, @@ -304,25 +307,22 @@ upload_cran <- function(pkg, built_path, call = parent.frame()) { comment = comments, upload = "Upload package" ) - req <- httr2::request(cran_submission_url) |> - httr2::req_body_multipart(!!!body) - - httr2::resp_check_status(resp) + resp <- httr2::req_perform(req) new_url <- httr2::url_parse(httr2::resp_url(resp)) # Confirmation ----------- cli::cli_inform(c(i = "Confirming submission")) - body <- list( + + req <- httr2::request(cran_submission_url) + req <- httr2::req_body_multipart( + req, pkg_id = new_url$query$pkg_id, name = maint$name, email = maint$email, policy_check = "1/", submit = "Submit package" ) - req <- do.call( - httr2::req_body_multipart, - c(list(httr2::request(cran_submission_url)), body) - ) + resp <- httr2::req_perform(req) new_url <- httr2::url_parse(httr2::resp_url(resp)) if (new_url$query$submit == "1") {