• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

R/H23-Apr-2021-1,807836

demo/H13-Apr-2018-159131

man/H23-Apr-2021-1,2141,097

src/H03-May-2022-180,985131,228

tests/H13-Apr-2018-1,7471,303

tools/H05-Jun-2020-10668

DESCRIPTIONH A D14-Dec-20212.2 KiB5150

LICENSEH A D23-Apr-20215.7 KiB13595

MD5H A D14-Dec-202135.5 KiB565564

NAMESPACEH A D12-Jan-2021910 3937

NEWS.mdH A D13-Dec-202112 KiB325171

README.mdH A D13-Dec-20215.8 KiB172123

README.md

1# httpuv: HTTP and WebSocket server library for R
2
3  <!-- badges: start -->
4  [![R build status](https://github.com/rstudio/httpuv/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/rstudio/httpuv/actions)
5  <!-- badges: end -->
6
7httpuv provides low-level socket and protocol support for handling HTTP and WebSocket requests directly from within R. It uses a multithreaded architecture, where I/O is handled on one thread, and the R callbacks are handled on another.
8
9It is primarily intended as a building block for other packages, rather than making it particularly easy to create complete web applications using httpuv alone. httpuv is built on top of the [libuv](https://github.com/joyent/libuv) and [http-parser](https://github.com/nodejs/http-parser) C libraries, both of which were developed by Joyent, Inc.
10
11
12## Installing
13
14You can install the stable version from CRAN, or the development version using **remotes**:
15
16```r
17# install from CRAN
18install.packages("httpuv")
19
20# or if you want to test the development version here
21if (!require("remotes")) install.packages("remotes")
22remotes::install_github("rstudio/httpuv")
23```
24
25Since httpuv contains C code, you'll need to make sure you're set up to install packages with compiled code. Follow the instructions at http://www.rstudio.com/ide/docs/packages/prerequisites
26
27
28## Basic Usage
29
30This is a basic web server that listens on port 5000 and responds to HTTP requests with a web page containing the current system time and the path of the request:
31
32```R
33library(httpuv)
34
35s <- startServer(host = "0.0.0.0", port = 5000,
36  app = list(
37    call = function(req) {
38      body <- paste0("Time: ", Sys.time(), "<br>Path requested: ", req$PATH_INFO)
39      list(
40        status = 200L,
41        headers = list('Content-Type' = 'text/html'),
42        body = body
43      )
44    }
45  )
46)
47```
48
49Note that when `host` is 0.0.0.0, it listens on all network interfaces. If `host` is 127.0.0.1, it will only listen to connections from the local host.
50
51The `startServer()` function takes an _app object_, which is a named list with functions that are invoked in response to certain events. In the example above, the list contains a function `call`. This function is invoked when a complete HTTP request is received by the server, and it is passed an environment object `req`, which contains information about HTTP request. `req$PATH_INFO` is the path requested (if the request was for http://127.0.0.1:5000/foo, it would be `"/foo"`).
52
53The `call` function is expected to return a list containing `status`, `headers`, and `body`. That list will be transformed into a HTTP response and sent to the client.
54
55To stop the server:
56
57```R
58s$stop()
59```
60
61Or, to stop all running httpuv servers:
62
63```R
64stopAllServers()
65```
66
67
68### Static paths
69
70A httpuv server application can serve up files on disk. This happens entirely within the I/O thread, so doing so will not block or be blocked by activity in the main R thread.
71
72To serve a path, use `staticPaths` in the app. This will serve the `www/` subdirectory of the current directory (from when `startServer` is called) as the root of the web path:
73
74```R
75s <- startServer("0.0.0.0", path = 5000,
76  app = list(
77    staticPaths = list("/" = "www/")
78  )
79)
80```
81
82By default, if a file named `index.html` exists in the directory, it will be served when `/` is requested.
83
84`staticPaths` can be combined with `call`. In this example, the web paths `/assets` and `/lib` are served from disk, but requests for any other paths go through the `call` function.
85
86```R
87s <- startServer("0.0.0.0", 5000,
88  list(
89    call = function(req) {
90      list(
91        status = 200L,
92        headers = list(
93          'Content-Type' = 'text/html'
94        ),
95        body = "Hello world!"
96      )
97    },
98    staticPaths = list(
99      "/assets" = "content/assets/",
100      # Don't use index.html for /lib
101      "/lib" = staticPath("content/lib", indexhtml = FALSE)
102    )
103  )
104)
105```
106
107
108### WebSocket server
109
110httpuv also can handle WebSocket connections. For example, this app acts as a WebSocket echo server:
111
112```R
113s <- startServer("127.0.0.1", 8080,
114  list(
115    onWSOpen = function(ws) {
116      # The ws object is a WebSocket object
117      cat("Server connection opened.\n")
118
119      ws$onMessage(function(binary, message) {
120        cat("Server received message:", message, "\n")
121        ws$send(message)
122      })
123      ws$onClose(function() {
124        cat("Server connection closed.\n")
125      })
126    }
127  )
128)
129```
130
131
132To test it out, you can connect to it using the [websocket](https://github.com/rstudio/websocket) package (which provides a WebSocket client). You can do this from the same R process or a different one.
133
134```R
135ws <- websocket::WebSocket$new("ws://127.0.0.1:8080/")
136ws$onMessage(function(event) {
137  cat("Client received message:", event$data, "\n")
138})
139
140# Wait for a moment before running next line
141ws$send("hello world")
142
143# Close client
144ws$close()
145```
146
147Note that both the httpuv and websocket packages provide a class named `WebSocket`; however, in httpuv, that class acts as a server, and in websocket, it acts as a client. They also have different APIs. For more information about the WebSocket client package, see the [project page](https://github.com/rstudio/websocket).
148
149---
150
151
152## Debugging builds
153
154httpuv can be built with debugging options enabled. This can be done by uncommenting these lines in src/Makevars, and then installing. The first one enables thread assertions, to ensure that code is running on the correct thread; if not. The second one enables tracing statements: httpuv will print lots of messages when various events occur.
155
156```
157PKG_CPPFLAGS += -DDEBUG_THREAD -UNDEBUG
158PKG_CPPFLAGS += -DDEBUG_TRACE
159```
160
161To install it directly from GitHub with these options, you can use `with_makevars`, like this:
162
163```R
164withr::with_makevars(
165  c(PKG_CPPFLAGS="-DDEBUG_TRACE -DDEBUG_THREAD -UNDEBUG"), {
166    devtools::install_github("rstudio/httpuv")
167  }, assignment = "+="
168)
169```
170
171&copy; 2013-2020 RStudio, Inc.
172