-
Notifications
You must be signed in to change notification settings - Fork 87
Expand file tree
/
Copy pathreq-url.R
More file actions
130 lines (120 loc) · 3.53 KB
/
Copy pathreq-url.R
File metadata and controls
130 lines (120 loc) · 3.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#' Modify request URL
#'
#' @description
#' * `req_url()` replaces the entire URL.
#' * `req_url_relative()` navigates to a relative URL.
#' * `req_url_query()` modifies individual query components.
#' * `req_url_path()` modifies just the path.
#' * `req_url_path_append()` adds to the path.
#'
#' @seealso
#' * To modify a URL without creating a request, see [url_modify()] and
#' friends.
#' * To use a template like `GET /user/{user}`, see [req_template()].
#' @inheritParams req_perform
#' @param url A new URL; either an absolute URL for `req_url()` or a
#' relative URL for `req_url_relative()`.
#' @param ... For `req_url_query()`: <[`dynamic-dots`][rlang::dyn-dots]>
#' Name-value pairs that define query parameters. Each value must be either
#' an atomic vector or `NULL` (which removes the corresponding parameters).
#' If you want to opt out of escaping, wrap strings in `I()`.
#'
#' For `req_url_path()` and `req_url_path_append()`: A sequence of path
#' components that will be combined with `/`.
#' @returns A modified HTTP [request].
#' @export
#' @examples
#' # Change complete url
#' req <- request("http://example.com")
#' req |> req_url("http://google.com")
#'
#' # Use a relative url
#' req <- request("http://example.com/a/b/c")
#' req |> req_url_relative("..")
#' req |> req_url_relative("/d/e/f")
#'
#' # Change url components
#' req |>
#' req_url_path_append("a") |>
#' req_url_path_append("b") |>
#' req_url_path_append("search.html") |>
#' req_url_query(q = "the cool ice")
#'
#' # Modify individual query parameters
#' req <- request("http://example.com?a=1&b=2")
#' req |> req_url_query(a = 10)
#' req |> req_url_query(a = NULL)
#' req |> req_url_query(c = 3)
#'
#' # Use .multi to control what happens with vector parameters:
#' req |> req_url_query(id = 100:105, .multi = "comma")
#' req |> req_url_query(id = 100:105, .multi = "explode")
#'
#' # If you have query parameters in a list, use !!!
#' params <- list(a = "1", b = "2")
#' req |>
#' req_url_query(!!!params, c = "3")
req_url <- function(req, url) {
check_request(req)
check_string(url)
req$url <- url
req
}
#' @export
#' @rdname req_url
req_url_relative <- function(req, url) {
check_request(req)
req_url(req, url_modify_relative(req$url, url))
}
#' @export
#' @rdname req_url
#' @inheritParams url_modify_query
req_url_query <- function(
.req,
...,
.multi = c("error", "comma", "pipe", "explode"),
.space = c("percent", "form")
) {
check_request(.req)
url <- url_modify_query(.req$url, ..., .multi = .multi, .space = .space)
req_url(.req, url)
}
#' @export
#' @rdname req_url
req_url_path <- function(req, ...) {
check_request(req)
path <- dots_to_path(...)
req_url(req, url_modify(req$url, path = path))
}
#' @export
#' @rdname req_url
req_url_path_append <- function(req, ...) {
check_request(req)
path <- dots_to_path(...)
# Keep verbatim url-encoding of input path
input <- curl::curl_parse_url(req$url, decode = FALSE)$path
path <- paste0(sub("/$", "", input), path)
req_url(req, curl::curl_modify_url(req$url, path = I(path)))
}
#' Get request URL
#'
#' Retrieve the URL from a request.
#'
#' @inheritParams req_perform
#' @returns A character string.
#' @export
#' @examples
#' request("https://httpbin.org") |>
#' req_url_path("/get") |>
#' req_url_query(hello = "world") |>
#' req_get_url()
req_get_url <- function(req) {
check_request(req)
req$url
}
dots_to_path <- function(...) {
path <- paste(c(...), collapse = "/")
# Ensure we don't add duplicate /s
# NB: also keeps "" unchanged.
sub("^([^/])", "/\\1", path)
}