Skip to main content

icap_rs/server/
preview.rs

1use crate::request::{Body, IncomingRequest, Remainder};
2use crate::{EmbeddedHttp, Response};
3
4/// Decision returned by a preview-aware route handler.
5///
6/// Returning [`PreviewDecision::Respond`] lets a service send a final ICAP
7/// response after seeing only preview bytes, before the server emits
8/// `ICAP/1.0 100 Continue` and before the client uploads the remainder.
9#[derive(Debug)]
10#[must_use]
11#[allow(clippy::large_enum_variant)]
12pub enum PreviewDecision {
13    /// Continue the normal Preview flow.
14    ///
15    /// The server sends `ICAP/1.0 100 Continue`, reads the remaining chunked
16    /// body, and invokes the same route again with a full body.
17    Continue,
18    /// Send this final ICAP response immediately.
19    ///
20    /// The server does not emit `100 Continue` and does not read the remainder
21    /// of the request body.
22    Respond(Response),
23}
24
25pub(super) fn mark_request_body_as_preview(req: &mut IncomingRequest, ieof: bool) {
26    let Some(embedded) = req.embedded.as_mut() else {
27        return;
28    };
29
30    let body = match embedded {
31        EmbeddedHttp::Req { body, .. } | EmbeddedHttp::Resp { body, .. } => body,
32    };
33
34    let Body::Full { reader } = body else {
35        return;
36    };
37
38    let preview = std::mem::take(reader);
39    *body = Body::Preview {
40        bytes: preview,
41        ieof,
42        remainder: Remainder::new(Vec::new(), None),
43    };
44}