Compare commits

...

9 Commits

Author SHA1 Message Date
Winston Chang
4d778faaf4 Bump version to 1.3.2 2019-04-18 11:51:16 -05:00
Winston Chang
3055cf5602 Update NEWS 2019-04-18 11:49:09 -05:00
Joe Cheng
36373ba28b Merge pull request #2386 from rstudio/joe/bugfix/subapp-routing
Fix #2385: R Markdown documents containing subapps not rendering properly
2019-04-18 08:49:56 -07:00
Joe Cheng
1415b57181 Add sys.www.root to createAppHandlers, so that subapps can access /shared/* 2019-04-16 18:40:29 -07:00
Joe Cheng
65d4a4e906 Add comments 2019-04-16 18:12:09 -07:00
Joe Cheng
0abe221227 Use v1.3.1.9000 2019-04-14 17:21:26 -07:00
Joe Cheng
1b8d822226 Fix #2385: R Markdown documents containing subapps not rendering properly 2019-04-14 17:19:17 -07:00
Joe Cheng
f5392d77dc Merge pull request #2382 from rstudio/fix-index-html
Fix serving of www/index.html
2019-04-11 11:43:44 -07:00
Winston Chang
1e88990a0b Fix serving of www/index.html. Closes #2380 2019-04-11 11:57:48 -05:00
6 changed files with 85 additions and 14 deletions

View File

@@ -1,7 +1,7 @@
Package: shiny
Type: Package
Title: Web Application Framework for R
Version: 1.3.1
Version: 1.3.2
Authors@R: c(
person("Winston", "Chang", role = c("aut", "cre"), email = "winston@rstudio.com"),
person("Joe", "Cheng", role = "aut", email = "joe@rstudio.com"),

14
NEWS.md
View File

@@ -1,20 +1,20 @@
shiny 1.3.1
shiny 1.3.2
===========
## Full changelog
### Bug fixes
### Breaking changes
* Fixed [#2285](https://github.com/rstudio/shiny/issues/2285), [#2288](https://github.com/rstudio/shiny/issues/2288): Static CSS/JS resources in subapps in R Markdown documents did not render properly. ([#2386](https://github.com/rstudio/shiny/pull/2386))
### New features
* Fixed [#2280](https://github.com/rstudio/shiny/issues/2280): Shiny applications that used a www/index.html file did not serve up the index file. ([#2382](https://github.com/rstudio/shiny/pull/2382))
### Minor new features and improvements
shiny 1.3.1
===========
### Bug fixes
* Fixed a performance issue introduced in v1.3.0 when using large nested lists within Shiny. ([#2377](https://github.com/rstudio/shiny/pull/2377))
### Documentation Updates
shiny 1.3.0
===========

16
R/app.R
View File

@@ -228,7 +228,13 @@ shinyAppDir_serverR <- function(appDir, options=list()) {
structure(
list(
staticPaths = staticPaths,
httpHandler = joinHandlers(c(uiHandler, fallbackWWWDir)),
# Even though the wwwDir is handled as a static path, we need to include
# it here to be handled by R as well. This is because the special case
# of index.html: it is specifically not handled as a staticPath for
# reasons explained above, but if someone does want to serve up an
# index.html, we need to handle it, and we do it by using the
# staticHandler in the R code path. (#2380)
httpHandler = joinHandlers(c(uiHandler, wwwDir, fallbackWWWDir)),
serverFuncSource = serverFuncSource,
onStart = onStart,
onStop = onStop,
@@ -355,7 +361,13 @@ shinyAppDir_appR <- function(fileName, appDir, options=list())
# uiHandler, then falbackWWWDir (which is served up by the R
# staticHandler function).
staticPaths = staticPaths,
httpHandler = joinHandlers(c(dynHttpHandler, fallbackWWWDir)),
# Even though the wwwDir is handled as a static path, we need to include
# it here to be handled by R as well. This is because the special case
# of index.html: it is specifically not handled as a staticPath for
# reasons explained above, but if someone does want to serve up an
# index.html, we need to handle it, and we do it by using the
# staticHandler in the R code path. (#2380)
httpHandler = joinHandlers(c(dynHttpHandler, wwwDir, fallbackWWWDir)),
serverFuncSource = dynServerFuncSource,
onStart = onStart,
onStop = onStop,

View File

@@ -23,6 +23,7 @@ registerClient <- function(client) {
.globals$resourcePaths <- list()
.globals$resources <- list()
.globals$showcaseDefault <- 0
@@ -69,8 +70,62 @@ addResourcePath <- function(prefix, directoryPath) {
getShinyOption("server")$setStaticPath(.list = stats::setNames(normalizedPath, prefix))
}
# .globals$resourcePaths persists across runs of applications.
# .globals$resourcePaths and .globals$resources persist across runs of applications.
.globals$resourcePaths[[prefix]] <- staticPath(normalizedPath)
# This is necessary because resourcePaths is only for serving assets out of C++;
# to support subapps, we also need assets to be served out of R, because those
# URLs are rewritten by R code (i.e. routeHandler) before they can be matched to
# a resource path.
.globals$resources[[prefix]] <- list(
directoryPath = normalizedPath,
func = staticHandler(normalizedPath)
)
}
# This function handles any GET request with two or more path elements where the
# first path element matches a prefix that was previously added using
# addResourcePath().
#
# For example, if `addResourcePath("foo", "~/bar")` was called, then a GET
# request for /foo/one/two.html would rewrite the PATH_INFO as /one/two.html and
# send it to the resource path function for "foo". As of this writing, that
# function will always be a staticHandler, which serves up a file if it exists
# and NULL if it does not.
#
# Since Shiny 1.3.x, assets registered via addResourcePath should mostly be
# served out of httpuv's native static file serving features. However, in the
# specific case of subapps, the R code path must be used, because subapps insert
# a giant random ID into the beginning of the URL that must be stripped off by
# an R route handler (see addSubApp()).
resourcePathHandler <- function(req) {
if (!identical(req$REQUEST_METHOD, 'GET'))
return(NULL)
# e.g. "/foo/one/two.html"
path <- req$PATH_INFO
match <- regexpr('^/([^/]+)/', path, perl=TRUE)
if (match == -1)
return(NULL)
len <- attr(match, 'capture.length')
# e.g. "foo"
prefix <- substr(path, 2, 2 + len - 1)
resInfo <- .globals$resources[[prefix]]
if (is.null(resInfo))
return(NULL)
# e.g. "/one/two.html"
suffix <- substr(path, 2 + len, nchar(path))
# Create a new request that's a clone of the current request, but adjust
# PATH_INFO and SCRIPT_NAME to reflect that we have already matched the first
# path element (e.g. "/foo"). See routeHandler() for more info.
subreq <- as.environment(as.list(req, all.names=TRUE))
subreq$PATH_INFO <- suffix
subreq$SCRIPT_NAME <- paste(subreq$SCRIPT_NAME, substr(path, 1, 2 + len), sep='')
return(resInfo$func(subreq))
}
#' Define Server Functionality
@@ -158,6 +213,8 @@ createAppHandlers <- function(httpHandlers, serverFuncSource) {
appvars <- new.env()
appvars$server <- NULL
sys.www.root <- system.file('www', package='shiny')
# This value, if non-NULL, must be present on all HTTP and WebSocket
# requests as the Shiny-Shared-Secret header or else access will be
# denied (403 response for HTTP, and instant close for websocket).
@@ -167,6 +224,8 @@ createAppHandlers <- function(httpHandlers, serverFuncSource) {
http = joinHandlers(c(
sessionHandler,
httpHandlers,
sys.www.root,
resourcePathHandler,
reactLogHandler
)),
ws = function(ws) {

View File

@@ -12,7 +12,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
var exports = window.Shiny = window.Shiny || {};
exports.version = "1.3.1"; // Version number inserted by Grunt
exports.version = "1.3.2"; // Version number inserted by Grunt
var origPushState = window.history.pushState;
window.history.pushState = function () {

File diff suppressed because one or more lines are too long