diff --git a/R/plumber.R b/R/plumber.R index 235781f5a..ea54df4fe 100644 --- a/R/plumber.R +++ b/R/plumber.R @@ -2,6 +2,11 @@ #' @import stringi NULL +# Hard code UTF-8 file encoding +# Removes encoding headache at minor cost of setting encoding in editor +# https://github.com/trestletech/plumber/pull/312 +utf8Encoding <- "UTF-8" + # used to identify annotation flags. verbs <- c("GET", "PUT", "POST", "DELETE", "HEAD", "OPTIONS", "PATCH") enumerateVerbs <- function(v){ @@ -13,7 +18,7 @@ enumerateVerbs <- function(v){ #' @rdname plumber #' @export -plumb <- function(file, dir=".", encoding="UTF-8"){ +plumb <- function(file, dir="."){ dirMode <- NULL @@ -50,7 +55,7 @@ plumb <- function(file, dir=".", encoding="UTF-8"){ on.exit(setwd(old)) # Expect that entrypoint will provide us with the router - x <- source(entrypoint, encoding=encoding) + x <- source(entrypoint, encoding=utf8Encoding) # source returns a list with value and visible elements, we want the (visible) value object. pr <- x$value @@ -62,7 +67,7 @@ plumb <- function(file, dir=".", encoding="UTF-8"){ } else if (file.exists(file)) { # Plumber file found - plumber$new(file, encoding=encoding) + plumber$new(file) } else { # Couldn't find the Plumber file nor an entrypoint stop("File does not exist: ", file) @@ -133,7 +138,6 @@ hookable <- R6Class( #' plumber router definition. Alternatively, if an `entrypoint.R` file is #' found, it will take precedence and be responsible for returning a runnable #' Plumber router. -#' @param encoding Encoding of the input file; see [base::file()]. #' @include globals.R #' @include serializer-json.R #' @include parse-block.R @@ -145,7 +149,7 @@ plumber <- R6Class( "plumber", inherit = hookable, public = list( - initialize = function(file=NULL, filters=defaultPlumberFilters, envir, encoding="UTF-8"){ + initialize = function(file=NULL, filters=defaultPlumberFilters, envir){ if (!is.null(file)){ if (!file.exists(file)){ @@ -178,11 +182,11 @@ plumber <- R6Class( private$notFoundHandler <- default404Handler if (!is.null(file)){ - con <- file(file, encoding=encoding) + con <- file(file, encoding=utf8Encoding) on.exit(close(con), add=TRUE) private$lines <- readLines(con) - Encoding(private$lines) <- "UTF-8" + Encoding(private$lines) <- utf8Encoding srcfile <- srcfilecopy(file, private$lines, file.info(file)[1, "mtime"], isFile=TRUE) diff --git a/man/plumber.Rd b/man/plumber.Rd index a56ade9fa..0e207d464 100644 --- a/man/plumber.Rd +++ b/man/plumber.Rd @@ -7,7 +7,7 @@ \title{Plumber Router} \format{An object of class \code{R6ClassGenerator} of length 24.} \usage{ -plumb(file, dir = ".", encoding = "UTF-8") +plumb(file, dir = ".") plumber } @@ -18,8 +18,6 @@ plumber plumber router definition. Alternatively, if an \code{entrypoint.R} file is found, it will take precedence and be responsible for returning a runnable Plumber router.} - -\item{encoding}{Encoding of the input file; see \code{\link[base:file]{base::file()}}.} } \description{ Routers are the core request handler in plumber. A router is responsible for diff --git a/tests/testthat/files/gb2312-encoded.R b/tests/testthat/files/gb2312-encoded.R deleted file mode 100644 index 0bd094902..000000000 --- a/tests/testthat/files/gb2312-encoded.R +++ /dev/null @@ -1,5 +0,0 @@ -# Note this file is saved with GB2312 encoding intentionally -#* @get /echo -function() { - "ÖÐÎÄÏûÏ¢" -} diff --git a/tests/testthat/files/multibytes.R b/tests/testthat/files/multibytes.R new file mode 100644 index 000000000..2f1563baf --- /dev/null +++ b/tests/testthat/files/multibytes.R @@ -0,0 +1,4 @@ +#* @get /echo +function() { + "中文消æ¯" +} diff --git a/tests/testthat/test-encoding.R b/tests/testthat/test-encoding.R deleted file mode 100644 index ed837c734..000000000 --- a/tests/testthat/test-encoding.R +++ /dev/null @@ -1,10 +0,0 @@ -context("encoding") - -test_that("support other encoding", { - r <- plumber$new("files/gb2312-encoded.R", encoding = "GB2312") - req <- make_req("GET", "/echo") - res <- PlumberResponse$new() - out <- r$serve(req, res)$body - expect_identical(out, jsonlite::toJSON("\u4e2d\u6587\u6d88\u606f")) - expect_equal(Encoding(out), "UTF-8") -}) diff --git a/tests/testthat/test-multibytes.R b/tests/testthat/test-multibytes.R new file mode 100644 index 000000000..e91cb1e64 --- /dev/null +++ b/tests/testthat/test-multibytes.R @@ -0,0 +1,12 @@ +context("multibytes source file") + +test_that("support files with multibytes", { + # on Windows, the default encoding is not UTF-8. So, plumber has to + # tell R to use UTF-8 encoding to read the source file. + r <- plumber$new("files/multibytes.R") + req <- make_req("GET", "/echo") + res <- PlumberResponse$new() + out <- r$serve(req, res)$body + expect_identical(out, jsonlite::toJSON("\u4e2d\u6587\u6d88\u606f")) + expect_equal(Encoding(out), "UTF-8") +})