考虑以下warp路由规范:
let read_book_route = warp::path!("book" / Address)
.and(warp::get())
.and(warp::any().map(move || read_book_state.clone()))
.and_then(handler::read_book_handler);
如果URL中提供了一个非Address
, warp会自动返回一个HTTP 405方法不允许的状态码:
$ curl -i http://example.com/book/not_a_valid_address
HTTP/1.1 405 Method Not Allowed
content-type: text/plain; charset=utf-8
content-length: 23
date: Thu, 25 Feb 2021 06:22:20 GMT
HTTP method not allowed
为什么是HTTP 405?为什么不是HTTP 400,或任何其他客户端错误?
path!
可以理解为path()
和param()
的序列,end()
(默认)封顶,根据param()
的文档:
如果该值不能被解析,则返回
404 Not Found
。
然而我猜这是一个Rejection
,这意味着warp将尝试下一个过滤器or
-ed,并获得的拒绝。
由于您不提供最小复制示例并且也不显示您的所有代码,我希望有其他过滤器,并且我不太清楚warp处理如何组合拒绝,我也不知道您是否有例如可以拦截param()
将产生的not_found
的中间recover
,并让其他拒绝优先考虑。
不确定100%(某些上下文缺乏),但可能与此问题相关:https://github.com/seanmonstar/warp/issues/77(它也提出了一些可能的解决方案)
由于过滤器形成了一个树,如果一个分支因拒绝而失败,相邻分支也可以尝试。Warp有拒绝的优先权。MethodNotAllowed
的优先级高于NotFound
。因此,如果路径与NotFound
的一个分支不匹配,由于不同的参数类型,warp
将尝试其他路径-并使用MethodNotAllowed
覆盖拒绝,因为其他分支有其他方法。
您可以使用RUST_LOG=trace cargo run
运行跟踪日志级别的服务器,并检查过滤器匹配是如何执行的。