Search code examples
rhttprestrserve

cannot access RestRserve via GET on localhost from a browser


I am starting a RestRserve application using the following R code (MacOS):

library(RestRserve)
app = Application$new(
  middleware = list(CORSMiddleware$new())
)

app$add_static(
  path = '/main',
  file_path = here::here('inst/html/test.html')
)

app$logger = Logger$new(level = "trace", name = "mylogger")
backend = BackendRserve$new()
backend$start(app, http_port = 8080)

with the test.html containing the simple code:

<!DOCTYPE html>
<html>
  <head>
    <title>Test</title>
  </head>
  <body>
    <div id = 'testdiv'>This is a test.</div>
    <script>
      console.log('hi.');
    </script>
  </body>
</html>

From curl on the command line, it works:

# curl http://localhost:8080/main

outputs

<!DOCTYPE html>
<html>
  <head>
    <title>Test</title>
  </head>
  <body>
    <div id = 'testdiv'>This is a test.</div>
    <script>
      console.log('hi.');
    </script>
  </body>
</html>

and the RestRserve log shows

{"timestamp":"2022-11-05 15:37:45.227026","level":"DEBUG","name":"mylogger","pid":29392,"msg":"","context":{"request_id":"cb2a0c38-5d1f-11ed-95b4-ae6922d47386","request":{"method":"GET","path":"/main","parameters_query":{},"parameters_path":[],"headers":{"accept":"*/*","user-agent":"curl/7.79.1","host":"localhost:8080"}}}}
{"timestamp":"2022-11-05 15:37:45.230490","level":"TRACE","name":"mylogger","pid":29392,"msg":"","context":{"request_id":"cb2a0c38-5d1f-11ed-95b4-ae6922d47386","middleware":"CORSMiddleware","message":"call process_request middleware"}}
{"timestamp":"2022-11-05 15:37:45.232072","level":"TRACE","name":"mylogger","pid":29392,"msg":"","context":{"request_id":"cb2a0c38-5d1f-11ed-95b4-ae6922d47386","message":"try to match requested path '/main'"}}
{"timestamp":"2022-11-05 15:37:45.232939","level":"TRACE","name":"mylogger","pid":29392,"msg":"","context":{"request_id":"cb2a0c38-5d1f-11ed-95b4-ae6922d47386","message":"requested path matched"}}
{"timestamp":"2022-11-05 15:37:45.233711","level":"TRACE","name":"mylogger","pid":29392,"msg":"","context":{"request_id":"cb2a0c38-5d1f-11ed-95b4-ae6922d47386","message":"call handler '1'"}}
{"timestamp":"2022-11-05 15:37:45.272269","level":"TRACE","name":"mylogger","pid":29392,"msg":"","context":{"request_id":"cb2a0c38-5d1f-11ed-95b4-ae6922d47386","middleware":"CORSMiddleware","message":"call process_response middleware"}}
{"timestamp":"2022-11-05 15:37:45.273345","level":"DEBUG","name":"mylogger","pid":29392,"msg":"","context":{"request_id":"cb2a0c38-5d1f-11ed-95b4-ae6922d47386","response":{"status_code":200,"headers":{"Server":"RestRserve/1.2.1; Rserve/1.8.10","Access-Control-Allow-Origin":"*"}}}}

However, when I try to access the same page locally from a (Firefox) browser, I get a 404:

GEThttp://localhost:8080/main
[HTTP/1.1 404 Code 404 69ms]

    
GET
    http://localhost:8080/main
Status
404
Code 404
VersionHTTP/1.1
Transferred125 B (13 B size)
Request PriorityHighest

        
    Content-length
        13
    Content-type
        text/plain
    Server
        RestRserve/1.2.1; Rserve/1.8.10
        
    Accept
        text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
    Accept-Encoding
        gzip, deflate, br
    Accept-Language
        en-GB,en;q=0.5
    Connection
        keep-alive
    DNT
        1
    Host
        localhost:8080
    Sec-Fetch-Dest
        document
    Sec-Fetch-Mode
        navigate
    Sec-Fetch-Site
        none
    Sec-Fetch-User
        ?1
    Upgrade-Insecure-Requests
        1
    User-Agent
        Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:106.0) Gecko/20100101 Firefox/106.0

