Skip to content

Commit f00fa2a

Browse files
authored
Allow supplying a raw vector as ncurl() data (#159)
* Allow supplying a raw vector as ncurl() data * Should copy the data for async ncurl cases
1 parent 0a749f8 commit f00fa2a

File tree

7 files changed

+39
-23
lines changed

7 files changed

+39
-23
lines changed

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#### Updates
44

5+
* `ncurl()` and variants now accept request data supplied as a raw vector (thanks @thomasp85, #158).
56
* `cv_reset()` now correctly resets the flag in the case a flag event has already been registered with `pipe_notify()`.
67
* The previous `listen()` and `dial()` argument `error`, removed in v1.6.0, is now defunct.
78
* The previous `serial_config()` argument `vec`, unutilised since v1.6.0, is removed.

R/ncurl.R

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
1717
#' request headers, for example: \cr
1818
#' `c(Authorization = "Bearer APIKEY", "Content-Type" = "text/plain")` \cr
1919
#' A non-character or non-named vector will be ignored.
20-
#' @param data (optional) character string request data to be submitted. If a
21-
#' vector, only the first element is taken, and non-character objects are
22-
#' ignored.
20+
#' @param data (optional) request data to be submitted. Must be a character
21+
#' string or raw vector, and other objects are ignored. If a character vector,
22+
#' only the first element is taken. When supplying binary data, the
23+
#' appropriate 'Content-Type' header should be set to specify the binary
24+
#' format.
2325
#' @param response (optional) a character vector specifying the response headers
2426
#' to return e.g. `c("date", "server")`. These are case-insensitive and
2527
#' will return NULL if not present. A non-character vector will be ignored.

man/ncurl.Rd

Lines changed: 5 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/ncurl_aio.Rd

Lines changed: 5 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/ncurl_session.Rd

Lines changed: 5 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/ncurl.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,16 @@ static SEXP mk_error_ncurlaio(const int xc) {
5252

5353
static nano_buf nano_char_buf(const SEXP data) {
5454

55-
nano_buf buf;
56-
const char *s = NANO_STRING(data);
57-
NANO_INIT(&buf, (unsigned char *) s, strlen(s));
55+
nano_buf buf = {0};
56+
switch (TYPEOF(data)) {
57+
case STRSXP: ;
58+
const char *s = NANO_STRING(data);
59+
NANO_INIT(&buf, (unsigned char *) s, strlen(s));
60+
break;
61+
case RAWSXP:
62+
NANO_INIT(&buf, NANO_DATAPTR(data), XLENGTH(data));
63+
break;
64+
}
5865

5966
return buf;
6067

@@ -175,9 +182,9 @@ SEXP rnng_ncurl(SEXP http, SEXP convert, SEXP follow, SEXP method, SEXP headers,
175182
}
176183
}
177184
}
178-
if (data != R_NilValue && TYPEOF(data) == STRSXP) {
185+
if (data != R_NilValue) {
179186
nano_buf enc = nano_char_buf(data);
180-
if ((xc = nng_http_req_set_data(req, enc.buf, enc.cur)))
187+
if (enc.cur && (xc = nng_http_req_set_data(req, enc.buf, enc.cur)))
181188
goto fail;
182189
}
183190

@@ -345,9 +352,9 @@ SEXP rnng_ncurl_aio(SEXP http, SEXP convert, SEXP method, SEXP headers, SEXP dat
345352
}
346353
}
347354
}
348-
if (data != R_NilValue && TYPEOF(data) == STRSXP) {
355+
if (data != R_NilValue) {
349356
nano_buf enc = nano_char_buf(data);
350-
if ((xc = nng_http_req_set_data(handle->req, enc.buf, enc.cur)))
357+
if (enc.cur && (xc = nng_http_req_copy_data(handle->req, enc.buf, enc.cur)))
351358
goto fail;
352359
}
353360

@@ -550,9 +557,9 @@ SEXP rnng_ncurl_session(SEXP http, SEXP convert, SEXP method, SEXP headers, SEXP
550557
}
551558
}
552559
}
553-
if (data != R_NilValue && TYPEOF(data) == STRSXP) {
560+
if (data != R_NilValue) {
554561
nano_buf enc = nano_char_buf(data);
555-
if ((xc = nng_http_req_set_data(handle->req, enc.buf, enc.cur)))
562+
if (enc.cur && (xc = nng_http_req_copy_data(handle->req, enc.buf, enc.cur)))
556563
goto fail;
557564
}
558565

tests/tests.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -430,15 +430,15 @@ test_error(socket(listen = "test"), "argument")
430430
test_type("list", ncurl("http://www.cam.ac.uk/"))
431431
test_type("list", ncurl("http://www.cam.ac.uk/", follow = FALSE, response = "date"))
432432
test_type("list", ncurl("http://www.cam.ac.uk/", follow = TRUE))
433-
test_type("list", ncurl("http://postman-echo.com/post", convert = FALSE, method = "POST", headers = c(`Content-Type` = "text/plain"), data = "test", response = c("Date", "Server"), timeout = 3000))
433+
test_type("list", ncurl("https://postman-echo.com/post", convert = FALSE, method = "POST", headers = c(`Content-Type` = "application/octet-stream"), data = as.raw(1L), response = c("Date", "Server"), timeout = 3000))
434434
test_class("errorValue", ncurl("http")$data)
435435
test_class("recvAio", haio <- ncurl_aio("http://example.com/"))
436436
test_true(is_aio(haio))
437437
test_type("integer", call_aio(haio)$status)
438438
test_class("ncurlAio", haio <- ncurl_aio("https://example.com/", convert = FALSE, response = "server"))
439439
test_notnull(haio$status)
440440
if (call_aio(haio)$status == 200L) test_notnull(haio$headers)
441-
test_class("ncurlAio", put1 <- ncurl_aio("http://postman-echo.com/put", method = "PUT", headers = c(Authorization = "Bearer token"), data = "test", response = c("Date", "server"), timeout = 3000L))
441+
test_class("ncurlAio", put1 <- ncurl_aio("https://postman-echo.com/put", method = "PUT", headers = c(`Content-Type` = "text/plain", Authorization = "Bearer token"), data = "test", response = c("Date", "server"), timeout = 3000L))
442442
test_print(put1)
443443
test_type("integer", call_aio_(put1)$status)
444444
if (put1$status == 200L) test_notnull(put1$headers)

0 commit comments

Comments
 (0)