Skip to content

Commit

Permalink
Throw error when attempting to change body type (#530)
Browse files Browse the repository at this point in the history
Fixes #451
  • Loading branch information
hadley authored Sep 3, 2024
1 parent 0b795b6 commit 62094f2
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 5 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# httr2 (development version)

* `req_body_*()` now give informative error if you attempt to change the body type (#451).
* `resp_body_html()` and `resp_body_xml()` now work when `req_perform()` is given a path (#448).
* `req_body_file()` now works with files >64kb once more (#524).
* New `req_perform_connection()` for working with streaming data. Unlike `req_perform_stream()` which uses callbacks, `req_perform_connection()` returns a regular response object with a connection as the body. It's paired with `resp_stream_bytes()`, `resp_stream_lines()`, and `resp_stream_sse()` that allows you to stream chunks as you want them. Unlike `req_perform_stream()` it supports `req_retry()` (with @jcheng5, #519).
Expand Down
34 changes: 30 additions & 4 deletions R/req-body.R
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,12 @@ req_body_raw <- function(req, body, type = NULL) {
cli::cli_abort("{.arg body} must be a raw vector or string.")
}

req_body(req, data = body, type = "raw", content_type = type %||% "")
req_body(
req,
data = body,
type = "raw",
content_type = type %||% ""
)
}

#' @export
Expand All @@ -74,7 +79,12 @@ req_body_file <- function(req, path, type = NULL) {
}

# Need to override default content-type "application/x-www-form-urlencoded"
req_body(req, data = new_path(path), type = "raw-file", content_type = type %||% "")
req_body(
req,
data = new_path(path),
type = "raw-file",
content_type = type %||% ""
)
}

#' @export
Expand Down Expand Up @@ -102,7 +112,13 @@ req_body_json <- function(req, data,
null = null,
...
)
req_body(req, data = data, type = "json", content_type = type, params = params)
req_body(
req,
data = data,
type = "json",
content_type = type,
params = params
)
}

#' @export
Expand Down Expand Up @@ -164,7 +180,17 @@ req_body_multipart <- function(.req, ...) {

# General structure -------------------------------------------------------

req_body <- function(req, data, type, content_type, params = list()) {
req_body <- function(req, data, type, content_type, params = list(), error_call = parent.frame()) {
if (!is.null(req$body) && req$body$type != type) {
cli::cli_abort(
c(
"Can't change body type from {req$body$type} to {type}.",
i = "You must use only one type of `req_body_*()` per request."
),
call = error_call
)
}

req$body <- list(
data = data,
type = type,
Expand Down
9 changes: 9 additions & 0 deletions tests/testthat/_snaps/req-body.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,12 @@
! Unexpected content type "application/xml".
* Expecting type "application/json" or suffix "json".

# can't change body type

Code
req %>% req_body_json(list(x = 1))
Condition
Error in `req_body_json()`:
! Can't change body type from raw to json.
i You must use only one type of `req_body_*()` per request.

5 changes: 4 additions & 1 deletion tests/testthat/test-req-body.R
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ test_that("no issues with partial name matching", {
req_body_multipart(d = "some data")

expect_named(req$body$data, "d")
})


test_that("can't change body type", {
req <- request("http://example.com") %>% req_body_raw(raw(1))
expect_snapshot(req %>% req_body_json(list(x = 1)), error = TRUE)
})

0 comments on commit 62094f2

Please sign in to comment.