mirror of https://github.com/fafhrd91/actix-web
implement from request for request parts
This commit is contained in:
parent
75f65fea4f
commit
f608d5c87b
128
src/extract.rs
128
src/extract.rs
|
@ -1,15 +1,22 @@
|
||||||
//! Request extractors
|
//! Request extractors
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
|
convert::Infallible,
|
||||||
|
fmt,
|
||||||
future::Future,
|
future::Future,
|
||||||
|
net::SocketAddr,
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
};
|
};
|
||||||
|
|
||||||
use actix_utils::future::{ready, Ready};
|
use actix_http::http::{Method, Uri, Version};
|
||||||
|
use actix_utils::future::{err, ok, Ready};
|
||||||
use futures_core::ready;
|
use futures_core::ready;
|
||||||
|
|
||||||
use crate::{dev::Payload, Error, HttpRequest};
|
use crate::{
|
||||||
|
dev::{ConnectionInfo, Payload},
|
||||||
|
Error, HttpRequest, ResponseError,
|
||||||
|
};
|
||||||
|
|
||||||
/// Trait implemented by types that can be extracted from request.
|
/// Trait implemented by types that can be extracted from request.
|
||||||
///
|
///
|
||||||
|
@ -218,14 +225,81 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromRequest for Uri {
|
||||||
|
type Error = Infallible;
|
||||||
|
type Future = Ready<Result<Uri, Infallible>>;
|
||||||
|
type Config = ();
|
||||||
|
|
||||||
|
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
|
||||||
|
ok(req.uri().clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromRequest for Version {
|
||||||
|
type Error = Infallible;
|
||||||
|
type Future = Ready<Result<Version, Infallible>>;
|
||||||
|
type Config = ();
|
||||||
|
|
||||||
|
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
|
||||||
|
ok(req.version())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromRequest for Method {
|
||||||
|
type Error = Infallible;
|
||||||
|
type Future = Ready<Result<Method, Infallible>>;
|
||||||
|
type Config = ();
|
||||||
|
|
||||||
|
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
|
||||||
|
ok(req.method().clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromRequest for ConnectionInfo {
|
||||||
|
type Error = Infallible;
|
||||||
|
type Future = Ready<Result<ConnectionInfo, Infallible>>;
|
||||||
|
type Config = ();
|
||||||
|
|
||||||
|
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
|
||||||
|
ok(req.connection_info().clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct MissingPeerAddr;
|
||||||
|
|
||||||
|
impl fmt::Display for MissingPeerAddr {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "Missing peer address.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ResponseError for MissingPeerAddr {}
|
||||||
|
|
||||||
|
impl FromRequest for SocketAddr {
|
||||||
|
type Error = Error;
|
||||||
|
type Future = Ready<Result<SocketAddr, Error>>;
|
||||||
|
type Config = ();
|
||||||
|
|
||||||
|
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
|
||||||
|
match req.peer_addr() {
|
||||||
|
Some(addr) => ok(addr),
|
||||||
|
None => {
|
||||||
|
log::error!("Missing peer address.");
|
||||||
|
err(MissingPeerAddr.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
impl FromRequest for () {
|
impl FromRequest for () {
|
||||||
type Error = Error;
|
type Error = Infallible;
|
||||||
type Future = Ready<Result<(), Error>>;
|
type Future = Ready<Result<(), Infallible>>;
|
||||||
type Config = ();
|
type Config = ();
|
||||||
|
|
||||||
fn from_request(_: &HttpRequest, _: &mut Payload) -> Self::Future {
|
fn from_request(_: &HttpRequest, _: &mut Payload) -> Self::Future {
|
||||||
ready(Ok(()))
|
ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,4 +487,48 @@ mod tests {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(r.is_err());
|
assert!(r.is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[actix_rt::test]
|
||||||
|
async fn test_uri() {
|
||||||
|
let req = TestRequest::default().uri("/foo/bar").to_http_request();
|
||||||
|
let uri = Uri::extract(&req).await.unwrap();
|
||||||
|
assert_eq!(uri.path(), "/foo/bar");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[actix_rt::test]
|
||||||
|
async fn test_version() {
|
||||||
|
let req = TestRequest::default()
|
||||||
|
.version(Version::HTTP_11)
|
||||||
|
.to_http_request();
|
||||||
|
let version = Version::extract(&req).await.unwrap();
|
||||||
|
assert_eq!(version, Version::HTTP_11);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[actix_rt::test]
|
||||||
|
async fn test_method() {
|
||||||
|
let req = TestRequest::default().method(Method::GET).to_http_request();
|
||||||
|
let method = Method::extract(&req).await.unwrap();
|
||||||
|
assert_eq!(method, Method::GET);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[actix_rt::test]
|
||||||
|
async fn test_conn_info() {
|
||||||
|
let req = TestRequest::default()
|
||||||
|
.uri("http://actix.rs/")
|
||||||
|
.to_http_request();
|
||||||
|
let conn_info = ConnectionInfo::extract(&req).await.unwrap();
|
||||||
|
assert_eq!(conn_info.scheme(), "http");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[actix_rt::test]
|
||||||
|
async fn test_peer_addr() {
|
||||||
|
let addr = "127.0.0.1:8080".parse().unwrap();
|
||||||
|
let req = TestRequest::default().peer_addr(addr).to_http_request();
|
||||||
|
let peer_addr = SocketAddr::extract(&req).await.unwrap();
|
||||||
|
assert_eq!(peer_addr, addr);
|
||||||
|
|
||||||
|
let req = TestRequest::default().to_http_request();
|
||||||
|
let res = SocketAddr::extract(&req).await;
|
||||||
|
assert!(res.is_err());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue