Skip to main content

Request

Struct Request 

Source
pub struct Request<'r> { /* private fields */ }
Expand description

The request as gates and handlers read it: the parts web-net has checked (the host matched a site, the path is canonical) and the raw request underneath.

use web_net::{App, get};

let app = App::builder()
    .route(get("/", |cx| {
        let req = cx.request();
        let line = format!("{} {}", req.host(), req.path());
        cx.text(200, &line)
    }))
    .build()?;
let r = serve_net::testing::respond(&app, b"GET / HTTP/1.1\r\nHost: localhost\r\n\r\n");
assert_eq!(r.text(), "localhost /");

Implementations§

Source§

impl<'r> Request<'r>

Source

pub fn method(&self) -> Method

The method.

use serve_net::Method;
use web_net::{App, post};

let app = App::builder()
    .route(post("/", |cx| {
        let post = cx.request().method() == Method::Post;
        cx.text(200, if post { "post" } else { "other" })
    }).csrf_exempt("example"))
    .build()?;
let r = serve_net::testing::respond(&app, b"POST / HTTP/1.1\r\nHost: localhost\r\nContent-Length: 0\r\n\r\n");
assert_eq!(r.text(), "post");
Source

pub fn path(&self) -> &'r str

The canonical path inside the site: the base path removed, percent escapes in their one canonical form. / for the site root.

use web_net::{App, get};

let app = App::builder()
    .base("/app")
    .route(get("/about", |cx| cx.text(200, cx.request().path())))
    .build()?;
let r = serve_net::testing::respond(&app, b"GET /app/about HTTP/1.1\r\nHost: localhost\r\n\r\n");
assert_eq!(r.text(), "/about");
Source

pub fn query(&self) -> Option<&'r str>

The query after ?, as received (validated by the parser, not decoded).

use web_net::{App, get};

let app = App::builder()
    .route(get("/search", |cx| cx.text(200, cx.request().query().unwrap_or(""))))
    .build()?;
let r = serve_net::testing::respond(&app, b"GET /search?q=red+shoes HTTP/1.1\r\nHost: localhost\r\n\r\n");
assert_eq!(r.text(), "q=red+shoes"); // not decoded
Source

pub fn host(&self) -> &'r str

The host the request named, as received (empty for an HTTP/1.0 request without one). It matched one of the site’s hosts, unless the site accepts any host.

use web_net::{App, get};

let app = App::builder()
    .route(get("/", |cx| cx.text(200, cx.request().host())))
    .build()?;
let r = serve_net::testing::respond(&app, b"GET / HTTP/1.1\r\nHost: localhost\r\n\r\n");
assert_eq!(r.text(), "localhost");
Source

pub fn header(&self, name: &str) -> Option<&'r [u8]>

The first value of a field.

use web_net::{App, get};

let app = App::builder()
    .route(get("/", |cx| {
        let accept = cx.request().header("accept").unwrap_or(b"*/*");
        cx.bytes(200, "text/plain", accept)
    }))
    .build()?;
let r = serve_net::testing::respond(&app, b"GET / HTTP/1.1\r\nHost: localhost\r\nAccept: text/html\r\n\r\n");
assert_eq!(r.text(), "text/html");
Source

pub fn header_str(&self, name: &str) -> Option<&'r str>

The first value of a field, if it is UTF-8.

use web_net::{App, get};

let app = App::builder()
    .route(get("/", |cx| {
        let agent = cx.request().header_str("user-agent").unwrap_or("unknown");
        cx.text(200, agent)
    }))
    .build()?;
let r = serve_net::testing::respond(&app, b"GET / HTTP/1.1\r\nHost: localhost\r\nUser-Agent: demo/1\r\n\r\n");
assert_eq!(r.text(), "demo/1");
Source

pub fn cookie(&self, name: &str) -> Result<Option<&'r str>, Ambiguous>

The value of the cookie name, read with cookie-net. Ok(None) when there is no such cookie.

use web_net::{App, get};

let app = App::builder()
    .route(get("/", |cx| {
        let theme = cx.request().cookie("theme").ok().flatten().unwrap_or("light");
        cx.text(200, theme)
    }))
    .build()?;
