pub struct HttpHandler { /* private fields */ }Expand description
The handler that bridges McpRouter to the real Dispatcher.
The port trait belongs to the router, so this type implements it and
declares nothing. There is no second “how to answer a request” here — only
Dispatcher with an HTTP envelope around it.
Implementations§
Source§impl HttpHandler
impl HttpHandler
Sourcepub const fn new(
dispatcher: Arc<Dispatcher>,
sessions: Arc<SessionStore<HttpSession>>,
ceiling: ProtocolVersion,
) -> Self
pub const fn new( dispatcher: Arc<Dispatcher>, sessions: Arc<SessionStore<HttpSession>>, ceiling: ProtocolVersion, ) -> Self
A handler over dispatcher and sessions, gated at ceiling.
Sourcepub const fn ceiling(&self) -> ProtocolVersion
pub const fn ceiling(&self) -> ProtocolVersion
The revision a session is gated with before it is negotiated.
Trait Implementations§
Source§impl Debug for HttpHandler
impl Debug for HttpHandler
Source§impl RequestHandler<HttpSession> for HttpHandler
impl RequestHandler<HttpSession> for HttpHandler
Source§fn unsessioned(&self, body: &[u8], headers: &HeaderMap) -> Unsessioned
fn unsessioned(&self, body: &[u8], headers: &HeaderMap) -> Unsessioned
What a body means when the request named no session.
Three arms, and which one a body falls in is a wire-format question this method can answer on its own:
initializeopens a session. It is the only method that does.- A body whose
params._metanamesPROTOCOL_VERSION_KEYis a SEP-2575 stateless request. It carries its own revision and its own capabilities, so it needs no session and is served against its own profile. - Anything else is a stateful call missing its header, which the router
answers with a
400and never hands here — so returningUnsessioned::NeedsSessionfor it is not a guess, it is the arm that produces that400.
The version key is what makes a body self-describing, and it is the only member that can: capabilities without a revision would not say which gates the answer is read against.
This runs on every sessionless POST, so the check is a lookup and not a
parse — a full RequestMeta::read would decode the whole body only
for a caller with a session header to throw it away.
Source§fn dispatch(
&self,
call: Inbound<'_, HttpSession>,
) -> impl Future<Output = Result<Response, Refusal>> + Send
fn dispatch( &self, call: Inbound<'_, HttpSession>, ) -> impl Future<Output = Result<Response, Refusal>> + Send
Runs one request, and answers it.
The refusal channel is a Refusal: there is no other, and an adapter
that cannot answer a request has exactly one honest way to say so. Note
that a protocol refusal — an unknown method, a tool that does not
exist — is not one. Those are answered in the body with a JSON-RPC error
object, because the peer asked a well-formed question and the answer is
that no such thing exists.