...and from the RestRserve logs:

{"timestamp":"2022-11-05 15:38:44.337891","level":"DEBUG","name":"mylogger","pid":29405,"msg":"","context":{"request_id":"ee65b4e0-5d1f-11ed-95b4-ae6922d47386","request":{"method":"GET","path":"http://localhost:8080/main","parameters_query":{},"parameters_path":[],"headers":{"sec-fetch-user":"?1","accept":["text/html","application/xhtml+xml","application/xml;q=0.9","image/avif","image/webp","*/*;q=0.8"],"sec-fetch-mode":"navigate","upgrade-insecure-requests":"1","sec-fetch-site":"none","connection":"keep-alive","dnt":"1","sec-fetch-dest":"document","accept-encoding":["gzip","deflate","br"],"host":"localhost:8080","accept-language":["en-GB","en;q=0.5"],"user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:106.0) Gecko/20100101 Firefox/106.0"}}}}
{"timestamp":"2022-11-05 15:38:44.341087","level":"TRACE","name":"mylogger","pid":29405,"msg":"","context":{"request_id":"ee65b4e0-5d1f-11ed-95b4-ae6922d47386","middleware":"CORSMiddleware","message":"call process_request middleware"}}
{"timestamp":"2022-11-05 15:38:44.342118","level":"TRACE","name":"mylogger","pid":29405,"msg":"","context":{"request_id":"ee65b4e0-5d1f-11ed-95b4-ae6922d47386","message":"try to match requested path 'http://localhost:8080/main'"}}
{"timestamp":"2022-11-05 15:38:44.378608","level":"TRACE","name":"mylogger","pid":29405,"msg":"","context":{"request_id":"ee65b4e0-5d1f-11ed-95b4-ae6922d47386","message":"requested path not matched"}}
{"timestamp":"2022-11-05 15:38:44.387233","level":"TRACE","name":"mylogger","pid":29405,"msg":"","context":{"request_id":"ee65b4e0-5d1f-11ed-95b4-ae6922d47386","middleware":"CORSMiddleware","message":"call process_response middleware"}}
{"timestamp":"2022-11-05 15:38:44.390369","level":"DEBUG","name":"mylogger","pid":29405,"msg":"","context":{"request_id":"ee65b4e0-5d1f-11ed-95b4-ae6922d47386","response":{"status_code":404,"headers":{"Server":"RestRserve/1.2.1; Rserve/1.8.10"}}}}

The key bit seems to be that when I request the page from curl, the server log reports try to match requested path '/main' - but when I do it from the browser, it reports try to match requested path 'http://localhost:8080/main'.

I suspect I'm doing something very basic wrong, but I'm not sure what it is. Any help would be appreciated.

My xfun::session_info():

R version 4.2.1 (2022-06-23)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Monterey 12.6

Locale: en_GB.UTF-8 / en_GB.UTF-8 / en_GB.UTF-8 / C / en_GB.UTF-8 / en_GB.UTF-8

Package version:
  backports_1.4.1  base64enc_0.1-3  bslib_0.4.1      cachem_1.0.6    
  checkmate_2.1.0  compiler_4.2.1   digest_0.6.30    evaluate_0.17   
  fastmap_1.1.0    fs_1.5.2         glue_1.6.2       graphics_4.2.1  
  grDevices_4.2.1  here_1.0.1       highr_0.9        htmltools_0.5.3 
  jquerylib_0.1.4  jsonlite_1.8.3   knitr_1.40       magrittr_2.0.3  
  memoise_2.0.1    methods_4.2.1    mime_0.12        parallel_4.2.1  
  R6_2.5.1         rappdirs_0.3.3   Rcpp_1.0.9       renv_0.16.0     
  RestRserve_1.2.1 rlang_1.0.6      rmarkdown_2.17   rprojroot_2.0.3 
  Rserve_1.8-10    sass_0.4.2       stats_4.2.1      stringi_1.7.8   
  stringr_1.4.1    tinytex_0.42     tools_4.2.1      utils_4.2.1     
  uuid_1.1-0       xfun_0.34        yaml_2.3.6      

