Skip to content

Commit 9512894

Browse files
committed
support returning strings for cross-client compatibility
1 parent 7237dcb commit 9512894

File tree

4 files changed

+99
-54
lines changed

4 files changed

+99
-54
lines changed

R/ncurl.R

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -271,46 +271,3 @@ as.promise.ncurlAio <- function(x) {
271271
#' @exportS3Method promises::is.promising
272272
#'
273273
is.promising.ncurlAio <- function(x) TRUE
274-
275-
#' Start REST Server
276-
#'
277-
#' Creates an instance of an HTTP REST server which evaluates R expressions sent
278-
#' to it [EXPERIMENTAL]. As arbitrary R expressions are evaluated, this
279-
#' should only be deployed on the local machine (using the 127.0.0.1
280-
#' loopback address) in a trusted environment.
281-
#'
282-
#' @param url full http address including hostname, port and path at which to
283-
#' host the server.
284-
#'
285-
#' @details Query the API with an HTTP client using the \sQuote{POST} method,
286-
#' with the request data being the R expression as a text string. The
287-
#' received response body will consist of the serialized evaluation result.
288-
#' Unserialize to return an R object.
289-
#'
290-
#' Use only in a new session. Use \sQuote{ctrl + \\} to forcibly quit
291-
#' when finished as the function blocks with no means of interruption.
292-
#'
293-
#' Currently still experimental as the server lacks error handling. Sending
294-
#' an invalid R expression will cause the server to exit.
295-
#'
296-
#' @return This function never returns.
297-
#'
298-
#' @examples
299-
#' if (interactive()) {
300-
#'
301-
#' # run in a new session:
302-
#' # nanonext::server()
303-
#'
304-
#' res <- ncurl("http://127.0.0.1:5555/api/rest",
305-
#' convert = FALSE,
306-
#' method = "POST",
307-
#' data = "Sys.time()")
308-
#'
309-
#' if (!is_error_value(res$data)) unserialize(res$data)
310-
#'
311-
#' }
312-
#'
313-
#' @export
314-
#'
315-
server <- function(url = "http://127.0.0.1:5555/api/rest")
316-
.Call(rnng_rest_server, url)

R/server.R

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Copyright (C) 2022-2024 Hibiki AI Limited <[email protected]>
2+
#
3+
# This file is part of nanonext.
4+
#
5+
# nanonext is free software: you can redistribute it and/or modify it under the
6+
# terms of the GNU General Public License as published by the Free Software
7+
# Foundation, either version 3 of the License, or (at your option) any later
8+
# version.
9+
#
10+
# nanonext is distributed in the hope that it will be useful, but WITHOUT ANY
11+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12+
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13+
#
14+
# You should have received a copy of the GNU General Public License along with
15+
# nanonext. If not, see <https://www.gnu.org/licenses/>.
16+
17+
# nanonext - server - HTTP REST Server -----------------------------------------
18+
19+
#' Start REST Server
20+
#'
21+
#' Creates an instance of an HTTP REST server which evaluates R expressions sent
22+
#' to it [EXPERIMENTAL]. As arbitrary R expressions are evaluated, this
23+
#' should only be deployed on the local machine (using the 127.0.0.1
24+
#' loopback address) in a trusted environment.
25+
#'
26+
#' @param url full http address including hostname, port and path at which to
27+
#' host the server.
28+
#'
29+
#' @details Query the API with an HTTP client using the \sQuote{POST} method,
30+
#' with the request data being the R expression as a text string. The
31+
#' received response body will consist of the evaluation result as a text
32+
#' string (if of the appropriate type), or otherwise a serialized R object,
33+
#' which should be passed to \code{\link{unserialize}}.
34+
#'
35+
#' Use only in a new session. Use \sQuote{ctrl + \\} to forcibly quit
36+
#' when finished as the function blocks with no means of interruption.
37+
#'
38+
#' Currently still experimental as the server lacks error handling. Sending
39+
#' an invalid R expression will cause the server to quit.
40+
#'
41+
#' @return This function never returns.
42+
#'
43+
#' @examples
44+
#' if (interactive()) {
45+
#'
46+
#' # run server in a new session:
47+
#' # Rscript -e 'nanonext::server()'
48+
#'
49+
#' # query using curl:
50+
#' # curl -X POST http://127.0.0.1:5555/api/rest -d 'format(Sys.time())'
51+
#'
52+
#' ncurl(
53+
#' "http://127.0.0.1:5555/api/rest",
54+
#' method = "POST",
55+
#' data = "format(Sys.time())"
56+
#' )
57+
#'
58+
#' res <- ncurl(
59+
#' "http://127.0.0.1:5555/api/rest",
60+
#' convert = FALSE,
61+
#' method = "POST",
62+
#' data = "data.frame(random = nanonext::random(3))"
63+
#' )
64+
#' if (!is_error_value(res$data)) unserialize(res$data)
65+
#'
66+
#' }
67+
#'
68+
#' @export
69+
#'
70+
server <- function(url = "http://127.0.0.1:5555/api/rest")
71+
.Call(rnng_rest_server, url)

man/server.Rd

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

src/server.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,13 @@ void inproc_server(const char* url) {
253253
const char *body = nng_msg_body(msg);
254254
nano_buf buf;
255255
SEXP res = R_ParseEvalString(body, R_GlobalEnv);
256-
nano_serialize(&buf, res, R_NilValue);
256+
if (TYPEOF(res) == STRSXP) {
257+
const char *string = NANO_STRING(res);
258+
buf.buf = (unsigned char *) string;
259+
buf.cur = strlen(string);
260+
} else {
261+
nano_serialize(&buf, res, R_NilValue);
262+
}
257263
nng_msg_clear(msg);
258264
nng_msg_append(msg, buf.buf, buf.cur);
259265
if ((xc = nng_sendmsg(s, msg, 0)))

0 commit comments

Comments
 (0)