Skip to content

Commit

Permalink
Merge commit '828ccbd6b1cf04df2d7b62aa0805e6d97c704115'
Browse files Browse the repository at this point in the history
#Conflicts:
#	NEWS.md
#	R/curl.R
  • Loading branch information
mgirlich committed Aug 7, 2023
2 parents bfbc760 + 828ccbd commit 9975a1e
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 42 deletions.
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
* `curl_translate()` gains the argument `simplify_headers` that removes some
common but unimportant headers e.g. `Sec-Fetch-Dest` or `sec-ch-ua-mobile`
(@mgirlich, #256).

* `curl_translate()` now parses the query components of the url (@mgirlich, #259).

* `curl_translate()` now works with multiline commands from the clipboard
(@mgirlich, #254).
Expand Down
83 changes: 57 additions & 26 deletions R/curl.R
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ curl_translate <- function(cmd, simplify_headers = TRUE) {
}
data <- curl_normalize(cmd)

out <- glue('request("{data$url}")')
add_line <- function(x, y) {
if (is.null(y)) {
return(x)
Expand All @@ -53,32 +52,38 @@ curl_translate <- function(cmd, simplify_headers = TRUE) {
paste0(x, ' %>% \n ', gsub("\n", "\n ", y))
}

if (!is.null(data$method)) {
out <- add_line(out, glue('req_method("{data$method}")'))
}
url_pieces <- httr2::url_parse(data$url)
query <- url_pieces$query
url_pieces$query <- NULL
url <- url_build(url_pieces)

steps <- glue('request("{url}")')
steps <- add_curl_step(steps, "req_method", main_args = data$method)

steps <- add_curl_step(steps, "req_url_query", dots = query)

# Content type set with data
type <- data$headers$`Content-Type`
data$headers$`Content-Type` <- NULL

headers_code <- curl_prepare_headers(data$headers, simplify_headers)
out <- add_line(out, headers_code)
headers <- curl_simplify_headers(data$headers, simplify_headers)
steps <- add_curl_step(steps, "req_headers", dots = headers)

if (!identical(data$data, "")) {
type <- encodeString(type %||% "application/x-www-form-urlencoded", quote = '"')
body <- encodeString(data$data, quote = '"')
out <- add_line(out, glue("req_body_raw({body}, {type})"))
type <- type %||% "application/x-www-form-urlencoded"
body <- data$data
steps <- add_curl_step(steps, "req_body_raw", main_args = c(body, type))
}

if (!is.null(data$auth)) {
out <- add_line(out, glue('req_auth_basic("{data$auth[[1]]}", "{data$auth[[2]]}")'))
}
steps <- add_curl_step(steps, "req_auth_basic", main_args = unname(data$auth))

perform_args <- list()
if (data$verbose) {
out <- add_line(out, "req_perform(verbosity = 1)")
} else {
out <- add_line(out, "req_perform()")
perform_args$verbosity <- 1
}
steps <- add_curl_step(steps, "req_perform", main_args = perform_args, keep_if_empty = TRUE)

out <- paste0(steps, collapse = " %>% \n ")
out <- paste0(out, "\n")

if (clip) {
Expand Down Expand Up @@ -168,7 +173,7 @@ curl_normalize <- function(cmd) {
)
}

curl_prepare_headers <- function(headers, simplify_headers) {
curl_simplify_headers <- function(headers, simplify_headers) {
if (simplify_headers) {
header_names <- tolower(names(headers))
to_drop <- startsWith(header_names, "sec-fetch") |
Expand All @@ -177,15 +182,7 @@ curl_prepare_headers <- function(headers, simplify_headers) {
headers <- headers[!to_drop]
}

if (length(headers) == 0) {
return(NULL)
}

names <- quote_name(names(headers))
values <- encodeString(unlist(headers), quote = '"')
args <- paste0(" ", names, " = ", values, ",\n", collapse = "")

paste0("req_headers(\n", args, ")")
headers
}

curl_data <- function(x, binary = FALSE, raw = FALSE) {
Expand Down Expand Up @@ -256,8 +253,42 @@ curl_args <- function(cmd) {
# Helpers -----------------------------------------------------------------

is_syntactic <- function(x) {
x == make.names(x)
x == "" | x == make.names(x)
}
quote_name <- function(x) {
ifelse(is_syntactic(x), x, encodeString(x, quote = "`"))
}

add_curl_step <- function(steps,
f,
...,
main_args = NULL,
dots = NULL,
keep_if_empty = FALSE) {
check_dots_empty0(...)
args <- c(main_args, dots)

if (is_empty(args) && !keep_if_empty) {
return(steps)
}

names <- quote_name(names2(args))
string <- vapply(args, is.character, logical(1L))
values <- unlist(args)
values <- ifelse(string, encodeString(values, quote = '"'), values)

args_named <- ifelse(
names == "",
paste0(values),
paste0(names, " = ", values)
)
if (is_empty(dots)) {
args_string <- paste0(args_named, collapse = ", ")
new_step <- paste0(f, "(", args_string, ")")
} else {
args_string <- paste0(" ", args_named, ",\n", collapse = "")
new_step <- paste0(f, "(\n", args_string, " )")
}

c(steps, new_step)
}
40 changes: 26 additions & 14 deletions tests/testthat/_snaps/curl.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,23 @@
# common headers can be removed

Code
cat(curl_prepare_headers(headers, simplify_headers = TRUE))
print(curl_simplify_headers(headers, simplify_headers = TRUE))
Message
<httr2_headers>
Output
req_headers(
Accept = "application/vnd.api+json",
`user-agent` = "agent",
)
Accept: application/vnd.api+json
user-agent: agent
Code
cat(curl_prepare_headers(headers, simplify_headers = FALSE))
print(curl_simplify_headers(headers, simplify_headers = FALSE))
Message
<httr2_headers>
Output
req_headers(
`Sec-Fetch-Dest` = "empty",
`Sec-Fetch-Mode` = "cors",
`sec-ch-ua-mobile` = "?0",
Accept = "application/vnd.api+json",
referer = "ref",
`user-agent` = "agent",
)
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
sec-ch-ua-mobile: ?0
Accept: application/vnd.api+json
referer: ref
user-agent: agent

# can translate to httr calls

Expand Down Expand Up @@ -68,6 +68,18 @@
request("http://x.com") %>%
req_perform(verbosity = 1)

# can translate query

Code
curl_translate("curl http://x.com?string=abcde&b=2")
Output
request("http://x.com") %>%
req_url_query(
string = "abcde",
b = "2",
) %>%
req_perform()

# can translate data

Code
Expand Down
10 changes: 8 additions & 2 deletions tests/testthat/test-curl.R
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ test_that("common headers can be removed", {
cmd <- paste("curl http://x.com -A agent -e ref", sec_fetch_headers, sec_ch_ua_headers, other_headers)
headers <- curl_normalize(cmd)$headers
expect_snapshot({
cat(curl_prepare_headers(headers, simplify_headers = TRUE))
cat(curl_prepare_headers(headers, simplify_headers = FALSE))
print(curl_simplify_headers(headers, simplify_headers = TRUE))
print(curl_simplify_headers(headers, simplify_headers = FALSE))
})
})

Expand Down Expand Up @@ -108,6 +108,12 @@ test_that("can translate to httr calls", {
})
})

test_that("can translate query", {
expect_snapshot({
curl_translate("curl http://x.com?string=abcde&b=2")
})
})

test_that("can translate data", {
expect_snapshot({
curl_translate("curl http://example.com --data abcdef")
Expand Down

0 comments on commit 9975a1e

Please sign in to comment.