Edit: Here's a zip file containing the necessary files, along with an renv lock file for reproducibility: zip file

I have since discovered that it seems to be ONLY Firefox with the issue. Chrome and Safari work as expected, as the following log shows:

{"timestamp":"2022-11-06 15:15:59.319797","level":"INFO","name":"mylogger","pid":42436,"msg":"","context":{"http_port":8080,"endpoints":{"GET":"/main"}}}
{"timestamp":"2022-11-06 15:15:59.322679","level":"DEBUG","name":"mylogger","pid":42436,"msg":"","context":"setting JIT level to 0"}
-- running Rserve in this R session (pid=42436), 2 server(s) --
(This session will block until Rserve is shut down)

// CURL
{"timestamp":"2022-11-06 15:16:20.977514","level":"DEBUG","name":"mylogger","pid":42462,"msg":"","context":{"request_id":"f81b042e-5de5-11ed-8d0e-ae6922d47386","request":{"method":"GET","path":"/main","parameters_query":{},"parameters_path":[],"headers":{"accept":"*/*","user-agent":"curl/7.79.1","host":"localhost:8080"}}}}
{"timestamp":"2022-11-06 15:16:20.979314","level":"TRACE","name":"mylogger","pid":42462,"msg":"","context":{"request_id":"f81b042e-5de5-11ed-8d0e-ae6922d47386","middleware":"CORSMiddleware","message":"call process_request middleware"}}
{"timestamp":"2022-11-06 15:16:20.979948","level":"TRACE","name":"mylogger","pid":42462,"msg":"","context":{"request_id":"f81b042e-5de5-11ed-8d0e-ae6922d47386","message":"try to match requested path '/main'"}}
{"timestamp":"2022-11-06 15:16:20.980293","level":"TRACE","name":"mylogger","pid":42462,"msg":"","context":{"request_id":"f81b042e-5de5-11ed-8d0e-ae6922d47386","message":"requested path matched"}}
{"timestamp":"2022-11-06 15:16:20.980612","level":"TRACE","name":"mylogger","pid":42462,"msg":"","context":{"request_id":"f81b042e-5de5-11ed-8d0e-ae6922d47386","message":"call handler '1'"}}
{"timestamp":"2022-11-06 15:16:21.019697","level":"TRACE","name":"mylogger","pid":42462,"msg":"","context":{"request_id":"f81b042e-5de5-11ed-8d0e-ae6922d47386","middleware":"CORSMiddleware","message":"call process_response middleware"}}
{"timestamp":"2022-11-06 15:16:21.020889","level":"DEBUG","name":"mylogger","pid":42462,"msg":"","context":{"request_id":"f81b042e-5de5-11ed-8d0e-ae6922d47386","response":{"status_code":200,"headers":{"Server":"RestRserve/1.2.1; Rserve/1.8.10","Access-Control-Allow-Origin":"*"}}}}


