ureq_proto/server/
provres.rs

1use http::{header, Response};
2
3use crate::body::response_body_allowed;
4use crate::{CloseReason, Error};
5
6use super::state::{ProvideResponse, SendResponse};
7use super::{append_request, Reply};
8
9impl Reply<ProvideResponse> {
10    /// Provide a response to the client's request.
11    ///
12    /// Takes a Response object and transitions to the SendResponse state.
13    /// Handles setting appropriate headers for the response body if they weren't already set.
14    pub fn provide(self, response: Response<()>) -> Result<Reply<SendResponse>, Error> {
15        if self.inner.expect_100_reject
16            && !response.status().is_client_error()
17            && !response.status().is_server_error()
18        {
19            return Err(Error::BadReject100Status(response.status()));
20        }
21
22        let mut inner = append_request(self.inner, response);
23
24        // unwrap are correct due to state we should be in when we get here.
25        let response = inner.response.as_mut().unwrap();
26
27        if response
28            .headers()
29            .any(|(h, v)| h == header::CONNECTION && v == "close")
30        {
31            inner.close_reason.push(CloseReason::ServerConnectionClose);
32        }
33
34        let writer = inner.state.writer.take().unwrap();
35        let info = response.analyze(writer)?;
36
37        let body_provided = info.body_mode.has_body();
38
39        let (_, status) = response.prelude();
40        let status = status.into();
41        let method = inner.method.as_ref().unwrap();
42
43        let body_allowed = response_body_allowed(method, status, info.body_mode.body_mode());
44        let force_send = inner.force_send_body;
45
46        let should_send_body = body_allowed || force_send;
47
48        if body_provided && !should_send_body {
49            // User set a body header but method does not allow one
50            return Err(Error::BodyNotAllowed);
51        }
52
53        if body_provided && !info.res_body_header && should_send_body {
54            // User did not set a body header, we set one.
55            let header = info.body_mode.body_header();
56            response.set_header(header.0, header.1)?;
57        }
58
59        inner.state.writer = Some(info.body_mode);
60
61        Ok(Reply::wrap(inner))
62    }
63
64    /// Convert the state to send a body despite the method
65    ///
66    /// Methods like HEAD and CONNECT should not have attached bodies.
67    /// Some broken APIs use bodies anyway and this is an escape hatch to
68    /// interoperate with such services.
69    pub fn force_send_body(&mut self) {
70        self.inner.force_send_body = true;
71    }
72}