let r = serve_net::testing::respond(&app, b"GET / HTTP/1.1\r\nHost: localhost\r\nCookie: theme=dark\r\n\r\n");
assert_eq!(r.text(), "dark");
§Errors

Ambiguous when the name appears twice, in one Cookie field or across several (a sign of cookie tossing, never resolved by picking one), or when the fields together are longer than cookie-net’s limit. Several Cookie fields are read as one header: HTTP/2 and HTTP/3 send the cookie as crumbs (RFC 9113 section 8.2.3).

Source

pub fn client(&self) -> &'r ClientInfo

The client, as serve-net established it (the real address behind a trusted proxy).

use web_net::{App, get};

let app = App::builder()
    .route(get("/", |cx| {
        let ip = cx.request().client().addr().map(|a| a.to_string()).unwrap_or_default();
        cx.text(200, &ip)
    }))
    .build()?;
// serve-net's test client connects from 127.0.0.1.
let r = serve_net::testing::respond(&app, b"GET / HTTP/1.1\r\nHost: localhost\r\n\r\n");
assert_eq!(r.text(), "127.0.0.1");
Source

pub fn scheme(&self) -> Scheme

https when the request came over TLS (or from a trusted proxy that said so).

use web_net::{App, get};

let app = App::builder()
    .route(get("/", |cx| cx.text(200, cx.request().scheme().as_str())))
    .build()?;
let r = serve_net::testing::respond(&app, b"GET / HTTP/1.1\r\nHost: localhost\r\n\r\n");
assert_eq!(r.text(), "http");
Source

pub fn route(&self) -> Option<&'r str>

The pattern of the matched route (/users/:id), once routing ran.

use web_net::{App, get};

let app = App::builder()
    .route(get("/users/:id", |cx| cx.text(200, cx.request().route().unwrap_or(""))))
    .build()?;
let r = serve_net::testing::respond(&app, b"GET /users/7 HTTP/1.1\r\nHost: localhost\r\n\r\n");
assert_eq!(r.text(), "/users/:id");
Source

pub fn id(&self) -> RequestId

The request’s reference.

use web_net::{App, get};

let app = App::builder()
    .route(get("/", |cx| {
        let same = cx.request().id() == cx.id();
        cx.text(200, if same { "same" } else { "different" })
    }))
    .build()?;
let r = serve_net::testing::respond(&app, b"GET / HTTP/1.1\r\nHost: localhost\r\n\r\n");
assert_eq!(r.text(), "same");
Source

pub fn envelope(&self) -> &'r Envelope

serve-net’s facts about the request.

use web_net::{App, get};

let app = App::builder()
    .route(get("/", |cx| {
        let seq = cx.request().envelope().seq().get().to_string();
        cx.text(200, &seq)
    }))
    .build()?;
let r = serve_net::testing::respond(&app, b"GET / HTTP/1.1\r\nHost: localhost\r\n\r\n");
assert_eq!(r.text(), "1");
Source

pub fn raw(&self) -> &'r HttpRequest<'r>

The raw request: the target as received, every field, the body.

use web_net::{App, get};

let app = App::builder()
    .route(get("/page", |cx| cx.text(200, cx.request().raw().head().target())))
    .build()?;
let r = serve_net::testing::respond(&app, b"GET /page?x=1 HTTP/1.1\r\nHost: localhost\r\n\r\n");
assert_eq!(r.text(), "/page?x=1");

Trait Implementations§

Source§

impl<'r> Clone for Request<'r>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'r> Copy for Request<'r>

Source§

impl Debug for Request<'_>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'r> Forget for Request<'r>

§

impl<'r> Freeze for Request<'r>

§

impl<'r> Move for Request<'r>

§

impl<'r> RefUnwindSafe for Request<'r>

§

impl<'r> Send for Request<'r>

§

impl<'r> Sync for Request<'r>

§

impl<'r> Unpin for Request<'r>

§

impl<'r> UnsafeUnpin for Request<'r>

§

impl<'r> UnwindSafe for Request<'r>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.