ureq_proto/server/
recvreq.rs1use http::{header, Request, Version};
2
3use crate::body::BodyReader;
4use crate::ext::HeaderIterExt;
5use crate::parser::try_parse_request;
6use crate::util::log_data;
7use crate::{ArrayVec, CloseReason, Error};
8
9use super::state::RecvRequest;
10use super::{Inner, Reply, ResponsePhase};
11use super::{RecvRequestResult, MAX_REQUEST_HEADERS};
12
13impl Reply<RecvRequest> {
14 pub fn new() -> Result<Self, Error> {
21 let close_reason = ArrayVec::from_fn(|_| CloseReason::ClientConnectionClose);
22
23 let inner = Inner {
24 phase: ResponsePhase::Status,
25 state: super::BodyState::default(),
26 response: None,
27 close_reason,
28 force_recv_body: false,
29 force_send_body: false,
30 method: None,
31 expect_100: false,
32 expect_100_reject: false,
33 };
34
35 Ok(Reply::wrap(inner))
36 }
37
38 pub fn try_request(&mut self, input: &[u8]) -> Result<(usize, Option<Request<()>>), Error> {
48 let maybe_request = self.do_try_request(input)?;
49
50 let (input_used, request) = match maybe_request {
51 Some(v) => v,
52 None => return Ok((0, None)),
54 };
55
56 self.inner.method = Some(request.method().clone());
57 self.inner.expect_100 = request.headers().iter().has_expect_100();
58
59 let headers = request.headers();
60 let is_http10 = request.version() == Version::HTTP_10;
61 let is_keep_alive = headers.iter().has(header::CONNECTION, "keep-alive");
62 let is_conn_close = headers.iter().has(header::CONNECTION, "close");
63
64 if is_http10 && !is_keep_alive {
65 self.inner
66 .close_reason
67 .push(CloseReason::CloseDelimitedBody);
68 }
69
70 if is_conn_close {
71 self.inner
72 .close_reason
73 .push(CloseReason::ClientConnectionClose);
74 }
75
76 Ok((input_used, Some(request)))
77 }
78
79 fn do_try_request(&mut self, input: &[u8]) -> Result<Option<(usize, Request<()>)>, Error> {
86 let (input_used, request) = match try_parse_request::<MAX_REQUEST_HEADERS>(input)? {
88 Some(v) => v,
89 None => {
90 return Ok(None);
91 }
92 };
93
94 log_data(&input[..input_used]);
95
96 let http10 = request.version() == Version::HTTP_10;
97 let method = request.method();
98
99 let header_lookup = |name: http::HeaderName| {
100 if let Some(header) = request.headers().get(name) {
101 return header.to_str().ok();
102 }
103 None
104 };
105
106 let reader =
107 BodyReader::for_request(http10, method, self.inner.force_recv_body, &header_lookup)?;
108 self.inner.state.reader = Some(reader);
109
110 Ok(Some((input_used, request)))
111 }
112
113 pub fn can_proceed(&self) -> bool {
119 self.inner.state.reader.is_some()
120 }
121
122 pub fn proceed(self) -> Option<RecvRequestResult> {
132 if !self.can_proceed() {
133 return None;
134 }
135
136 let has_request_body = self.inner.state.reader.as_ref().unwrap().has_body();
137
138 if has_request_body {
139 if self.inner.expect_100 {
140 Some(RecvRequestResult::Send100(Reply::wrap(self.inner)))
141 } else {
142 Some(RecvRequestResult::RecvBody(Reply::wrap(self.inner)))
143 }
144 } else {
145 Some(RecvRequestResult::ProvideResponse(Reply::wrap(self.inner)))
146 }
147 }
148
149 pub fn force_recv_body(&mut self) {
155 self.inner.force_recv_body = true;
156 }
157}