Struct trillium_http::Conn
source · pub struct Conn<Transport> { /* private fields */ }
Expand description
A http connection
Unlike in other rust http implementations, this struct represents both the request and the response, and holds the transport over which the response will be sent.
Implementations§
source§impl<Transport> Conn<Transport>
impl<Transport> Conn<Transport>
sourcepub async fn map<F, Fut>(
transport: Transport,
stopper: Stopper,
handler: F,
) -> Result<Option<Upgrade<Transport>>>
pub async fn map<F, Fut>( transport: Transport, stopper: Stopper, handler: F, ) -> Result<Option<Upgrade<Transport>>>
read any number of new Conn
s from the transport and call the
provided handler function until either the connection is closed or
an upgrade is requested. A return value of Ok(None) indicates a
closed connection, while a return value of Ok(Some(upgrade))
represents an upgrade.
Provides a default HttpConfig
See the documentation for Conn
for a full example.
§Errors
This will return an error variant if:
- there is an io error when reading from the underlying transport
- headers are too long
- we are unable to parse some aspect of the request
- the request is an unsupported http version
- we cannot make sense of the headers, such as if there is a
content-length
header as well as atransfer-encoding: chunked
header.
sourcepub async fn map_with_config<F, Fut>(
http_config: HttpConfig,
transport: Transport,
stopper: Stopper,
handler: F,
) -> Result<Option<Upgrade<Transport>>>
pub async fn map_with_config<F, Fut>( http_config: HttpConfig, transport: Transport, stopper: Stopper, handler: F, ) -> Result<Option<Upgrade<Transport>>>
read any number of new Conn
s from the transport and call the
provided handler function until either the connection is closed or
an upgrade is requested. A return value of Ok(None) indicates a
closed connection, while a return value of Ok(Some(upgrade))
represents an upgrade.
See the documentation for Conn
for a full example.
§Errors
This will return an error variant if:
- there is an io error when reading from the underlying transport
- headers are too long
- we are unable to parse some aspect of the request
- the request is an unsupported http version
- we cannot make sense of the headers, such as if there is a
content-length
header as well as atransfer-encoding: chunked
header.
sourcepub fn state(&self) -> &StateSet
pub fn state(&self) -> &StateSet
returns a read-only reference to the state typemap for this conn
stability note: this is not unlikely to be removed at some
point, as this may end up being more of a trillium concern
than a trillium_http
concern
sourcepub fn state_mut(&mut self) -> &mut StateSet
pub fn state_mut(&mut self) -> &mut StateSet
returns a mutable reference to the state typemap for this conn
stability note: this is not unlikely to be removed at some
point, as this may end up being more of a trillium concern
than a trillium_http
concern
sourcepub fn request_headers(&self) -> &Headers
pub fn request_headers(&self) -> &Headers
returns a reference to the request headers
sourcepub fn request_headers_mut(&mut self) -> &mut Headers
pub fn request_headers_mut(&mut self) -> &mut Headers
returns a mutable reference to the response headers
sourcepub fn response_headers_mut(&mut self) -> &mut Headers
pub fn response_headers_mut(&mut self) -> &mut Headers
returns a mutable reference to the response headers
sourcepub fn response_headers(&self) -> &Headers
pub fn response_headers(&self) -> &Headers
returns a reference to the response headers
sourcepub fn set_status(&mut self, status: impl TryInto<Status>)
pub fn set_status(&mut self, status: impl TryInto<Status>)
sets the http status code from any TryInto<Status>
.
assert!(conn.status().is_none());
conn.set_status(200); // a status can be set as a u16
assert_eq!(conn.status().unwrap(), Status::Ok);
conn.set_status(Status::ImATeapot); // or as a Status
assert_eq!(conn.status().unwrap(), Status::ImATeapot);
sourcepub fn status(&self) -> Option<Status>
pub fn status(&self) -> Option<Status>
retrieves the current response status code for this conn, if
it has been set. See Conn::set_status
for example usage.
sourcepub fn path(&self) -> &str
pub fn path(&self) -> &str
retrieves the path part of the request url, up to and excluding any query component
let mut conn = Conn::new_synthetic(Method::Get, "/some/path?and&a=query", ());
assert_eq!(conn.path(), "/some/path");
sourcepub fn path_and_query(&self) -> &str
pub fn path_and_query(&self) -> &str
retrieves the combined path and any query
sourcepub fn querystring(&self) -> &str
pub fn querystring(&self) -> &str
retrieves the query component of the path
let mut conn = Conn::new_synthetic(Method::Get, "/some/path?and&a=query", ());
assert_eq!(conn.querystring(), "and&a=query");
let mut conn = Conn::new_synthetic(Method::Get, "/some/path", ());
assert_eq!(conn.querystring(), "");
sourcepub fn set_response_body(&mut self, body: impl Into<Body>)
pub fn set_response_body(&mut self, body: impl Into<Body>)
Sets the response body to anything that is impl Into<Body>
.
conn.set_response_body("hello");
conn.set_response_body(String::from("hello"));
conn.set_response_body(vec![99, 97, 116]);
sourcepub fn response_body(&self) -> Option<&Body>
pub fn response_body(&self) -> Option<&Body>
returns a reference to the current response body, if it has been set
sourcepub fn take_response_body(&mut self) -> Option<Body>
pub fn take_response_body(&mut self) -> Option<Body>
remove the response body from this conn and return it
assert!(conn.response_body().is_none());
conn.set_response_body("hello");
assert!(conn.response_body().is_some());
let body = conn.take_response_body();
assert!(body.is_some());
assert!(conn.response_body().is_none());
sourcepub fn method(&self) -> Method
pub fn method(&self) -> Method
returns the http method for this conn’s request.
let mut conn = Conn::new_synthetic(Method::Get, "/some/path?and&a=query", ());
assert_eq!(conn.method(), Method::Get);
sourcepub fn set_method(&mut self, method: Method)
pub fn set_method(&mut self, method: Method)
overrides the http method for this conn
sourcepub fn http_version(&self) -> Version
pub fn http_version(&self) -> Version
returns the http version for this conn.
sourcepub async fn cancel_on_disconnect<'a, Fut>(
&'a mut self,
fut: Fut,
) -> Option<Fut::Output>
pub async fn cancel_on_disconnect<'a, Fut>( &'a mut self, fut: Fut, ) -> Option<Fut::Output>
Cancels and drops the future if reading from the transport results in an error or empty read
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 one byte at a time
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<T>(mut conn: Conn<T>) -> Conn<T>
where
T: AsyncRead + AsyncWrite + Send + Sync + Unpin + 'static
{
let Some(returned_body) = conn.cancel_on_disconnect(async {
something_slow_and_cancel_safe().await
}).await else { return conn; };
conn.set_response_body(returned_body);
conn.set_status(200);
conn
}
sourcepub async fn is_disconnected(&mut self) -> bool
pub async fn is_disconnected(&mut self) -> bool
Check if the transport is connected by attempting to read from the transport
§Example
This is best to use at appropriate points in a long-running handler, like:
async fn handler<T>(mut conn: Conn<T>) -> Conn<T>
where
T: AsyncRead + AsyncWrite + Send + Sync + Unpin + 'static
{
for _ in 0..100 {
if conn.is_disconnected().await {
return conn;
}
something_slow_but_not_cancel_safe().await;
}
conn.set_status(200);
conn
}
sourcepub fn request_encoding(&self) -> &'static Encoding
pub fn request_encoding(&self) -> &'static Encoding
returns the [encoding_rs::Encoding
] for this request, as
determined from the mime-type charset, if available
let mut conn = Conn::new_synthetic(Method::Get, "/", ());
assert_eq!(conn.request_encoding(), encoding_rs::WINDOWS_1252); // the default
conn.request_headers_mut().insert("content-type", "text/plain;charset=utf-16");
assert_eq!(conn.request_encoding(), encoding_rs::UTF_16LE);
sourcepub fn response_encoding(&self) -> &'static Encoding
pub fn response_encoding(&self) -> &'static Encoding
returns the [encoding_rs::Encoding
] for this response, as
determined from the mime-type charset, if available
let mut conn = Conn::new_synthetic(Method::Get, "/", ());
assert_eq!(conn.response_encoding(), encoding_rs::WINDOWS_1252); // the default
conn.response_headers_mut().insert("content-type", "text/plain;charset=utf-16");
assert_eq!(conn.response_encoding(), encoding_rs::UTF_16LE);
sourcepub async fn request_body(&mut self) -> ReceivedBody<'_, Transport>
pub async fn request_body(&mut self) -> ReceivedBody<'_, Transport>
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
let mut conn = Conn::new_synthetic(Method::Get, "/", "hello");
let request_body = conn.request_body().await;
assert_eq!(request_body.content_length(), Some(5));
assert_eq!(request_body.read_string().await.unwrap(), "hello");
sourcepub fn stopper(&self) -> Stopper
pub fn stopper(&self) -> Stopper
returns a clone of the stopper::Stopper
for this Conn. use
this to gracefully stop long-running futures and streams
inside of handler functions
sourcepub async fn new(
transport: Transport,
bytes: Vec<u8>,
stopper: Stopper,
) -> Result<Self>
pub async fn new( transport: Transport, bytes: Vec<u8>, stopper: Stopper, ) -> Result<Self>
§Create a new Conn
This function creates a new conn from the provided
Transport
, as well as any
bytes that have already been read from the transport, and a
Stopper
instance that will be used to signal graceful
shutdown.
§Errors
This will return an error variant if:
- there is an io error when reading from the underlying transport
- headers are too long
- we are unable to parse some aspect of the request
- the request is an unsupported http version
- we cannot make sense of the headers, such as if there is a
content-length
header as well as atransfer-encoding: chunked
header.
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 set_secure(&mut self, secure: bool)
pub fn set_secure(&mut self, secure: bool)
set whether the connection should be considered 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 finalize_headers(&mut self)
pub fn finalize_headers(&mut self)
calculates any auto-generated headers for this conn prior to sending it
sourcepub fn after_send<F>(&mut self, after_send: F)
pub fn after_send<F>(&mut self, after_send: F)
Registers a function to call after the http response has been
completely transferred. Please note that this is a sync function
and should be computationally lightweight. If your application
needs additional async processing, use your runtime’s task spawn
within this hook. If your library needs additional async
processing in an after_send
hook, please open an issue. This hook
is currently designed for simple instrumentation and logging, and
should be thought of as equivalent to a Drop hook.
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 fn map_transport<T: AsyncRead + AsyncWrite + Send + Sync + Unpin + 'static>(
self,
f: impl Fn(Transport) -> T,
) -> Conn<T>
pub fn map_transport<T: AsyncRead + AsyncWrite + Send + Sync + Unpin + 'static>( self, f: impl Fn(Transport) -> T, ) -> Conn<T>
applies a mapping function from one transport to another. This is particularly useful for boxing the transport. unless you’re sure this is what you’re looking for, you probably don’t want to be using this
sourcepub fn transport(&self) -> &Transport
pub fn transport(&self) -> &Transport
Get a reference to the transport.
sourcepub fn transport_mut(&mut self) -> &mut Transport
pub fn transport_mut(&mut self) -> &mut Transport
Get a mutable reference to the transport.
This should only be used to call your own custom methods on the transport that do not read or write any data. Calling any method that reads from or writes to the transport will disrupt the HTTP protocol. If you’re looking to transition from HTTP to another protocol, use an HTTP upgrade.
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, if available.
source§impl Conn<Synthetic>
impl Conn<Synthetic>
sourcepub fn new_synthetic(
method: Method,
path: impl Into<String>,
body: impl Into<Synthetic>,
) -> Self
pub fn new_synthetic( method: Method, path: impl Into<String>, body: impl Into<Synthetic>, ) -> Self
Construct a new synthetic conn with provided method, path, and body.
let conn = Conn::new_synthetic(Method::Get, "/", "hello");
assert_eq!(conn.method(), Method::Get);
assert_eq!(conn.path(), "/");
sourcepub fn replace_body(&mut self, body: impl Into<Synthetic>)
pub fn replace_body(&mut self, body: impl Into<Synthetic>)
Replaces the synthetic body. This is intended for testing use.