Code inside "app.R"
library(shiny)
shiny:::handlerManager$addHandler(
function(req) {
print(req$REQUEST_METHOD)
return(NULL)
},
"key"
)
ui <- fluidPage()
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
When directory structure looks like this:
app/
|-- app.R
The commands
curl -X GET http://127.0.0.1:3818
curl -X POST http://127.0.0.1:3818
works fine.
The R console outputs
Listening on http://127.0.0.1:3818
[1] "GET"
[1] "POST"
[1] "GET"
But when i add empty www directory to app directory POST no longer works.
(If I add dir named www_tmp it works)
app/
|-- app.R
|-- www/
The R console outputs after same GET and POST request
Listening on http://127.0.0.1:3818
[1] "GET"
[1] "GET"
So my questions are ...
- Why does www dir impacts POST request?
- Can i fix it somehow? (Have www dir and POST request)
---------- EDIT 2023-03-30 Solution ----------
Why does www dir impacts POST request?
hg77 answered it in Accepting POST requests from Shiny · GitHub :
I think I found the root cause in https://github.com/rstudio/shiny/blob/main/R/server.R#L395
httpuv is handling the requests before they hit the R handlers.
"session" = excludeStaticPath(),
/session is excluded. And
curl -vX POST http://localhost:3838/session/post
hits the R handlers.
Can i fix it somehow? (Have www dir and POST request)
Yes! But I need to exclude my path form handling by httpuv
I can do it by:
shiny_env <- shiny:::.globals
shiny_env$resourcePaths <- c(shiny_env$resourcePaths, list("MY_POST_ROOT_PATH" = httpuv::excludeStaticPath()))
The full working app would look like this:
library(shiny)
shiny:::handlerManager$addHandler(
function(req) {
print(req$REQUEST_METHOD)
return(NULL)
},
"key"
)
ui <- fluidPage()
server <- function(input, output) {}
shiny_env <- shiny:::.globals
shiny_env$resourcePaths <- c(shiny_env$resourcePaths, list("postpath" = httpuv::excludeStaticPath()))
shinyApp(ui = ui, server = server)
This app can accept all POST request to path postpath
e.g.: curl -vX POST http://localhost:3838/postpath/
Note: The / at the end is required