Merge pull request #2970 from rstudio/joe/feature/ui-http-response-2

This commit is contained in:
Winston Chang
2020-07-16 14:11:37 -05:00
committed by GitHub
9 changed files with 80 additions and 14 deletions

View File

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

View File

@@ -116,6 +116,7 @@ export(hoverOpts)
export(hr)
export(htmlOutput)
export(htmlTemplate)
export(httpResponse)
export(icon)
export(imageOutput)
export(img)

View File

@@ -6,6 +6,10 @@ shiny 1.5.0.9000
* Added appropriate labels to `icon()` element to provide screen-reader users with alternative descriptions for the `fontawesome` and `glyphicon`: `aria-label` is automatically applied based on the fontawesome name. For example, `icon("calendar")` will be announced as "calendar icon" to screen readers. "presentation" aria role has also been attached to `icon()` to remove redundant semantic info for screen readers.
### Minor new features and improvements
* When UI is specified as a function (e.g. `ui <- function(req) { ... }`), the response can now be an HTTP response as returned from the (newly exported) `httpResponse()` function. (#2970)
### Bug fixes
* Fixed #2859: `renderPlot()` wasn't correctly setting `showtext::showtext_opts()`'s `dpi` setting with the correct resolution on high resolution displays; which means, if the font was rendered by showtext, font sizes would look smaller than they should on such displays. (#2941)

View File

@@ -14,7 +14,26 @@
# returns `NULL`, or an `httpResponse`.
#
## ------------------------------------------------------------------------
httpResponse <- function(status = 200,
#' Create an HTTP response object
#'
#' @param status HTTP status code for the response.
#' @param content_type The value for the `Content-Type` header.
#' @param content The body of the response, given as a single-element character
#' vector (will be encoded as UTF-8) or a raw vector.
#' @param headers A named list of additional headers to include. Do not include
#' `Content-Length` (as it is automatically calculated) or `Content-Type` (the
#' `content_type` argument is used instead).
#'
#' @examples
#' httpResponse(status = 405L,
#' content_type = "text/plain",
#' content = "The requested method was not allowed"
#' )
#'
#' @keywords internal
#' @export
httpResponse <- function(status = 200L,
content_type = "text/html; charset=UTF-8",
content = "",
headers = list()) {

View File

@@ -24,7 +24,7 @@ withMathJax <- function(...) {
)
}
renderPage <- function(ui, connection, showcase=0, testMode=FALSE) {
renderPage <- function(ui, showcase=0, testMode=FALSE) {
# If the ui is a NOT complete document (created by htmlTemplate()), then do some
# preprocessing and make sure it's a complete document.
if (!inherits(ui, "html_document")) {
@@ -77,7 +77,7 @@ renderPage <- function(ui, connection, showcase=0, testMode=FALSE) {
}
html <- renderDocument(ui, shiny_deps, processDep = createWebDependency)
writeUTF8(html, con = connection)
enc2utf8(paste(collapse = "\n", html))
}
#' Create a Shiny UI handler
@@ -101,16 +101,18 @@ uiHttpHandler <- function(ui, uiPattern = "^/$") {
force(ui)
allowed_methods <- "GET"
if (is.function(ui)) {
allowed_methods <- attr(ui, "http_methods_supported", exact = TRUE) %OR% allowed_methods
}
function(req) {
if (!identical(req$REQUEST_METHOD, 'GET'))
if (!isTRUE(req$REQUEST_METHOD %in% allowed_methods))
return(NULL)
if (!isTRUE(grepl(uiPattern, req$PATH_INFO)))
return(NULL)
textConn <- file(open = "w+")
on.exit(close(textConn))
showcaseMode <- .globals$showcaseDefault
if (.globals$showcaseOverride) {
mode <- showcaseModeOfReq(req)
@@ -150,8 +152,11 @@ uiHttpHandler <- function(ui, uiPattern = "^/$") {
if (is.null(uiValue))
return(NULL)
renderPage(uiValue, textConn, showcaseMode, testMode)
html <- paste(readLines(textConn, encoding = 'UTF-8'), collapse='\n')
return(httpResponse(200, content=enc2utf8(html)))
if (inherits(uiValue, "httpResponse")) {
return(uiValue)
} else {
html <- renderPage(uiValue, showcaseMode, testMode)
return(httpResponse(200, content=html))
}
}
}

View File

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

File diff suppressed because one or more lines are too long

36
man/httpResponse.Rd Normal file
View File

@@ -0,0 +1,36 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/middleware.R
\name{httpResponse}
\alias{httpResponse}
\title{Create an HTTP response object}
\usage{
httpResponse(
status = 200L,
content_type = "text/html; charset=UTF-8",
content = "",
headers = list()
)
}
\arguments{
\item{status}{HTTP status code for the response.}
\item{content_type}{The value for the \code{Content-Type} header.}
\item{content}{The body of the response, given as a single-element character
vector (will be encoded as UTF-8) or a raw vector.}
\item{headers}{A named list of additional headers to include. Do not include
\code{Content-Length} (as it is automatically calculated) or \code{Content-Type} (the
\code{content_type} argument is used instead).}
}
\description{
Create an HTTP response object
}
\examples{
httpResponse(status = 405L,
content_type = "text/plain",
content = "The requested method was not allowed"
)
}
\keyword{internal}

View File

@@ -195,6 +195,7 @@ reference:
- onStop
- diskCache
- memoryCache
- httpResponse
- key_missing
- title: Plot interaction
desc: Functions related to interactive plots