Skip to content

Commit 0775c2a

Browse files
committed
update ncurl
1 parent 3f9b045 commit 0775c2a

File tree

14 files changed

+135
-92
lines changed

14 files changed

+135
-92
lines changed

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#### New Features
44

55
* New `stream()` interface exposes low-level byte stream functionality in the NNG library, intended for communicating with non-NNG endpoints, including but not limited to websocket servers.
6+
* `ncurl()` adds explicit arguments supporting HTTP methods other than GET, including for setting the 'Authorization' header.
67

78
#### Updates
89

R/sendrecv.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
#' pub <- socket("pub", dial = "inproc://nanonext")
4141
#'
4242
#' send(pub, data.frame(a = 1, b = 2))
43-
#' send(pub, c(10.1, 20.2, 30.3), mode = "raw")
43+
#' send(pub, c(10.1, 20.2, 30.3), mode = "raw", block = 100)
4444
#'
4545
#' close(pub)
4646
#'
@@ -190,7 +190,7 @@ send.nanoStream <- function(con,
190190
#' recv(s2, keep.raw = FALSE)
191191
#'
192192
#' send(s1, c(1.1, 2.2, 3.3), mode = "raw")
193-
#' res <- recv(s2, mode = "double")
193+
#' res <- recv(s2, mode = "double", block = 100)
194194
#' res
195195
#' send(s1, "example message", mode = "raw", echo = FALSE)
196196
#' recv(s2, mode = "character", keep.raw = FALSE)

R/stream.R

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828
#' TLS is automatically configured for dialing a secure websocket address
2929
#' starting 'wss://' (where the NNG library has been built with TLS support).
3030
#'
31+
#' @examples
32+
#' # will succeed only if there is an open connection at the address:
33+
#' s <- stream(dial = "tcp://127.0.0.1:5555")
34+
#'
3135
#' @export
3236
#'
3337
stream <- function(dial = NULL, listen = NULL, textframes = FALSE) {
@@ -70,8 +74,11 @@ stream <- function(dial = NULL, listen = NULL, textframes = FALSE) {
7074
#'
7175
#' nano cURL - a minimalist http(s) client.
7276
#'
73-
#' @param http the URL address.
74-
#' @param ... (optional) additional arguments, see 'methods' section below.
77+
#' @param url the URL address.
78+
#' @param method (optional) the HTTP method.
79+
#' @param ctype (optional) the 'Content-type' header.
80+
#' @param auth (optional) the 'Authorization' header.
81+
#' @param data (optional) the request data to be submitted.
7582
#'
7683
#' @return Named list of 2 elements:
7784
#' \itemize{
@@ -82,17 +89,6 @@ stream <- function(dial = NULL, listen = NULL, textframes = FALSE) {
8289
#' as html, json, xml etc. if required.}
8390
#' }
8491
#'
85-
#' @section Methods:
86-
#'
87-
#' Additional arguments may be passed in using '...' for HTTP methods other
88-
#' than GET.
89-
#' \itemize{
90-
#' \item{Parsed as follows: [method], [content-type], [data]}
91-
#' \item{Example: "POST", "text/plain", "hello world"}
92-
#' \item{All 3 arguments must be supplied, and will be ignored otherwise, as
93-
#' will extra arguments}
94-
#' }
95-
#'
9692
#' @section Redirects:
9793
#'
9894
#' In interactive sessions: will prompt upon receiving a redirect location
@@ -107,17 +103,15 @@ stream <- function(dial = NULL, listen = NULL, textframes = FALSE) {
107103
#'
108104
#' @examples
109105
#' ncurl("http://httpbin.org/get")
110-
#' ncurl("http://httpbin.org/post", "POST", "text/plain", "hello world")
106+
#' ncurl("http://httpbin.org/put", "PUT", "text/plain", "Bearer APIKEY", "hello world")
107+
#' ncurl("http://httpbin.org/post", "POST", "application/json", data = '{"key": "value"}')
111108
#'
112109
#' @export
113110
#'
114-
ncurl <- function(http, ...) {
111+
ncurl <- function(url, method = NULL, ctype = NULL, auth = NULL, data = NULL) {
115112

116-
dots <- list(...)
117-
args <- if (length(dots) >= 3L) {
118-
list(dots[[1L]], dots[[2L]], writeBin(object = dots[[3L]], con = raw()))
119-
}
120-
res <- .Call(rnng_ncurl, http, args)
113+
data <- if (!missing(data)) writeBin(object = data, con = raw())
114+
res <- .Call(rnng_ncurl, url, method, ctype, auth, data)
121115
missing(res) && return(invisible())
122116
if (is.integer(res)) {
123117
logerror(res)

R/utils.R

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@ is_error_value <- function(x) inherits(x, "errorValue")
108108
logging <- function(level) {
109109

110110
cache <- switch(tolower(Sys.getenv("NANONEXT_LOG")),
111-
info = 1L,
112-
0L)
111+
info = TRUE,
112+
FALSE)
113113

114114
logging <- function(level = c("keep", "check", "error", "info")) {
115115

@@ -118,10 +118,10 @@ logging <- function(level) {
118118
original <- cache
119119
cache <<- switch(level,
120120
check = switch(tolower(Sys.getenv("NANONEXT_LOG")),
121-
info = 1L,
122-
0L),
123-
error = 0L,
124-
info = 1L,
121+
info = TRUE,
122+
FALSE),
123+
error = FALSE,
124+
info = TRUE,
125125
keep = original)
126126
if (cache != original) cat(sprintf("%s [ %s ] %s: %s\n",
127127
format.POSIXct(Sys.time()), "log level", "set to",

README.Rmd

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -404,15 +404,24 @@ Above it can be seen that the final value resolves into a timeout, which is an i
404404

405405
### ncurl: Minimalist http Client
406406

407-
`ncurl()` is a minimalistic http(s) client. In normal use, it takes only one argument, the URL. It can follow redirects.
407+
`ncurl()` is a minimalist http(s) client. In normal use, it takes only one argument, the URL. It can follow redirects.
408408

409409
```{r ncurl}
410410
411411
ncurl("http://httpbin.org/headers")
412412
413413
```
414414

415-
For advanced use, supports additional HTTP methods such as POST or PUT. In this respect, it may be used as a performant and lightweight method for making requests to REST APIs.
415+
For advanced use, supports additional HTTP methods such as POST or PUT.
416+
417+
```{r ncurladv}
418+
419+
res <- ncurl("http://httpbin.org/post", "POST", "application/json", "Bearer APIKEY", '{"key": "value"}')
420+
res$data
421+
422+
```
423+
424+
In this respect, it may be used as a performant and lightweight method for making requests to REST APIs.
416425

417426
[&laquo; Back to ToC](#table-of-contents)
418427

@@ -424,12 +433,13 @@ For advanced use, supports additional HTTP methods such as POST or PUT. In this
424433
425434
s <- stream(dial = "wss://socketsbay.com/wss/v2/2/demo/", textframes = TRUE)
426435
s
436+
s |> send("hello world")
427437
428438
```
429439

430-
The stream interface is especially useful for communicating with websocket servers. Where TLS is enabled in the NNG library, connecting to secure websockets is configured automatically. Here, the argument `textframes = TRUE` can be specified where the websocket server uses text rather than binary frames.
440+
The stream interface can be used to communicate with websocket servers. Where TLS is enabled in the NNG library, connecting to secure websockets is configured automatically. Here, the argument `textframes = TRUE` can be specified where the websocket server uses text rather than binary frames.
431441

432-
The same API as found in the rest of the package is available: synchronous `send`/`recv`, as well as their asynchronous counterparts `send_aio`/`recv_aio`. This affords an extraordinary amount of flexibility in ingesting and processing streaming data.
442+
The same API for Sockets can equally be used on Streams: `send()` and `recv()`, as well as their asynchronous counterparts `send_aio()` and `recv_aio()`. This affords a great deal of flexibility in ingesting and processing streaming data.
433443

434444
[&laquo; Back to ToC](#table-of-contents)
435445

README.md

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ aio
370370
#> < recvAio >
371371
#> - $data for message data
372372
aio$data |> str()
373-
#> num [1:100000000] -0.0012 -1.2404 1.1994 1.2642 -0.2507 ...
373+
#> num [1:100000000] -0.736 -1.684 0.223 0.326 1.103 ...
374374
```
375375

376376
As `call_aio()` is blocking and will wait for completion, an alternative
@@ -405,37 +405,37 @@ an environment variable `NANONEXT_LOG`.
405405

406406
``` r
407407
logging(level = "info")
408-
#> 2022-03-27 15:31:07 [ log level ] set to: info
408+
#> 2022-03-29 00:05:47 [ log level ] set to: info
409409

410410
pub <- socket("pub", listen = "inproc://nanobroadcast")
411-
#> 2022-03-27 15:31:07 [ sock open ] id: 9 | protocol: pub
412-
#> 2022-03-27 15:31:07 [ list start ] sock: 9 | url: inproc://nanobroadcast
411+
#> 2022-03-29 00:05:47 [ sock open ] id: 9 | protocol: pub
412+
#> 2022-03-29 00:05:47 [ list start ] sock: 9 | url: inproc://nanobroadcast
413413
sub <- socket("sub", dial = "inproc://nanobroadcast")
414-
#> 2022-03-27 15:31:07 [ sock open ] id: 10 | protocol: sub
415-
#> 2022-03-27 15:31:07 [ dial start ] sock: 10 | url: inproc://nanobroadcast
414+
#> 2022-03-29 00:05:47 [ sock open ] id: 10 | protocol: sub
415+
#> 2022-03-29 00:05:47 [ dial start ] sock: 10 | url: inproc://nanobroadcast
416416

417417
sub |> subscribe(topic = "examples")
418-
#> 2022-03-27 15:31:07 [ subscribe ] sock: 10 | topic: examples
418+
#> 2022-03-29 00:05:47 [ subscribe ] sock: 10 | topic: examples
419419
pub |> send(c("examples", "this is an example"), mode = "raw", echo = FALSE)
420420
sub |> recv(mode = "character", keep.raw = FALSE)
421421
#> [1] "examples" "this is an example"
422422

423423
pub |> send(c("other", "this other topic will not be received"), mode = "raw", echo = FALSE)
424424
sub |> recv(mode = "character", keep.raw = FALSE)
425-
#> 2022-03-27 15:31:07 [ 8 ] Try again
425+
#> 2022-03-29 00:05:47 [ 8 ] Try again
426426

427427
# specify NULL to subscribe to ALL topics
428428
sub |> subscribe(topic = NULL)
429-
#> 2022-03-27 15:31:07 [ subscribe ] sock: 10 | topic: ALL
429+
#> 2022-03-29 00:05:47 [ subscribe ] sock: 10 | topic: ALL
430430
pub |> send(c("newTopic", "this is a new topic"), mode = "raw", echo = FALSE)
431431
sub |> recv("character", keep.raw = FALSE)
432432
#> [1] "newTopic" "this is a new topic"
433433

434434
sub |> unsubscribe(topic = NULL)
435-
#> 2022-03-27 15:31:07 [ unsubscribe ] sock: 10 | topic: ALL
435+
#> 2022-03-29 00:05:47 [ unsubscribe ] sock: 10 | topic: ALL
436436
pub |> send(c("newTopic", "this topic will now not be received"), mode = "raw", echo = FALSE)
437437
sub |> recv("character", keep.raw = FALSE)
438-
#> 2022-03-27 15:31:07 [ 8 ] Try again
438+
#> 2022-03-29 00:05:47 [ 8 ] Try again
439439

440440
# however the topics explicitly subscribed to are still received
441441
pub |> send(c("examples", "this example will still be received"), mode = "raw", echo = FALSE)
@@ -444,7 +444,7 @@ sub |> recv(mode = "character", keep.raw = FALSE)
444444

445445
# set logging level back to the default of errors only
446446
logging(level = "error")
447-
#> 2022-03-27 15:31:07 [ log level ] set to: error
447+
#> 2022-03-29 00:05:47 [ log level ] set to: error
448448

449449
close(pub)
450450
close(sub)
@@ -495,7 +495,7 @@ aio2$data
495495
# after the survey expires, the second resolves into a timeout error
496496
Sys.sleep(0.5)
497497
aio2$data
498-
#> 2022-03-27 15:31:07 [ 5 ] Timed out
498+
#> 2022-03-29 00:05:48 [ 5 ] Timed out
499499
#> 'errorValue' int 5
500500

501501
close(sur)
@@ -512,7 +512,7 @@ integer message values.
512512

513513
### ncurl: Minimalist http Client
514514

515-
`ncurl()` is a minimalistic http(s) client. In normal use, it takes only
515+
`ncurl()` is a minimalist http(s) client. In normal use, it takes only
516516
one argument, the URL. It can follow redirects.
517517

518518
``` r
@@ -521,14 +521,21 @@ ncurl("http://httpbin.org/headers")
521521
#> [1] 7b 0a 20 20 22 68 65 61 64 65 72 73 22 3a 20 7b 0a 20 20 20 20 22 48 6f 73
522522
#> [26] 74 22 3a 20 22 68 74 74 70 62 69 6e 2e 6f 72 67 22 2c 20 0a 20 20 20 20 22
523523
#> [51] 58 2d 41 6d 7a 6e 2d 54 72 61 63 65 2d 49 64 22 3a 20 22 52 6f 6f 74 3d 31
524-
#> [76] 2d 36 32 34 30 37 35 32 63 2d 30 63 61 34 34 63 64 31 30 33 64 62 31 61 61
525-
#> [101] 38 30 66 32 31 62 62 62 38 22 0a 20 20 7d 0a 7d 0a
524+
#> [76] 2d 36 32 34 32 33 66 34 63 2d 35 31 38 62 62 65 38 66 34 31 65 31 37 37 39
525+
#> [101] 63 34 32 34 61 35 61 62 33 22 0a 20 20 7d 0a 7d 0a
526526
#>
527527
#> $data
528-
#> [1] "{\n \"headers\": {\n \"Host\": \"httpbin.org\", \n \"X-Amzn-Trace-Id\": \"Root=1-6240752c-0ca44cd103db1aa80f21bbb8\"\n }\n}\n"
528+
#> [1] "{\n \"headers\": {\n \"Host\": \"httpbin.org\", \n \"X-Amzn-Trace-Id\": \"Root=1-62423f4c-518bbe8f41e1779c424a5ab3\"\n }\n}\n"
529529
```
530530

531531
For advanced use, supports additional HTTP methods such as POST or PUT.
532+
533+
``` r
534+
res <- ncurl("http://httpbin.org/post", "POST", "application/json", "Bearer APIKEY", '{"key": "value"}')
535+
res$data
536+
#> [1] "{\n \"args\": {}, \n \"data\": \"{\\\"key\\\": \\\"value\\\"}\", \n \"files\": {}, \n \"form\": {}, \n \"headers\": {\n \"Authorization\": \"Bearer APIKEY\", \n \"Content-Length\": \"16\", \n \"Content-Type\": \"application/json\", \n \"Host\": \"httpbin.org\", \n \"X-Amzn-Trace-Id\": \"Root=1-62423f4c-4de27fd3765f72b51e01d918\"\n }, \n \"json\": {\n \"key\": \"value\"\n }, \n \"origin\": \"78.145.225.121\", \n \"url\": \"http://httpbin.org/post\"\n}\n"
537+
```
538+
532539
In this respect, it may be used as a performant and lightweight method
533540
for making requests to REST APIs.
534541

@@ -547,18 +554,20 @@ s
547554
#> - type: dialer
548555
#> - url: wss://socketsbay.com/wss/v2/2/demo/
549556
#> - textframes: TRUE
557+
s |> send("hello world")
558+
#> [1] 68 65 6c 6c 6f 20 77 6f 72 6c 64 00
550559
```
551560

552-
The stream interface is especially useful for communicating with
553-
websocket servers. Where TLS is enabled in the NNG library, connecting
554-
to secure websockets is configured automatically. Here, the argument
555-
`textframes = TRUE` can be specified where the websocket server uses
556-
text rather than binary frames.
561+
The stream interface can be used to communicate with websocket servers.
562+
Where TLS is enabled in the NNG library, connecting to secure websockets
563+
is configured automatically. Here, the argument `textframes = TRUE` can
564+
be specified where the websocket server uses text rather than binary
565+
frames.
557566

558-
The same API as found in the rest of the package is available:
559-
synchronous `send`/`recv`, as well as their asynchronous counterparts
560-
`send_aio`/`recv_aio`. This affords an extraordinary amount of
561-
flexibility in ingesting and processing streaming data.
567+
The same API for Sockets can equally be used on Streams: `send()` and
568+
`recv()`, as well as their asynchronous counterparts `send_aio()` and
569+
`recv_aio()`. This affords a great deal of flexibility in ingesting and
570+
processing streaming data.
562571

563572
[« Back to ToC](#table-of-contents)
564573

man/ncurl.Rd

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

man/recv.Rd

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/send.Rd

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/stream.Rd

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

0 commit comments

Comments
 (0)