Struct trillium_testing::prelude::Conn
source · pub struct Conn { /* private fields */ }
Expand description
§A Trillium HTTP connection.
A Conn represents both the request and response of a http connection, as well as any application state that is associated with that connection.
§with_{attribute}
naming convention
A convention that is used throughout trillium is that any interface
that is named with_{attribute}
will take ownership of the conn, set
the attribute and return the conn, enabling chained calls like:
struct MyState(&'static str);
async fn handler(mut conn: trillium::Conn) -> trillium::Conn {
conn.with_response_header("content-type", "text/plain")
.with_state(MyState("hello"))
.with_body("hey there")
.with_status(418)
}
use trillium_testing::prelude::*;
assert_response!(
get("/").on(&handler),
Status::ImATeapot,
"hey there",
"content-type" => "text/plain"
);
If you need to set a property on the conn without moving it,
set_{attribute}
associated functions will be your huckleberry, as is
conventional in other rust projects.
§State
Every trillium Conn contains a state type which is a set that contains
at most one element for each type. State is the primary way that
handlers attach data to a conn as it passes through a tuple
handler. State access should generally be implemented by libraries
using a private type and exposed with a ConnExt
trait. See library
patterns for more
elaboration and examples.
§In relation to trillium_http::Conn
trillium::Conn
is currently implemented as an abstraction on top of a
trillium_http::Conn
. In particular, trillium::Conn
boxes the
transport using a BoxedTransport
so that application code can be written without transport
generics. See Transport
for further
reading on this.
Implementations§
source§impl Conn
impl Conn
sourcepub fn ok(self, body: impl Into<Body>) -> Conn
pub fn ok(self, body: impl Into<Body>) -> Conn
Conn::ok
is a convenience function for the common pattern of
setting a body and a 200 status in one call. It is exactly
identical to conn.with_status(200).with_body(body).halt()
use trillium::Conn;
use trillium_testing::prelude::*;
let mut conn = get("/").on(&|conn: Conn| async move { conn.ok("hello") });
assert_body!(&mut conn, "hello");
assert_status!(&conn, 200);
assert!(conn.is_halted());
sourcepub fn status(&self) -> Option<Status>
pub fn status(&self) -> Option<Status>
returns the response status for this Conn
, if it has been set.
use trillium_testing::prelude::*;
let mut conn = get("/").on(&());
assert!(conn.status().is_none());
conn.set_status(200);
assert_eq!(conn.status().unwrap(), Status::Ok);
sourcepub fn set_status(&mut self, status: impl TryInto<Status>)
pub fn set_status(&mut self, status: impl TryInto<Status>)
assigns a status to this response. see Conn::status
for example usage
sourcepub fn with_status(self, status: impl TryInto<Status>) -> Conn
pub fn with_status(self, status: impl TryInto<Status>) -> Conn
sets the response status for this Conn
and returns it. note that
this does not set the halted status.
use trillium_testing::prelude::*;
let conn = get("/").on(&|conn: Conn| async move {
conn.with_status(418)
});
let status = conn.status().unwrap();
assert_eq!(status, Status::ImATeapot);
assert_eq!(status, 418);
assert!(!conn.is_halted());
sourcepub fn with_body(self, body: impl Into<Body>) -> Conn
pub fn with_body(self, body: impl Into<Body>) -> Conn
Sets the response body from any impl Into<Body>
and returns the
Conn
for fluent chaining. Note that this does not set the response
status or halted. See Conn::ok
for a function that does both
of those.
use trillium_testing::prelude::*;
let conn = get("/").on(&|conn: Conn| async move {
conn.with_body("hello")
});
assert_eq!(conn.response_len(), Some(5));
sourcepub fn set_body(&mut self, body: impl Into<Body>)
pub fn set_body(&mut self, body: impl Into<Body>)
Sets the response body from any impl Into<Body>
. Note that this does not set the response
status or halted.
use trillium_testing::prelude::*;
let mut conn = get("/").on(&());
conn.set_body("hello");
assert_eq!(conn.response_len(), Some(5));
sourcepub fn take_response_body(&mut self) -> Option<Body>
pub fn take_response_body(&mut self) -> Option<Body>
Removes the response body from the Conn
use trillium_testing::prelude::*;
let mut conn = get("/").on(&());
conn.set_body("hello");
let mut body = conn.take_response_body().unwrap();
assert_eq!(body.len(), Some(5));
assert_eq!(conn.response_len(), None);
sourcepub fn response_body(&self) -> Option<&Body>
pub fn response_body(&self) -> Option<&Body>
Borrows the response body from the Conn
use trillium_testing::prelude::*;
let mut conn = get("/").on(&());
conn.set_body("hello");
let body = conn.response_body().unwrap();
assert_eq!(body.len(), Some(5));
assert!(body.is_static());
assert_eq!(body.static_bytes(), Some(&b"hello"[..]));
sourcepub fn state<T>(&self) -> Option<&T>where
T: 'static,
pub fn state<T>(&self) -> Option<&T>where
T: 'static,
Attempts to retrieve a &T from the state set
use trillium_testing::prelude::*;
struct Hello;
let mut conn = get("/").on(&());
assert!(conn.state::<Hello>().is_none());
conn.insert_state(Hello);
assert!(conn.state::<Hello>().is_some());
sourcepub fn state_mut<T>(&mut self) -> Option<&mut T>where
T: 'static,
pub fn state_mut<T>(&mut self) -> Option<&mut T>where
T: 'static,
Attempts to retrieve a &mut T from the state set
sourcepub fn set_state<T>(&mut self, state: T) -> Option<T>
👎Deprecated: use Conn::insert_state
pub fn set_state<T>(&mut self, state: T) -> Option<T>
see [insert_state
]
sourcepub fn insert_state<T>(&mut self, state: T) -> Option<T>
pub fn insert_state<T>(&mut self, state: T) -> Option<T>
Inserts a new type into the state set. See Conn::state
for an example.
Returns the previously-set instance of this type, if any
sourcepub fn with_state<T>(self, state: T) -> Conn
pub fn with_state<T>(self, state: T) -> Conn
Puts a new type into the state set and returns the
Conn
. this is useful for fluent chaining
sourcepub fn take_state<T>(&mut self) -> Option<T>
pub fn take_state<T>(&mut self) -> Option<T>
Removes a type from the state set and returns it, if present
sourcepub fn mut_state_or_insert_with<T, F>(&mut self, default: F) -> &mut T
pub fn mut_state_or_insert_with<T, F>(&mut self, default: F) -> &mut T
Either returns the current &mut T from the state set, or inserts a new one with the provided default function and returns a mutable reference to it
sourcepub async fn request_body(&mut self) -> ReceivedBody<'_, BoxedTransport>
pub async fn request_body(&mut self) -> ReceivedBody<'_, BoxedTransport>
Returns a ReceivedBody
that references this Conn
. The Conn
retains all data and holds the singular transport, but the
ReceivedBody
provides an interface to read body content.
See also: Conn::request_body_string
for a convenience function
when the content is expected to be utf8.
§Examples
use trillium_testing::prelude::*;
let mut conn = get("/").with_request_body("request body").on(&());
let request_body = conn.request_body().await;
assert_eq!(request_body.content_length(), Some(12));
assert_eq!(request_body.read_string().await.unwrap(), "request body");
sourcepub async fn request_body_string(&mut self) -> Result<String, Error>
pub async fn request_body_string(&mut self) -> Result<String, Error>
Convenience function to read the content of a request body as a String
.
§Errors
This will return an error variant if either there is an IO failure on the underlying transport or if the body content is not a utf8 string.
§Examples
use trillium_testing::prelude::*;
let mut conn = get("/").with_request_body("request body").on(&());
assert_eq!(conn.request_body_string().await.unwrap(), "request body");
sourcepub fn response_len(&self) -> Option<u64>
pub fn response_len(&self) -> Option<u64>
if there is a response body for this conn and it has a known fixed length, it is returned from this function
use trillium_testing::prelude::*;
let mut conn = get("/").on(&|conn: trillium::Conn| async move {
conn.with_body("hello")
});
assert_eq!(conn.response_len(), Some(5));
sourcepub fn method(&self) -> Method
pub fn method(&self) -> Method
returns the request method for this conn.
use trillium_testing::prelude::*;
let mut conn = get("/").on(&());
assert_eq!(conn.method(), Method::Get);
sourcepub fn headers_mut(&mut self) -> &mut Headers
👎Deprecated: use Conn::response_headers_mut
pub fn headers_mut(&mut self) -> &mut Headers
sourcepub fn response_headers(&self) -> &Headers
pub fn response_headers(&self) -> &Headers
borrow the response headers
sourcepub fn response_headers_mut(&mut self) -> &mut Headers
pub fn response_headers_mut(&mut self) -> &mut Headers
mutably borrow the response headers
sourcepub fn request_headers(&self) -> &Headers
pub fn request_headers(&self) -> &Headers
borrow the request headers
sourcepub fn request_headers_mut(&mut self) -> &mut Headers
pub fn request_headers_mut(&mut self) -> &mut Headers
mutably borrow request headers
sourcepub fn with_response_header(
self,
header_name: impl Into<HeaderName<'static>>,
header_value: impl Into<HeaderValues>,
) -> Conn
pub fn with_response_header( self, header_name: impl Into<HeaderName<'static>>, header_value: impl Into<HeaderValues>, ) -> Conn
insert a header name and value/values into the response headers
and return the conn. for a slight performance improvement, use a
KnownHeaderName
as the first argument instead of a
str.
use trillium_testing::prelude::*;
let mut conn = get("/").on(&|conn: trillium::Conn| async move {
conn.with_response_header("content-type", "application/html")
});
sourcepub fn with_header(
self,
header_name: impl Into<HeaderName<'static>>,
header_value: impl Into<HeaderValues>,
) -> Conn
👎Deprecated: use Conn::with_response_header
pub fn with_header( self, header_name: impl Into<HeaderName<'static>>, header_value: impl Into<HeaderValues>, ) -> Conn
Prefer [with_response_header
]
sourcepub fn path(&self) -> &str
pub fn path(&self) -> &str
returns the path for this request. note that this may not represent the entire http request path if running nested routers.
sourcepub fn querystring(&self) -> &str
pub fn querystring(&self) -> &str
returns query part of the request path
use trillium_testing::prelude::*;
let conn = get("/a/b?c&d=e").on(&());
assert_eq!(conn.querystring(), "c&d=e");
let conn = get("/a/b").on(&());
assert_eq!(conn.querystring(), "");
§Parsing
Trillium does not include a querystring parsing library, as there is no universal standard for querystring encodings of arrays, but several library options exist, inluding:
QueryStrong
(by the author of trillium)serde_qs
querystring
serde_querystring
sourcepub fn halt(self) -> Conn
pub fn halt(self) -> Conn
sets the halted
attribute of this conn, preventing later
processing in a given tuple handler. returns
the conn for fluent chaining
use trillium_testing::prelude::*;
let mut conn = get("/").on(&|conn: trillium::Conn| async move {
conn.halt()
});
assert!(conn.is_halted());
sourcepub fn set_halted(&mut self, halted: bool)
pub fn set_halted(&mut self, halted: bool)
sets the halted
attribute of this conn. see Conn::halt
.
use trillium_testing::prelude::*;
let mut conn = get("/").on(&());
assert!(!conn.is_halted());
conn.set_halted(true);
assert!(conn.is_halted());
sourcepub const fn is_halted(&self) -> bool
pub const fn is_halted(&self) -> bool
retrieves the halted state of this conn. see Conn::halt
.
sourcepub fn is_secure(&self) -> bool
pub fn is_secure(&self) -> bool
predicate function to indicate whether the connection is
secure. note that this does not necessarily indicate that the
transport itself is secure, as it may indicate that
trillium_http
is behind a trusted reverse proxy that has
terminated tls and provided appropriate headers to indicate
this.
sourcepub fn start_time(&self) -> Instant
pub fn start_time(&self) -> Instant
The [Instant
] that the first header bytes for this conn were
received, before any processing or parsing has been performed.
sourcepub const fn inner(&self) -> &Conn<BoxedTransport>
pub const fn inner(&self) -> &Conn<BoxedTransport>
returns an immutable reference to the inner
trillium_http::Conn
. please open an issue if you need to do
this in application code.
stability note: hopefully this can go away at some point, but
for now is an escape hatch in case trillium_http::Conn
presents interfaces that cannot be reached otherwise.
sourcepub fn inner_mut(&mut self) -> &mut Conn<BoxedTransport>
pub fn inner_mut(&mut self) -> &mut Conn<BoxedTransport>
returns a mutable reference to the inner
trillium_http::Conn
. please open an issue if you need to
do this in application code.
stability note: hopefully this can go away at some point, but
for now is an escape hatch in case trillium_http::Conn
presents interfaces that cannot be reached otherwise.
sourcepub fn into_inner<T>(self) -> Conn<T>where
T: Transport,
pub fn into_inner<T>(self) -> Conn<T>where
T: Transport,
transforms this trillium::Conn
into a trillium_http::Conn
with the specified transport type. Please note that this will
panic if you attempt to downcast from trillium’s boxed
transport into the wrong transport type. Also note that this
is a lossy conversion, dropping the halted state and any
nested router path data.
§Panics
This will panic if you attempt to downcast to the wrong Transport type.
sourcepub fn peer_ip(&self) -> Option<IpAddr>
pub fn peer_ip(&self) -> Option<IpAddr>
retrieves the remote ip address for this conn, if available.
sourcepub fn set_peer_ip(&mut self, peer_ip: Option<IpAddr>)
pub fn set_peer_ip(&mut self, peer_ip: Option<IpAddr>)
sets the remote ip address for this conn.
sourcepub fn push_path(&mut self, path: String)
pub fn push_path(&mut self, path: String)
for router implementations. pushes a route segment onto the path
sourcepub async fn cancel_on_disconnect<'a, Fut>(
&'a mut self,
fut: Fut,
) -> Option<<Fut as Future>::Output>
pub async fn cancel_on_disconnect<'a, Fut>( &'a mut self, fut: Fut, ) -> Option<<Fut as Future>::Output>
Cancels and drops the future if reading from the transport results in an error or empty read
If the client disconnects from the conn’s transport, this function will return None. If the future completes without disconnection, this future will return Some containing the output of the future.
The use of this method is not advised if your connected http client employs pipelining (rarely seen in the wild), as it will buffer an unbounded number of requests
Note that the inner future cannot borrow conn, so you will need to clone or take any information needed to execute the future prior to executing this method.
§Example
async fn something_slow_and_cancel_safe() -> String {
String::from("this was not actually slow")
}
async fn handler(mut conn: Conn) -> Conn {
match conn.cancel_on_disconnect(async {
something_slow_and_cancel_safe().await
}).await {
Some(returned_body) => conn.ok(returned_body),
None => conn
}
}
sourcepub async fn is_disconnected(&mut self) -> bool
pub async fn is_disconnected(&mut self) -> bool
Check if the transport is connected by testing attempting to read from the transport
§Example
This is best to use at appropriate points in a long-running handler, like:
async fn handler(mut conn: Conn) -> Conn {
for _ in 0..100 {
if conn.is_disconnected().await {
return conn;
}
something_slow_but_not_cancel_safe().await;
}
conn.ok("ok!")
}