// FIREFOX
{"timestamp":"2022-11-06 15:16:39.105416","level":"DEBUG","name":"mylogger","pid":42537,"msg":"","context":{"request_id":"02e91044-5de6-11ed-8d0e-ae6922d47386","request":{"method":"GET","path":"http://localhost:8080/main","parameters_query":{},"parameters_path":[],"headers":{"sec-fetch-user":"?1","accept":["text/html","application/xhtml+xml","application/xml;q=0.9","image/avif","image/webp","*/*;q=0.8"],"sec-fetch-mode":"navigate","upgrade-insecure-requests":"1","sec-fetch-site":"none","connection":"keep-alive","dnt":"1","sec-fetch-dest":"document","accept-encoding":["gzip","deflate","br"],"host":"localhost:8080","accept-language":["en-GB","en;q=0.5"],"user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:106.0) Gecko/20100101 Firefox/106.0"}}}}
{"timestamp":"2022-11-06 15:16:39.109379","level":"TRACE","name":"mylogger","pid":42537,"msg":"","context":{"request_id":"02e91044-5de6-11ed-8d0e-ae6922d47386","middleware":"CORSMiddleware","message":"call process_request middleware"}}
{"timestamp":"2022-11-06 15:16:39.110400","level":"TRACE","name":"mylogger","pid":42537,"msg":"","context":{"request_id":"02e91044-5de6-11ed-8d0e-ae6922d47386","message":"try to match requested path 'http://localhost:8080/main'"}}
{"timestamp":"2022-11-06 15:16:39.130536","level":"TRACE","name":"mylogger","pid":42537,"msg":"","context":{"request_id":"02e91044-5de6-11ed-8d0e-ae6922d47386","message":"requested path not matched"}}
{"timestamp":"2022-11-06 15:16:39.135085","level":"TRACE","name":"mylogger","pid":42537,"msg":"","context":{"request_id":"02e91044-5de6-11ed-8d0e-ae6922d47386","middleware":"CORSMiddleware","message":"call process_response middleware"}}
{"timestamp":"2022-11-06 15:16:39.135951","level":"DEBUG","name":"mylogger","pid":42537,"msg":"","context":{"request_id":"02e91044-5de6-11ed-8d0e-ae6922d47386","response":{"status_code":404,"headers":{"Server":"RestRserve/1.2.1; Rserve/1.8.10"}}}}


