Skip to content

Commit

Permalink
feat(runStaticServer): Serve a static directory easily
Browse files Browse the repository at this point in the history
  • Loading branch information
gadenbuie committed Aug 15, 2023
1 parent 326b719 commit 5041b3e
Show file tree
Hide file tree
Showing 6 changed files with 152 additions and 0 deletions.
1 change: 1 addition & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,6 @@ Collate:
'httpuv.R'
'random_port.R'
'server.R'
'staticServer.R'
'static_paths.R'
'utils.R'
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export(listServers)
export(randomPort)
export(rawToBase64)
export(runServer)
export(runStaticServer)
export(service)
export(startDaemonizedServer)
export(startPipeServer)
Expand Down
78 changes: 78 additions & 0 deletions R/staticServer.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#' Serve a directory
#'
#' Run a server to host a static directory.
#'
#' @examplesIf interactive()
#' website_dir <- system.file("example-static-site", package = "httpuv")
#' runStaticServer(dir = website_dir)
#'
#' @param dir The directory to serve. Defaults to the current working directory.
#' @inheritParams startServer
#' @param background Whether to run the server in the background. By default,
#' the server runs in the foreground and blocks the R console. You can stop
#' the server by interrupting it with `Ctrl + C`.
#'
#' When `background = TRUE`, the server will run in the background and will
#' process requests when the R console is idle. To stop a background server,
#' call [stopAllServers()] or call [stopServer()] on the server object
#' returned (invisibly) by this function.
#'
#' @seealso [runServer()] provides a similar interface for running a dynamic
#' app server. Both `runStaticServer()` and [runServer()] are built on top of
#' [startServer()], [service()] and [stopServer()]. Learn more about httpuv
#' servers in [startServer()].
#'
#' @export
runStaticServer <- function(
dir = getwd(),
host = "127.0.0.1",
port = 7446,
background = FALSE,
browse = interactive()
) {
stopifnot(
"`port` must be an integer" = is.numeric(port),
"`port` must be an integer" = port == as.integer(port),
"`port` must be a single integer" = length(port) == 1
)

port <- requested_or_random_port(port, host)
root <- staticPath(dir)

server <- startServer(
app = list(staticPaths = list("/" = root)),
host = host,
port = port
)

message("Serving: '", dir, "'")
message("View at: http://", host, ":", port, sep = "")

if (isTRUE(browse)) {
utils::browseURL(paste0("http://", host, ":", port))
}

if (background) return(invisible(server))

on.exit(stopServer(server))
service(0)
}

requested_or_random_port <- function(port, host = "127.0.0.1") {
tryCatch(
# Is the requested port open?
randomPort(port, port, host = host),
error = function(err) {
msg <- conditionMessage(err)
if (!grepl("Cannot find an available port", msg, fixed = TRUE)) {
stop(msg)
}
warning(
"Port ", port, " is not available. Using a random port.",
immediate. = TRUE,
call. = FALSE
)
randomPort(host = host)
}
)
}
12 changes: 12 additions & 0 deletions inst/example-static-site/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Home | A Static Site</title>
</head>
<body>
<h1>Hello, static site</h1>
<p>This is a static site with just two pages. This is the <strong>home page</strong> and the other page is an <a href="office.html">office page</a>.</p>
</body>
</html>
12 changes: 12 additions & 0 deletions inst/example-static-site/office.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Office | A Static Site</title>
</head>
<body>
<h1>Hello, static site</h1>
<p>This is a static site with just two pages. This is the <strong>office page</strong> and the other page is the <a href="index.html">home page</a>.</p>
</body>
</html>
48 changes: 48 additions & 0 deletions man/runStaticServer.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 5041b3e

Please sign in to comment.