Skip to content

RStudio/Posit Workbench static file paths break #997

@LucaAnholt

Description

@LucaAnholt

Background

I'm trying to serve a website via some static JS, HTML and CSS files in RStudio Workbench using a plumber API I'm developing.

The plumber API endpoint serving the static files (as per the docs) is defined as:

#* static files
#* @assets ./dist /
list()

The ./dist folder containing the static website files is structured like so (with index.html using relative paths to source all of the various files):

dist
├── assets
│   ├── index-BuF2VGXq.js
│   ├── index-CAJq-P8_.css
│   ├── index-ChuXfzd8.js
│   └── testPage-MBawWazC.js
├── favicon.ico
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
└── robots.txt

When I run the plumber API, all my other endpoints work as expected, however when I go to the root / I see the following errors in the browser console:

Failed to load resource: the server responded with a status of 404 (Not Found) index-ChuXfzd8.js:1
Failed to load resource: the server responded with a status of 404 (Not Found) manifest.json:1 

This is because the URL in RStudio Workbench is dynamic and uses a proxy in order for it to be accessible via the browser.

For example, when running my API on port 8900 in my Workbench session, http://127.0.0.1:8900 proxies over to https://<workbench_instance>.net/s/a441fcfc78a310d8af850/p/a5d3c674/.

I can therefore successfully access the static files manually at their relevant endpoints using the full dynamic proxy URL:

https://<workbench_instance>.net/s/a441fcfc78a310d8af850/p/a5d3c674/assets/index-ChuXfzd8.js:1

TL/DR

So in short, my API running in Workbench is (unsuccessfully) trying to access the static files using the base URL:

e.g.

https://<workbench_instance>.net/assets/index-ChuXfzd8.js

which ultimately fails because it's actually served at the full dynamic / proxy URL:

e.g.

https://<workbench_instance>.net/s/a441fcfc78a310d8af850/p/a5d3c674/assets/index-ChuXfzd8.js

My current (hacky) workarounds

1. Hardcode the full dynamic paths into my ./dist/index.html file

This works but is less than ideal as these are hardcoded and will break when I rebuild the static files, change the port my API is running at, or start a new Workbench session.

2. Dynamically modify the endpoint using rstudioapi::translateLocalUrl

In this workaround I

  1. Get the translated Workbench proxy URL using rstudioapi::translateLocalUrl() for the specific port my API is running at
  2. Use the dynamic /s/<service ID>/p/<random ID> portion of the proxy URL defining the current service running the API as a prefix to my plumber API root endpoint
library(plumber)
library(rstudioapi)

port <- 8900

generate_base_path <- function(port = 8900) {
  local_url <- glue::glue("http://127.0.0.1:{port}/")
  
  translated_url <- rstudioapi::translateLocalUrl(local_url, absolute = TRUE)

  base_path <- sub("http[s]?://[^/]+", "", translated_url)
  
  return(base_path)
}

base_path <- generate_base_path(port = port)

static_router <- PlumberStatic$new("./dist")

pr <- plumber::plumb("./plumber.R")

## Mount the static file folder dynamically to the correct proxy path
pr$mount(paste0(base_path, "/dist"), static_router)

local_url <- glue::glue("http://127.0.0.1:{port}/")
message(glue::glue("Running at: {rstudioapi::translateLocalUrl(local_url, absolute = TRUE)}"))
pr$run(port = port, docs = FALSE)

This is obviously quite convoluted and I was wondering (hoping) if there were any better solutions!

I saw that #60 requests something quite similar, however, unfortunately I cannot in my case use docker / nginx or any other external routing solutions as the admin maintaining the server in which the RStudio Workbench instance is running cannot/won't install docker.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions