coap_handler/handler.rs
1/// A minimal stateless testing CoAP server interface.
2use coap_message::{MinimalWritableMessage, MutableWritableMessage, ReadableMessage};
3
4/// A CoAP request handler. This gets called by a CoAP server implementation that the handler is
5/// assigned to; the server has the handler [processes the request's
6/// data](Self::extract_request_data) into a RequestData structure, possibly calls [asks for the
7/// expected length](Self::estimate_length) before allocating a response message, and then asks the
8/// handler to [populate the allocated response message](Self::build_response) with data persisted
9/// in the RequestData structure.
10///
11/// Both data extraction and response building are fallible operations. In the error case, it is up
12/// to the CoAP server implementation to reset the message into a state into which the error can be
13/// [rendered](coap_message::error::RenderableOnMinimal::render). There is currently no trait
14/// method in [`coap_message`] that describes how that would be done, but the CoAP implementation
15/// knows the concrete type and can use its methods directly.
16pub trait Handler {
17 /// Type constructed in [`extract_request_data()`](Self::extract_request_data) passed on to
18 /// [`build_response()`](Self::build_response).
19 ///
20 /// This type can usually be made very compact, with exceptions for POST style requests where
21 /// not only do request and response have large payloads, but also both are needed at the same
22 /// time.
23 type RequestData;
24
25 /// Error type for [`extract_request_data()`](Self::extract_request_data).
26 ///
27 /// Typical types to use here are [core::convert::Infallible] (which, due to the possibility of
28 /// unknown critical CoAP options, is only practical when their presence is carried in the
29 /// extracted data) or types provided by libraries (eg.
30 /// [coap-handler-implementations::Error](https://docs.rs/coap-handler-implementations/0.5.0/coap_handler_implementations/struct.Error.html)).
31 type ExtractRequestError: core::fmt::Debug + coap_message::error::RenderableOnMinimal;
32 /// Error type for [writing response data](Self::build_response).
33 ///
34 /// This is generic over writable messages because the most typical errors to show up here are
35 /// generated when writing to the messages. A suitable type here is `M::UnionError`.
36 // FIXME could we carry an error type in here instead of the message? if so, does the same
37 // apply to render?
38 type BuildResponseError<M: MinimalWritableMessage>: core::fmt::Debug
39 + coap_message::error::RenderableOnMinimal;
40
41 /// Process an incoming request.
42 ///
43 /// Unless the server implementation performs request deduplication, this may be called
44 /// multiple times per request. Whether a server performs request deduplication (and thus the
45 /// handlers need to be idempotent, which is best practice in CoAP anyway) is not expressed in
46 /// the type system.
47 ///
48 /// Effects of requests may already be performed at this step -- to the point where
49 /// [Self::RequestData] is `()` to indicate success.
50 fn extract_request_data<M: ReadableMessage>(
51 &mut self,
52 request: &M,
53 ) -> Result<Self::RequestData, Self::ExtractRequestError>;
54 /// Estimate an upper bound for the number of bytes in the response
55 ///
56 /// Sizes are counted as in UDP after the header, i.e., encoded options plus payload indicator
57 /// plus payload.
58 fn estimate_length(&mut self, request: &Self::RequestData) -> usize;
59 /// Build a response for the request
60 ///
61 /// While this is typically called exactly once per request, it can also be called not at all
62 /// (eg. if a TCP connection was dropped between parsing the request and sending the response)
63 /// or multiple times (if the response was sent in a CON, needed to be retransmitted, and the
64 /// RequestData is Clone).
65 fn build_response<M: MutableWritableMessage>(
66 &mut self,
67 response: &mut M,
68 request: Self::RequestData,
69 ) -> Result<(), Self::BuildResponseError<M>>;
70}