-
Notifications
You must be signed in to change notification settings - Fork 264
Add 405 http code handling #554
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(See comments)
…avoid duplicating execution
Merge remote-tracking branch 'upstream/master' into http_405 # Conflicts: # NEWS.md
This is much better. Thank you. It still feels weird overloading the |
Co-authored-by: Barret Schloerke <barret@rstudio.com>
Co-authored-by: Barret Schloerke <barret@rstudio.com>
Merge remote-tracking branch 'upstream/master' into http_405 # Conflicts: # NEWS.md
Merge remote-tracking branch 'upstream/master' into http_405 # Conflicts: # NEWS.md
Ok. I believe I have a solution that we can use inside # this function works under the assumption that the regular route was not found.
# Here we are only trying to find if there are other routes that can be
allowed_verbs <- function(pr, path_to_find) {
verbs_allowed <- c()
# look at all possible endpoints
for (endpoint_group in pr$endpoints) {
for (endpoint in endpoint_group) {
if (endpoint$matchesPath(path_to_find)) {
verbs_allowed <- c(verbs_allowed, endpoint$verbs)
}
}
}
# look at all possible mounts
for (i in seq_along(pr$mounts)) {
mount <- pr$mounts[[i]]
mount_path <- sub("/$", "", names(pr$mounts)[i]) # trim trailing `/`
# if the front of the urls don't match, move on to next mount
if (!identical(
substr(path_to_find, 0, nchar(mount_path)),
mount_path
)) {
next
}
# remove path and recurse
mount_path_to_find <- substr(path_to_find, nchar(mount_path) + 1, nchar(path_to_find))
m_verbs <- allowed_verbs(mount, mount_path_to_find)
# add any verbs found
if (length(m_verbs) > 0) {
verbs_allowed <- c(verbs_allowed, m_verbs)
}
}
# return verbs
return(verbs_allowed)
}
pr <- plumber$new()
sub <- plumber$new()
sub$handle("GET", "/test", force)
pr$mount("/barret", sub)
allowed_verbs(pr, path_to_find = "/barret/test") # "GET"
allowed_verbs(pr, path_to_find = "/subroute/not_found") # NULL
allowed_verbs(pr, path_to_find = "/barret/") # NULL
allowed_verbs(pr, path_to_find = "/barret/wrong") # NULL
####################
is_405 <- function(pr, path_to_find, verb_to_find) {
verbs_allowed <- allowed_verbs(pr, path_to_find)
# nothing found, not 405
if (length(verbs_allowed) == 0) return(FALSE)
!(verb_to_find %in% verbs_allowed)
}
is_405(pr, path_to_find = "/barret/test", "GET") # FALSE
is_405(pr, path_to_find = "/barret/test", "POST") # TRUE
is_405(pr, path_to_find = "/subroute/not_found") # FALSE Will need a new method (as you said) to match the path. # plumber-step.R
# PlumberEndpoint public defs
#' @description ability to serve request
#' @param req a request object
#' @return a logical. `TRUE` when endpoint can serve request.
canServe = function(req){
req$REQUEST_METHOD %in% self$verbs && self$matchesRoute(req$PATH_INFO)
},
#' @description determines if route matches requested path
#' @param path a url path
#' @return a logical. `TRUE` when endpoint matches the requested path.
matchesPath = function(path) {
!is.na(stri_match_first_regex(path, private$regex$regex)[1,1])
}, Untested 404 handler update... if (is_405(req$pr, req$PATH_INFO, req$REQUEST_METHOD)) {
res$status <- 405L
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Allow
res$setHeader("Allow", paste(req$verbsAllowed, collapse = ", "))
return(list(error = "405 - Method Not Allowed"))
} ...woot |
(done with updates in the above comment) |
pr is not a value of req, did you expect it to be or should I add it? |
Sorry. It is currently not implemented. See #310 Want to add it to this PR? Or can make separate PR |
The Line 584 in 038e0bc |
I added it here : Line 814 in 038e0bc
|
Im finishing up, just need to fix test because we use a mock req with make_req that does not have a router |
Co-authored-by: Barret Schloerke <barret@rstudio.com>
@meztez Is this PR ready for review / merging? |
@meztez Is this PR ready for review / merging? |
@schloerke yes |
Co-authored-by: Carson Sievert <cpsievert1@gmail.com>
Co-authored-by: Carson Sievert <cpsievert1@gmail.com>
Co-authored-by: Carson Sievert <cpsievert1@gmail.com>
Co-authored-by: Carson Sievert <cpsievert1@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM pending test
Fixes #493
Fixes #310
PR task list:
devtools::document()