// CHROME
{"timestamp":"2022-11-06 15:17:02.465899","level":"DEBUG","name":"mylogger","pid":42581,"msg":"","context":{"request_id":"10d59236-5de6-11ed-8d0e-ae6922d47386","request":{"method":"GET","path":"/main","parameters_query":{},"parameters_path":[],"headers":{"accept-language":["en-GB","en-US;q=0.9","en;q=0.8"],"sec-fetch-user":"?1","sec-fetch-mode":"navigate","accept":["text/html","application/xhtml+xml","application/xml;q=0.9","image/avif","image/webp","image/apng","*/*;q=0.8","application/signed-exchange;v=b3;q=0.9"],"upgrade-insecure-requests":"1","host":"localhost:8080","sec-ch-ua-mobile":"?0","connection":"keep-alive","sec-fetch-site":"none","accept-encoding":["gzip","deflate","br"],"sec-ch-ua-platform":"\"macOS\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36","sec-fetch-dest":"document","sec-ch-ua":"\"Google Chrome\";v=\"107\", \"Chromium\";v=\"107\", \"Not=A?Brand\";v=\"24\""}}}}
{"timestamp":"2022-11-06 15:17:02.469188","level":"TRACE","name":"mylogger","pid":42581,"msg":"","context":{"request_id":"10d59236-5de6-11ed-8d0e-ae6922d47386","middleware":"CORSMiddleware","message":"call process_request middleware"}}
{"timestamp":"2022-11-06 15:17:02.500166","level":"TRACE","name":"mylogger","pid":42581,"msg":"","context":{"request_id":"10d59236-5de6-11ed-8d0e-ae6922d47386","message":"try to match requested path '/main'"}}
{"timestamp":"2022-11-06 15:17:02.501355","level":"TRACE","name":"mylogger","pid":42581,"msg":"","context":{"request_id":"10d59236-5de6-11ed-8d0e-ae6922d47386","message":"requested path matched"}}
{"timestamp":"2022-11-06 15:17:02.502114","level":"TRACE","name":"mylogger","pid":42581,"msg":"","context":{"request_id":"10d59236-5de6-11ed-8d0e-ae6922d47386","message":"call handler '1'"}}
{"timestamp":"2022-11-06 15:17:02.508769","level":"TRACE","name":"mylogger","pid":42581,"msg":"","context":{"request_id":"10d59236-5de6-11ed-8d0e-ae6922d47386","middleware":"CORSMiddleware","message":"call process_response middleware"}}
{"timestamp":"2022-11-06 15:17:02.521776","level":"DEBUG","name":"mylogger","pid":42581,"msg":"","context":{"request_id":"10d59236-5de6-11ed-8d0e-ae6922d47386","response":{"status_code":200,"headers":{"Server":"RestRserve/1.2.1; Rserve/1.8.10","Access-Control-Allow-Origin":"*"}}}}
{"timestamp":"2022-11-06 15:17:02.589190","level":"DEBUG","name":"mylogger","pid":42581,"msg":"","context":{"request_id":"10e88832-5de6-11ed-8d0e-ae6922d47386","request":{"method":"GET","path":"/favicon.ico","parameters_query":{},"parameters_path":[],"headers":{"accept-language":["en-GB","en-US;q=0.9","en;q=0.8"],"sec-fetch-mode":"no-cors","accept":["image/avif","image/webp","image/apng","image/svg+xml","image/*","*/*;q=0.8"],"referer":"http://localhost:8080/main","sec-ch-ua":"\"Google Chrome\";v=\"107\", \"Chromium\";v=\"107\", \"Not=A?Brand\";v=\"24\"","sec-fetch-dest":"image","host":"localhost:8080","sec-ch-ua-mobile":"?0","connection":"keep-alive","sec-fetch-site":"same-origin","accept-encoding":["gzip","deflate","br"],"sec-ch-ua-platform":"\"macOS\"","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"}}}}
{"timestamp":"2022-11-06 15:17:02.590595","level":"TRACE","name":"mylogger","pid":42581,"msg":"","context":{"request_id":"10e88832-5de6-11ed-8d0e-ae6922d47386","middleware":"CORSMiddleware","message":"call process_request middleware"}}
{"timestamp":"2022-11-06 15:17:02.624676","level":"TRACE","name":"mylogger","pid":42581,"msg":"","context":{"request_id":"10e88832-5de6-11ed-8d0e-ae6922d47386","message":"try to match requested path '/favicon.ico'"}}
{"timestamp":"2022-11-06 15:17:02.625751","level":"TRACE","name":"mylogger","pid":42581,"msg":"","context":{"request_id":"10e88832-5de6-11ed-8d0e-ae6922d47386","message":"requested path not matched"}}
{"timestamp":"2022-11-06 15:17:02.629144","level":"TRACE","name":"mylogger","pid":42581,"msg":"","context":{"request_id":"10e88832-5de6-11ed-8d0e-ae6922d47386","middleware":"CORSMiddleware","message":"call process_response middleware"}}
{"timestamp":"2022-11-06 15:17:02.629966","level":"DEBUG","name":"mylogger","pid":42581,"msg":"","context":{"request_id":"10e88832-5de6-11ed-8d0e-ae6922d47386","response":{"status_code":404,"headers":{"Server":"RestRserve/1.2.1; Rserve/1.8.10"}}}}


