V
impl<S, B> Future for MetricsResponse<S, B>
where
B: MessageBody,
S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
{
type Output = Result<ServiceResponse<StreamMetrics<B>>, Error>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project();
let start = *this.start;
let res = match futures::ready!(this.fut.poll(cx)) {
Ok(res) => res,
Err(e) => return Poll::Ready(Err(e)),
};
let req = res.request();
let method = req.method().clone();
let pattern_or_path = req
.match_pattern()
.unwrap_or_else(|| req.path().to_string());
let path = req.path().to_string();
let inner = this.inner.clone();
Poll::Ready(Ok(res.map_body(move |mut head, mut body| {
// We short circuit the response status and body to serve the endpoint
// automagically. This way the user does not need to set the middleware *AND*
// an endpoint to serve middleware results. The user is only required to set
// the middleware and tell us what the endpoint should be.
if inner.matches(&path, &method) {
head.status = StatusCode::OK;
head.headers.insert(
CONTENT_TYPE,
HeaderValue::from_static("text/plain; version=0.0.4; charset=utf-8"),
);
}
StreamMetrics {
body: B::from(inner.metrics()),
size: 0,
start,
end: inner.clock.end(),
inner,
status: head.status,
path: pattern_or_path,
method,
}
})))
}
}
