From 38a562d71e2a3b73b428ca8087e4c34e5a0584c6 Mon Sep 17 00:00:00 2001 From: Nelson Areal Date: Wed, 17 May 2023 09:35:39 +0100 Subject: [PATCH 1/2] Added a parameter that allows the upgrade of insecure requests This avoids the browser block of the websocket served through ws [CSP: upgrade-insecure-requests - HTTP | MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/upgrade-insecure-requests) --- DESCRIPTION | 2 +- R/file_stream_server.R | 29 ++++++++++++++++----- inst/templates/prism.html | 2 ++ man/file_stream_server.Rd | 10 +++++++- man/lc_server_iface.Rd | 53 +++++++++++++++++++++------------------ man/serve_file.Rd | 5 +++- src/RcppExports.cpp | 5 ++++ 7 files changed, 72 insertions(+), 34 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 6c8abbd..2a8db9d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -27,6 +27,6 @@ Imports: crayon, rstudioapi, stringi -RoxygenNote: 7.1.0 +RoxygenNote: 7.2.3 LinkingTo: Rcpp diff --git a/R/file_stream_server.R b/R/file_stream_server.R index abfa98f..6a6dfac 100644 --- a/R/file_stream_server.R +++ b/R/file_stream_server.R @@ -37,13 +37,19 @@ lc_server <- R6::R6Class( ) -file_stream_server = function(host, port, file, file_id, interval = 3, template = "prism") { +file_stream_server = function(host, port, file, file_id, interval = 3, template = "prism", upgrade_content_security_policy) { port = as.integer(port) file_cache = file_cache(file) + if (upgrade_content_security_policy == TRUE){ + content_security_policy = '' + } else { + content_security_policy = "" + } page = glue::glue( readr::read_file(get_template(template)), lang = "r", - title = file + title = file, + meta = content_security_policy ) get_next_ws_id = local({ @@ -157,6 +163,7 @@ lc_server_iface = R6::R6Class( interval = NULL, bitly_url = NULL, server = NULL, + upgrade_content_security_policy = NULL, init_file = function(file, auto_save) { @@ -271,9 +278,11 @@ lc_server_iface = R6::R6Class( #' @param bitly should a bitly bit link be created for the server. #' @param auto_save should the broadcast file be auto saved update tic. #' @param open_browser should a browser session be opened. + #' @param upgrade_content_security_policy should insecure requests be upgraded. initialize = function( file, ip, port, interval = 2, - bitly = FALSE, auto_save = TRUE, open_browser = TRUE + bitly = FALSE, auto_save = TRUE, open_browser = TRUE, + upgrade_content_security_policy = FALSE ) { private$init_file(file, auto_save) private$init_ip(ip) @@ -281,6 +290,8 @@ lc_server_iface = R6::R6Class( private$template = "prism" private$interval = interval + private$upgrade_content_security_policy = + upgrade_content_security_policy self$start() if (bitly) @@ -368,7 +379,9 @@ lc_server_iface = R6::R6Class( start = function() { private$server = file_stream_server( private$ip, private$port, private$file, private$file_id, - template = private$template, interval = private$interval + template = private$template, interval = private$interval, + upgrade_content_security_policy = + private$upgrade_content_security_policy ) usethis::ui_done( paste( @@ -442,16 +455,20 @@ lc_server_iface = R6::R6Class( #' @param bitly should a bitly bit link be created for the server. #' @param auto_save should the broadcast file be auto saved during each update tic. #' @param open_browser should a browser session be opened. +#' @param upgrade_content_security_policy should insecure requests be upgraded. #' #' @export serve_file = function(file, ip, port, interval = 1, bitly = FALSE, auto_save = TRUE, - open_browser = TRUE) { + open_browser = TRUE, + upgrade_content_security_policy = FALSE) { server = lc_server_iface$new(file = file, ip = ip, port = port, interval = interval, bitly = bitly, auto_save = auto_save, - open_browser = open_browser) + open_browser = open_browser, + upgrade_content_security_policy = + upgrade_content_security_policy) welcome_msg = c( "## Welcome to `livecode`!", diff --git a/inst/templates/prism.html b/inst/templates/prism.html index 64c00d0..5c68c7f 100644 --- a/inst/templates/prism.html +++ b/inst/templates/prism.html @@ -3,6 +3,8 @@ {title} + {meta} + diff --git a/man/file_stream_server.Rd b/man/file_stream_server.Rd index 5989f10..9ebd20c 100644 --- a/man/file_stream_server.Rd +++ b/man/file_stream_server.Rd @@ -4,7 +4,15 @@ \alias{file_stream_server} \title{Content-Type' = 'text/html'} \usage{ -file_stream_server(host, port, file, file_id, interval = 3, template = "prism") +file_stream_server( + host, + port, + file, + file_id, + interval = 3, + template = "prism", + upgrade_content_security_policy +) } \description{ Content-Type' = 'text/html' diff --git a/man/lc_server_iface.Rd b/man/lc_server_iface.Rd index 6703c93..78cbb5e 100644 --- a/man/lc_server_iface.Rd +++ b/man/lc_server_iface.Rd @@ -20,19 +20,19 @@ The interface also provides additional tools for sending messages. \section{Methods}{ \subsection{Public methods}{ \itemize{ -\item \href{#method-new}{\code{lc_server_iface$new()}} -\item \href{#method-open}{\code{lc_server_iface$open()}} -\item \href{#method-print}{\code{lc_server_iface$print()}} -\item \href{#method-send_msg}{\code{lc_server_iface$send_msg()}} -\item \href{#method-is_running}{\code{lc_server_iface$is_running()}} -\item \href{#method-start}{\code{lc_server_iface$start()}} -\item \href{#method-stop}{\code{lc_server_iface$stop()}} -\item \href{#method-restart}{\code{lc_server_iface$restart()}} +\item \href{#method-LiveCodeServer_Interface-new}{\code{lc_server_iface$new()}} +\item \href{#method-LiveCodeServer_Interface-open}{\code{lc_server_iface$open()}} +\item \href{#method-LiveCodeServer_Interface-print}{\code{lc_server_iface$print()}} +\item \href{#method-LiveCodeServer_Interface-send_msg}{\code{lc_server_iface$send_msg()}} +\item \href{#method-LiveCodeServer_Interface-is_running}{\code{lc_server_iface$is_running()}} +\item \href{#method-LiveCodeServer_Interface-start}{\code{lc_server_iface$start()}} +\item \href{#method-LiveCodeServer_Interface-stop}{\code{lc_server_iface$stop()}} +\item \href{#method-LiveCodeServer_Interface-restart}{\code{lc_server_iface$restart()}} } } \if{html}{\out{
}} -\if{html}{\out{}} -\if{latex}{\out{\hypertarget{method-new}{}}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-LiveCodeServer_Interface-new}{}}} \subsection{Method \code{new()}}{ Creates a new livecode server \subsection{Usage}{ @@ -43,7 +43,8 @@ Creates a new livecode server interval = 2, bitly = FALSE, auto_save = TRUE, - open_browser = TRUE + open_browser = TRUE, + upgrade_content_security_policy = FALSE )}\if{html}{\out{}} } @@ -63,13 +64,15 @@ Creates a new livecode server \item{\code{auto_save}}{should the broadcast file be auto saved update tic.} \item{\code{open_browser}}{should a browser session be opened.} + +\item{\code{upgrade_content_security_policy}}{should insecure requests be upgraded.} } \if{html}{\out{}} } } \if{html}{\out{
}} -\if{html}{\out{}} -\if{latex}{\out{\hypertarget{method-open}{}}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-LiveCodeServer_Interface-open}{}}} \subsection{Method \code{open()}}{ Open server in browser \subsection{Usage}{ @@ -78,8 +81,8 @@ Open server in browser } \if{html}{\out{
}} -\if{html}{\out{}} -\if{latex}{\out{\hypertarget{method-print}{}}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-LiveCodeServer_Interface-print}{}}} \subsection{Method \code{print()}}{ Class print method \subsection{Usage}{ @@ -88,8 +91,8 @@ Class print method } \if{html}{\out{
}} -\if{html}{\out{}} -\if{latex}{\out{\hypertarget{method-send_msg}{}}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-LiveCodeServer_Interface-send_msg}{}}} \subsection{Method \code{send_msg()}}{ Send a noty message to all connected users on the next update tic. \subsection{Usage}{ @@ -122,8 +125,8 @@ Send a noty message to all connected users on the next update tic. } } \if{html}{\out{
}} -\if{html}{\out{}} -\if{latex}{\out{\hypertarget{method-is_running}{}}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-LiveCodeServer_Interface-is_running}{}}} \subsection{Method \code{is_running()}}{ Determine if the server is running. \subsection{Usage}{ @@ -135,8 +138,8 @@ Returns `TRUE` if the server is running. } } \if{html}{\out{
}} -\if{html}{\out{}} -\if{latex}{\out{\hypertarget{method-start}{}}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-LiveCodeServer_Interface-start}{}}} \subsection{Method \code{start()}}{ Start the server \subsection{Usage}{ @@ -145,8 +148,8 @@ Start the server } \if{html}{\out{
}} -\if{html}{\out{}} -\if{latex}{\out{\hypertarget{method-stop}{}}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-LiveCodeServer_Interface-stop}{}}} \subsection{Method \code{stop()}}{ Stop the server \subsection{Usage}{ @@ -162,8 +165,8 @@ Stop the server } } \if{html}{\out{
}} -\if{html}{\out{}} -\if{latex}{\out{\hypertarget{method-restart}{}}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-LiveCodeServer_Interface-restart}{}}} \subsection{Method \code{restart()}}{ Restart the server \subsection{Usage}{ diff --git a/man/serve_file.Rd b/man/serve_file.Rd index e35edf1..97513d6 100644 --- a/man/serve_file.Rd +++ b/man/serve_file.Rd @@ -11,7 +11,8 @@ serve_file( interval = 1, bitly = FALSE, auto_save = TRUE, - open_browser = TRUE + open_browser = TRUE, + upgrade_content_security_policy = FALSE ) } \arguments{ @@ -28,6 +29,8 @@ serve_file( \item{auto_save}{should the broadcast file be auto saved during each update tic.} \item{open_browser}{should a browser session be opened.} + +\item{upgrade_content_security_policy}{should insecure requests be upgraded.} } \description{ Create a livecode server for broadcasting a file diff --git a/src/RcppExports.cpp b/src/RcppExports.cpp index a944df3..14b2d44 100644 --- a/src/RcppExports.cpp +++ b/src/RcppExports.cpp @@ -5,6 +5,11 @@ using namespace Rcpp; +#ifdef RCPP_USE_GLOBAL_ROSTREAM +Rcpp::Rostream& Rcpp::Rcout = Rcpp::Rcpp_cout_get(); +Rcpp::Rostream& Rcpp::Rcerr = Rcpp::Rcpp_cerr_get(); +#endif + // get_ipv4 Rcpp::CharacterVector get_ipv4(); RcppExport SEXP _livecode_get_ipv4() { From 78b9f97d3144b768e23e59e6d46f425572786f16 Mon Sep 17 00:00:00 2001 From: Nelson Areal Date: Thu, 22 Feb 2024 09:58:28 +0000 Subject: [PATCH 2/2] Replaced the markdownToHTML function by mark_html available since version 1.3 of the markdown package. --- R/file_stream_server.R | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/R/file_stream_server.R b/R/file_stream_server.R index 6a6dfac..5e293bf 100644 --- a/R/file_stream_server.R +++ b/R/file_stream_server.R @@ -340,10 +340,9 @@ lc_server_iface = R6::R6Class( ..., parse_md = TRUE) { if (parse_md) { - text = markdown::markdownToHTML( + text = markdown::mark_html( text = text, - fragment.only = TRUE, - extensions = markdown::markdownExtensions() + template = FALSE ) } else { text = paste(text, collapse = "\n")