// SAFARI
{"timestamp":"2022-11-06 15:17:46.317929","level":"DEBUG","name":"mylogger","pid":42600,"msg":"","context":{"request_id":"2af8d6dc-5de6-11ed-8d0e-ae6922d47386","request":{"method":"GET","path":"/main","parameters_query":{},"parameters_path":[],"headers":{"connection":"keep-alive","accept-encoding":["gzip","deflate"],"user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Safari/605.1.15","accept":["text/html","application/xhtml+xml","application/xml;q=0.9","*/*;q=0.8"],"accept-language":["en-GB","en;q=0.9"],"host":"localhost:8080","upgrade-insecure-requests":"1"}}}}
{"timestamp":"2022-11-06 15:17:46.321741","level":"TRACE","name":"mylogger","pid":42600,"msg":"","context":{"request_id":"2af8d6dc-5de6-11ed-8d0e-ae6922d47386","middleware":"CORSMiddleware","message":"call process_request middleware"}}
{"timestamp":"2022-11-06 15:17:46.323816","level":"TRACE","name":"mylogger","pid":42600,"msg":"","context":{"request_id":"2af8d6dc-5de6-11ed-8d0e-ae6922d47386","message":"try to match requested path '/main'"}}
{"timestamp":"2022-11-06 15:17:46.343214","level":"TRACE","name":"mylogger","pid":42600,"msg":"","context":{"request_id":"2af8d6dc-5de6-11ed-8d0e-ae6922d47386","message":"requested path matched"}}
{"timestamp":"2022-11-06 15:17:46.344548","level":"TRACE","name":"mylogger","pid":42600,"msg":"","context":{"request_id":"2af8d6dc-5de6-11ed-8d0e-ae6922d47386","message":"call handler '1'"}}
{"timestamp":"2022-11-06 15:17:46.351469","level":"TRACE","name":"mylogger","pid":42600,"msg":"","context":{"request_id":"2af8d6dc-5de6-11ed-8d0e-ae6922d47386","middleware":"CORSMiddleware","message":"call process_response middleware"}}
{"timestamp":"2022-11-06 15:17:46.352603","level":"DEBUG","name":"mylogger","pid":42600,"msg":"","context":{"request_id":"2af8d6dc-5de6-11ed-8d0e-ae6922d47386","response":{"status_code":200,"headers":{"Server":"RestRserve/1.2.1; Rserve/1.8.10","Access-Control-Allow-Origin":"*"}}}}
{"timestamp":"2022-11-06 15:17:46.625070","level":"DEBUG","name":"mylogger","pid":42600,"msg":"","context":{"request_id":"2b27e03a-5de6-11ed-8d0e-ae6922d47386","request":{"method":"GET","path":"/favicon.ico","parameters_query":{},"parameters_path":[],"headers":{"accept-encoding":["gzip","deflate"],"referer":"http://localhost:8080/main","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Safari/605.1.15","accept":"*/*","accept-language":["en-GB","en;q=0.9"],"host":"localhost:8080","connection":"keep-alive"}}}}
{"timestamp":"2022-11-06 15:17:46.625808","level":"TRACE","name":"mylogger","pid":42600,"msg":"","context":{"request_id":"2b27e03a-5de6-11ed-8d0e-ae6922d47386","middleware":"CORSMiddleware","message":"call process_request middleware"}}
{"timestamp":"2022-11-06 15:17:46.626167","level":"TRACE","name":"mylogger","pid":42600,"msg":"","context":{"request_id":"2b27e03a-5de6-11ed-8d0e-ae6922d47386","message":"try to match requested path '/favicon.ico'"}}
{"timestamp":"2022-11-06 15:17:46.630388","level":"TRACE","name":"mylogger","pid":42600,"msg":"","context":{"request_id":"2b27e03a-5de6-11ed-8d0e-ae6922d47386","message":"requested path not matched"}}
{"timestamp":"2022-11-06 15:17:46.636464","level":"TRACE","name":"mylogger","pid":42600,"msg":"","context":{"request_id":"2b27e03a-5de6-11ed-8d0e-ae6922d47386","middleware":"CORSMiddleware","message":"call process_response middleware"}}
{"timestamp":"2022-11-06 15:17:46.637459","level":"DEBUG","name":"mylogger","pid":42600,"msg":"","context":{"request_id":"2b27e03a-5de6-11ed-8d0e-ae6922d47386","response":{"status_code":404,"headers":{"Server":"RestRserve/1.2.1; Rserve/1.8.10"}}}}


Solution

  • The cause was a Firefox extension, "IPFS companion": https://github.com/ipfs/ipfs-companion. When this extension is disabled, things work as expected.