Skip to main content

http_net/
server.rs

1//! The server side of an HTTP/1.1 connection, without I/O.
2
3use alloc::vec::Vec;
4
5use crate::{
6    body::{Decoder, Encoder, Step, push_framing},
7    buffer::Buffer,
8    date::HttpDate,
9    error::HttpError,
10    head::{
11        HeadKind, HeadScanner, Headers, RequestHead, RequestInfo, Scan, Version, interpret_request,
12    },
13    limits::Limits,
14    message::{
15        OutBody, Response, check_response_field, check_trailers, check_upgrade_protocol,
16        push_last_chunk_with_trailers, write_field,
17    },
18    method::Method,
19    preface::is_h2_preface,
20    status::write_status_line,
21    write::{BodyPlan, OutgoingBody, Output, ResponseHeadRef},
22};
23
24/// What a [`ServerConn`] has for the caller after [`poll`](ServerConn::poll).
25///
26/// # Examples
27///
28/// ```
29/// use http_net::{Response, ServerConn, ServerEvent};
30///
31/// let mut conn = ServerConn::new();
32/// let mut out = Vec::new();
33/// let _ = conn.feed(b"POST /echo HTTP/1.1\r\nHost: a\r\nContent-Length: 2\r\n\r\nhi");
34/// let mut body = Vec::new();
35/// loop {
36///     match conn.poll().unwrap() {
37///         ServerEvent::Request(req) => assert_eq!(req.path(), "/echo"),
38///         ServerEvent::Body(chunk) => body.extend_from_slice(chunk),
39///         ServerEvent::RequestEnd => {
40///             conn.respond(&Response::new(200).body(body.clone()), &mut out).unwrap();
41///         }
42///         ServerEvent::NeedInput => break,
43///         other => panic!("{other:?}"),
44///     }
45/// }
46/// assert!(out.ends_with(b"\r\n\r\nhi"));
47/// ```
48#[non_exhaustive]
49pub enum ServerEvent<'a> {
50    /// A request head arrived. Its body (if any) follows as
51    /// [`Body`](ServerEvent::Body) events, then
52    /// [`RequestEnd`](ServerEvent::RequestEnd). A response may be sent from
53    /// this point on; sending it while body bytes are still unread closes
54    /// the connection afterwards (a request without a body stays
55    /// keep-alive). If the head
56    /// [`expects_continue`](RequestHead::expects_continue), answer with
57    /// [`send_continue`](ServerConn::send_continue) or a final response
58    /// before waiting for the body.
59    Request(RequestHead<'a>),
60    /// A run of body bytes, after chunked decoding.
61    Body(&'a [u8]),
62    /// The request's trailer fields, just before
63    /// [`RequestEnd`](ServerEvent::RequestEnd): only with
64    /// [`set_report_trailers(true)`](ServerConn::set_report_trailers) and a
65    /// non-empty trailer section. They never change how the request was
66    /// framed. The values of credential fields are redacted in `Debug`.
67    Trailers(Headers<'a>),
68    /// The request is complete. Send the response if it has not been sent.
69    RequestEnd,
70    /// More input is needed: read from the socket, then
71    /// [`feed`](ServerConn::feed) (or [`read_buf`](ServerConn::read_buf) and
72    /// [`commit`](ServerConn::commit)), or [`feed_eof`](ServerConn::feed_eof)
73    /// if the peer closed.
74    NeedInput,
75    /// The request is complete and its response has not been finished yet.
76    /// Pipelined requests wait in the buffer until it is.
77    AwaitingResponse,
78    /// A `101 Switching Protocols` (or a 2xx to `CONNECT`) was sent: the
79    /// connection now belongs to the new protocol. Bytes that already arrived
80    /// for it are in [`remaining_input`](ServerConn::remaining_input).
81    Upgraded,
82    /// The connection is finished: flush any output, then close the socket.
83    Closed,
84}
85
86/// Body bytes print as their length: a body can carry credentials that no
87/// field redaction sees (a form login, a token).
88impl core::fmt::Debug for ServerEvent<'_> {
89    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
90        match self {
91            Self::Request(head) => f.debug_tuple("Request").field(head).finish(),
92            Self::Body(bytes) => f
93                .debug_tuple("Body")
94                .field(&format_args!("{} bytes", bytes.len()))
95                .finish(),
96            Self::Trailers(fields) => f.debug_tuple("Trailers").field(fields).finish(),
97            Self::RequestEnd => f.write_str("RequestEnd"),
98            Self::NeedInput => f.write_str("NeedInput"),
99            Self::AwaitingResponse => f.write_str("AwaitingResponse"),
100            Self::Upgraded => f.write_str("Upgraded"),
101            Self::Closed => f.write_str("Closed"),
102        }
103    }
104}
105
106#[derive(Clone, Copy, Debug, PartialEq, Eq)]
107enum ReqState {
108    Head,
109    Body,
110    Complete,
111    Upgraded,
112    Failed,
113    Closed,
114}
115
116#[derive(Clone, Copy, Debug, PartialEq, Eq)]
117enum RespState {
118    Idle,
119    Streaming(Encoder),
120    Sent,
121}
122
123/// The phase of a connection, for drivers that run header-read, request,
124/// and response deadlines: what [`ServerConn::progress`] and
125/// [`ClientConn::progress`](crate::ClientConn::progress) report.
126///
127/// # Examples
128///
129/// ```
130/// use http_net::{Progress, ServerConn, ServerEvent};
131///
132/// let mut conn = ServerConn::new();
133/// assert_eq!(conn.progress(), Progress::Idle);
134/// let _ = conn.feed(b"GET / HTTP/1.1\r\n");
135/// assert!(matches!(conn.poll(), Ok(ServerEvent::NeedInput)));
136/// assert_eq!(conn.progress(), Progress::Head);
137/// ```
138#[non_exhaustive]
139#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
140pub enum Progress {
141    /// Between messages: no byte of the next one has been seen. Idle
142    /// keep-alive time belongs to this phase, so a request deadline should
143    /// not start here.
144    Idle,
145    /// Some bytes of a head have arrived; the head is not complete.
146    Head,
147    /// The head is complete and body bytes are still to come.
148    Body,
149    /// Server: the request is complete (or has no body left to read), or it
150    /// was refused with a parse error, and its response is not finished.
151    /// Client: the request was sent and nothing of the response has arrived,
152    /// or a pipelined request is next.
153    AwaitingResponse,
154    /// A streamed body is being written: the response on a server, the
155    /// request on a client.
156    WritingBody,
157    /// The connection belongs to another protocol.
158    Upgraded,
159    /// The connection is finished (or will be once the last response is
160    /// written).
161    Closed,
162}
163
164/// The server side of one HTTP/1.1 connection: a sans-IO state machine.
165///
166/// The connection owns a bounded input buffer. The caller moves bytes
167/// between it and the socket: input in through [`feed`](Self::feed) (or
168/// [`read_buf`](Self::read_buf) + [`commit`](Self::commit) to read straight
169/// into the buffer), events out through [`poll`](Self::poll), responses out
170/// through [`respond`](Self::respond) into a caller-owned `Vec<u8>`.
171///
172/// Requests are handled one at a time, in order. Keep-alive is automatic:
173/// after a response is finished the next request (possibly already buffered,
174/// when the client pipelines) is parsed on the next `poll`. A connection
175/// that must close (the client asked, HTTP/1.0 without keep-alive, the
176/// response was sent before the request body was read, or a parse error)
177/// reports [`ServerEvent::Closed`] once its last response is written.
178///
179/// Steady state allocates nothing: the input buffer and the field index are
180/// reused across requests.
181///
182/// # Examples
183///
184/// ```
185/// use http_net::{Response, ServerConn, ServerEvent};
186///
187/// let mut conn = ServerConn::new();
188/// let mut out = Vec::new();
189/// // Two pipelined requests in one read.
190/// let _ = conn.feed(b"GET /a HTTP/1.1\r\nHost: x\r\n\r\nGET /b HTTP/1.1\r\nHost: x\r\n\r\n");
191/// let mut paths = Vec::new();
192/// loop {
193///     match conn.poll().unwrap() {
194///         ServerEvent::Request(req) => paths.push(req.path().to_string()),
195///         ServerEvent::RequestEnd => conn.respond(&Response::text(200, "ok"), &mut out).unwrap(),
196///         ServerEvent::NeedInput => break,
197///         other => panic!("{other:?}"),
198///     }
199/// }
200/// assert_eq!(paths, ["/a", "/b"]);
201/// ```
202pub struct ServerConn {
203    buf: Buffer,
204    limits: Limits,
205    scanner: HeadScanner,
206    trailers: HeadScanner,
207    decoder: Decoder,
208    info: RequestInfo,
209    state: ReqState,
210    resp: RespState,
211    keep_alive: bool,
212    /// Cleared by `set_keep_alive(false)`: every later response closes.
213    allow_keep_alive: bool,
214    continue_sent: bool,
215    /// A body byte of the current request was delivered.
216    body_seen: bool,
217    /// The response being streamed was declared chunked (trailers allowed,
218    /// even if an HTTP/1.0 client forced a close-delimited body).
219    resp_chunked: bool,
220    report_trailers: bool,
221    requests_served: u64,
222    /// The connection has not yet shown whether it starts with the HTTP/2
223    /// preface (checked once, before the first request only).
224    preface_undecided: bool,
225}
226
227impl Default for ServerConn {
228    fn default() -> Self {
229        Self::new()
230    }
231}
232
233impl core::fmt::Debug for ServerConn {
234    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
235        f.debug_struct("ServerConn")
236            .field("state", &self.state)
237            .field("response", &self.resp)
238            .field("buffered", &self.buf.unread().len())
239            .field("limits", &self.limits)
240            .finish()
241    }
242}
243
244impl ServerConn {
245    /// A connection with the default [`Limits`].
246    ///
247    /// # Examples
248    ///
249    /// ```
250    /// let conn = http_net::ServerConn::new();
251    /// assert!(conn.request().is_none());
252    /// ```
253    #[must_use]
254    pub fn new() -> Self {
255        Self::with_limits(Limits::new())
256    }
257
258    /// A connection enforcing `limits`.
259    ///
260    /// # Examples
261    ///
262    /// ```
263    /// use http_net::{HttpError, Limits, ServerConn};
264    ///
265    /// let mut conn = ServerConn::with_limits(Limits::new().with_max_body(4));
266    /// let _ = conn.feed(b"POST / HTTP/1.1\r\nHost: a\r\nContent-Length: 5\r\n\r\n");
267    /// assert_eq!(conn.poll().unwrap_err(), HttpError::BodyTooLarge);
268    /// ```
269    #[must_use]
270    pub fn with_limits(limits: Limits) -> Self {
271        Self::from_buffer(Buffer::new(limits.buffer_capacity()), limits)
272    }
273
274    /// A connection enforcing `limits` that reads into `storage`, for
275    /// drivers that pool buffers: its capacity is used up to
276    /// [`Limits::buffer_capacity`], its contents are ignored. Give it back
277    /// with [`into_buffer`](Self::into_buffer).
278    ///
279    /// # Examples
280    ///
281    /// ```
282    /// use http_net::{Limits, ServerConn, ServerEvent};
283    ///
284    /// let pooled: Vec<u8> = Vec::with_capacity(8192);
285    /// let mut conn = ServerConn::with_buffer(pooled, Limits::new());
286    /// let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\n\r\n");
287    /// assert!(matches!(conn.poll().unwrap(), ServerEvent::Request(_)));
288    /// let back = conn.into_buffer();
289    /// assert!(back.capacity() >= 8192);
290    /// ```
291    #[must_use]
292    pub fn with_buffer(storage: Vec<u8>, limits: Limits) -> Self {
293        Self::from_buffer(
294            Buffer::with_storage(storage, limits.buffer_capacity()),
295            limits,
296        )
297    }
298
299    fn from_buffer(mut buf: Buffer, limits: Limits) -> Self {
300        buf.pin_at_pos();
301        Self {
302            buf,
303            limits,
304            scanner: HeadScanner::new(),
305            trailers: HeadScanner::new(),
306            decoder: Decoder::new(),
307            info: RequestInfo::EMPTY,
308            state: ReqState::Head,
309            resp: RespState::Idle,
310            keep_alive: false,
311            allow_keep_alive: true,
312            continue_sent: false,
313            body_seen: false,
314            resp_chunked: false,
315            report_trailers: false,
316            requests_served: 0,
317            preface_undecided: true,
318        }
319    }
320
321    /// The limits this connection enforces.
322    ///
323    /// # Examples
324    ///
325    /// ```
326    /// assert_eq!(http_net::ServerConn::new().limits(), &http_net::Limits::new());
327    /// ```
328    #[must_use]
329    pub fn limits(&self) -> &Limits {
330        &self.limits
331    }
332
333    /// Copies as much of `bytes` into the input buffer as fits and returns
334    /// how many bytes were taken. Fewer than `bytes.len()` means the buffer
335    /// is full: [`poll`](Self::poll) until it asks for input, then feed the
336    /// rest.
337    ///
338    /// # Examples
339    ///
340    /// ```
341    /// let mut conn = http_net::ServerConn::new();
342    /// assert_eq!(conn.feed(b"GET / HTTP/1.1\r\n"), 16);
343    /// ```
344    #[must_use = "bytes beyond the returned count were not taken"]
345    pub fn feed(&mut self, bytes: &[u8]) -> usize {
346        self.buf.feed(bytes)
347    }
348
349    /// Spare space at the end of the input buffer, for reading from a
350    /// socket without an intermediate copy. Follow with
351    /// [`commit`](Self::commit). It is empty only when the buffer is full of
352    /// input the parser has not been asked to process yet; poll first.
353    ///
354    /// # Examples
355    ///
356    /// ```
357    /// let mut conn = http_net::ServerConn::new();
358    /// let spare = conn.read_buf();
359    /// let msg = b"GET / HTTP/1.1\r\nHost: a\r\n\r\n";
360    /// spare[..msg.len()].copy_from_slice(msg);
361    /// conn.commit(msg.len());
362    /// assert!(matches!(conn.poll(), Ok(http_net::ServerEvent::Request(_))));
363    /// ```
364    pub fn read_buf(&mut self) -> &mut [u8] {
365        self.buf.spare()
366    }
367
368    /// Records that `n` bytes were written into [`read_buf`](Self::read_buf).
369    /// An `n` larger than the slice `read_buf` returned is clamped to its
370    /// length: committing bytes that were not written would hand stale
371    /// buffer contents to the parser.
372    ///
373    /// # Examples
374    ///
375    /// ```
376    /// let mut conn = http_net::ServerConn::new();
377    /// conn.read_buf()[0] = b'G';
378    /// conn.commit(1);
379    /// assert!(matches!(conn.poll(), Ok(http_net::ServerEvent::NeedInput)));
380    /// ```
381    pub fn commit(&mut self, n: usize) {
382        self.buf.commit(n);
383    }
384
385    /// Records that the peer closed its sending side. A connection idle
386    /// between requests then reports [`ServerEvent::Closed`]; one in the
387    /// middle of a request reports [`HttpError::UnexpectedEof`].
388    ///
389    /// # Examples
390    ///
391    /// ```
392    /// let mut conn = http_net::ServerConn::new();
393    /// conn.feed_eof();
394    /// assert!(matches!(conn.poll(), Ok(http_net::ServerEvent::Closed)));
395    /// ```
396    pub fn feed_eof(&mut self) {
397        self.buf.set_eof();
398    }
399
400    /// Advances the parser and reports what happened. Call it until it
401    /// returns [`ServerEvent::NeedInput`], [`ServerEvent::AwaitingResponse`],
402    /// [`ServerEvent::Upgraded`], or [`ServerEvent::Closed`].
403    ///
404    /// # Errors
405    ///
406    /// Any [`HttpError`] parse error. The connection is then finished: send
407    /// one error response (see [`HttpError::status`]) with
408    /// [`respond`](Self::respond), flush, and close. It is written as an
409    /// answer to a `GET`, or, once a `HEAD` request line has been read, to a
410    /// `HEAD`, without content.
411    ///
412    /// # Examples
413    ///
414    /// ```
415    /// use http_net::{HttpError, ServerConn};
416    ///
417    /// let mut conn = ServerConn::new();
418    /// let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\n folded\r\n\r\n");
419    /// assert_eq!(conn.poll().unwrap_err(), HttpError::ObsFold);
420    /// ```
421    pub fn poll(&mut self) -> Result<ServerEvent<'_>, HttpError> {
422        loop {
423            match self.state {
424                ReqState::Head => return self.poll_head(),
425                ReqState::Body => {
426                    if self.resp == RespState::Sent && !self.decoder.is_read() {
427                        // Answered before the body was read: the rest of the
428                        // body cannot be trusted to frame the next request.
429                        self.state = ReqState::Closed;
430                        return Ok(ServerEvent::Closed);
431                    }
432                    return self.poll_body();
433                }
434                ReqState::Complete => {
435                    if self.resp != RespState::Sent {
436                        return Ok(ServerEvent::AwaitingResponse);
437                    }
438                    if !self.keep_alive {
439                        self.state = ReqState::Closed;
440                        return Ok(ServerEvent::Closed);
441                    }
442                    self.next_exchange();
443                }
444                ReqState::Upgraded => return Ok(ServerEvent::Upgraded),
445                ReqState::Failed | ReqState::Closed => return Ok(ServerEvent::Closed),
446            }
447        }
448    }
449
450    fn poll_head(&mut self) -> Result<ServerEvent<'_>, HttpError> {
451        let start = self.buf.pin();
452        if self.preface_undecided {
453            // RFC 9113 section 3.4: prior-knowledge HTTP/2 starts the
454            // connection with a fixed preface. Decide before the head is
455            // scanned (its first 18 bytes are a complete HTTP/1.1-shaped
456            // head), and wait while the input could still be the preface, so
457            // the answer does not depend on how the bytes arrived.
458            match is_h2_preface(self.buf.from(start)) {
459                Some(true) => return Err(self.fail(HttpError::Http2Preface)),
460                Some(false) => self.preface_undecided = false,
461                None if self.buf.is_eof() => self.preface_undecided = false,
462                None => return Ok(ServerEvent::NeedInput),
463            }
464        }
465        let msg = self.buf.from(start);
466        let progress = self
467            .scanner
468            .advance(msg, &self.limits, HeadKind::Request, true)
469            .map_err(|e| self.fail(e))?;
470        let len = match progress {
471            Scan::Partial if self.buf.is_eof() => {
472                if self.buf.from(start).is_empty() {
473                    self.state = ReqState::Closed;
474                    return Ok(ServerEvent::Closed);
475                }
476                return Err(self.fail(HttpError::UnexpectedEof));
477            }
478            Scan::Partial => return Ok(ServerEvent::NeedInput),
479            Scan::Done(len) => len,
480        };
481        let info = interpret_request(
482            self.buf.from(start),
483            self.scanner.start_line(),
484            &self.scanner.fields,
485            &self.limits,
486        )
487        .map_err(|e| self.fail(e))?;
488        self.buf.consume(len);
489        self.buf.extend_pin_to_pos();
490        self.info = info;
491        self.keep_alive = info.keep_alive;
492        self.decoder.start(info.framing);
493        self.state = ReqState::Body;
494        Ok(ServerEvent::Request(self.view()))
495    }
496
497    fn poll_body(&mut self) -> Result<ServerEvent<'_>, HttpError> {
498        let mut framing_bytes = 0;
499        let step = self.decoder.step(
500            self.buf.unread(),
501            self.buf.is_eof(),
502            &self.limits,
503            &mut self.trailers,
504            self.report_trailers,
505            &mut framing_bytes,
506        );
507        self.buf.consume(framing_bytes);
508        match step.map_err(|e| self.fail(e))? {
509            Step::Data(n) => {
510                let start = self.buf.pos();
511                self.buf.consume(n);
512                self.body_seen = true;
513                Ok(ServerEvent::Body(self.buf.range(start, start + n)))
514            }
515            Step::Trailers => Ok(ServerEvent::Trailers(Headers::new(
516                self.buf.unread(),
517                &self.trailers.fields,
518            ))),
519            Step::Done => {
520                self.state = ReqState::Complete;
521                Ok(ServerEvent::RequestEnd)
522            }
523            Step::NeedMore => Ok(ServerEvent::NeedInput),
524        }
525    }
526
527    fn fail(&mut self, e: HttpError) -> HttpError {
528        self.state = ReqState::Failed;
529        self.keep_alive = false;
530        e
531    }
532
533    fn next_exchange(&mut self) {
534        self.buf.wipe_consumed();
535        self.buf.unpin();
536        self.buf.pin_at_pos();
537        self.scanner.reset();
538        self.resp = RespState::Idle;
539        self.info = RequestInfo::EMPTY;
540        self.continue_sent = false;
541        self.body_seen = false;
542        self.state = ReqState::Head;
543    }
544
545    /// Whether a response to the current request has been started.
546    #[cfg(feature = "std")]
547    pub(crate) fn response_started(&self) -> bool {
548        self.resp != RespState::Idle
549    }
550
551    /// Whether the current request's body has been read to its end: the
552    /// exchange is complete, or the request has no body at all (a response
553    /// given at [`ServerEvent::Request`] then leaves nothing unread).
554    fn body_read(&self) -> bool {
555        self.state == ReqState::Complete || (self.state == ReqState::Body && self.decoder.is_read())
556    }
557
558    fn view(&self) -> RequestHead<'_> {
559        RequestHead::new(
560            self.buf.from(self.buf.pin()),
561            &self.scanner.fields,
562            &self.info,
563        )
564    }
565
566    /// The current request's head, from its arrival until the `poll` after
567    /// its response is finished (still available after an upgrade).
568    ///
569    /// # Examples
570    ///
571    /// ```
572    /// use http_net::{ServerConn, ServerEvent};
573    ///
574    /// let mut conn = ServerConn::new();
575    /// let _ = conn.feed(b"PUT /f HTTP/1.1\r\nHost: a\r\nContent-Length: 1\r\n\r\nz");
576    /// while !matches!(conn.poll().unwrap(), ServerEvent::RequestEnd) {}
577    /// assert_eq!(conn.request().unwrap().path(), "/f");
578    /// ```
579    #[must_use]
580    pub fn request(&self) -> Option<RequestHead<'_>> {
581        match self.state {
582            ReqState::Body | ReqState::Complete | ReqState::Upgraded => Some(self.view()),
583            _ => None,
584        }
585    }
586
587    /// Whether a `101 Switching Protocols` (or a 2xx to `CONNECT`) was sent
588    /// and the connection now belongs to another protocol.
589    ///
590    /// # Examples
591    ///
592    /// ```
593    /// assert!(!http_net::ServerConn::new().is_upgraded());
594    /// ```
595    #[must_use]
596    pub fn is_upgraded(&self) -> bool {
597        self.state == ReqState::Upgraded
598    }
599
600    /// Input that arrived after the last message this connection parsed:
601    /// after [`ServerEvent::Upgraded`], the first bytes of the new protocol.
602    ///
603    /// # Examples
604    ///
605    /// ```
606    /// use http_net::{Response, ServerConn, ServerEvent};
607    ///
608    /// let mut conn = ServerConn::new();
609    /// let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\nConnection: upgrade\r\nUpgrade: x\r\n\r\n\x81\x00");
610    /// assert!(matches!(conn.poll().unwrap(), ServerEvent::Request(_)));
611    /// assert!(matches!(conn.poll().unwrap(), ServerEvent::RequestEnd));
612    /// conn.respond(&Response::switching_protocols("x"), &mut Vec::new()).unwrap();
613    /// assert!(matches!(conn.poll().unwrap(), ServerEvent::Upgraded));
614    /// assert_eq!(conn.remaining_input(), b"\x81\x00");
615    /// ```
616    #[must_use]
617    pub fn remaining_input(&self) -> &[u8] {
618        self.buf.unread()
619    }
620
621    /// Writes `response` for the current request into `out`.
622    ///
623    /// With a full body the response is complete. With a streamed body
624    /// ([`Response::chunked`], [`Response::content_length`]) follow with
625    /// [`send_body`](Self::send_body) and [`end_body`](Self::end_body).
626    /// After a parse error, one response may still be sent; it is marked
627    /// `connection: close`.
628    ///
629    /// # Errors
630    ///
631    /// - the first error recorded by the [`Response`] builder;
632    /// - [`HttpError::InvalidStatus`] for a status outside `100..=599`, or a
633    ///   1xx other than 101;
634    /// - [`HttpError::BodyNotAllowed`] for a body on 1xx, 204, 304, 101, or a
635    ///   2xx to `CONNECT`;
636    /// - [`HttpError::UpgradeNotOffered`] for a 101 whose protocol the
637    ///   request's `Upgrade` field did not offer;
638    /// - [`HttpError::InvalidState`] when there is no request to answer, a
639    ///   response was already started, or a 101 does not answer a complete
640    ///   upgrade request.
641    ///
642    /// # Examples
643    ///
644    /// ```
645    /// use http_net::{Response, ServerConn, ServerEvent};
646    ///
647    /// let mut conn = ServerConn::new();
648    /// let _ = conn.feed(b"HEAD / HTTP/1.1\r\nHost: a\r\n\r\n");
649    /// while !matches!(conn.poll().unwrap(), ServerEvent::RequestEnd) {}
650    /// let mut out = Vec::new();
651    /// conn.respond(&Response::text(200, "hello"), &mut out).unwrap();
652    /// // HEAD: the length is announced, the body is not sent.
653    /// assert!(out.windows(17).any(|w| w == b"content-length: 5"));
654    /// assert!(out.ends_with(b"\r\n\r\n"));
655    /// ```
656    pub fn respond(&mut self, response: &Response, out: &mut Vec<u8>) -> Result<(), HttpError> {
657        self.respond_dated(response, None, out)
658    }
659
660    /// As [`respond`](Self::respond), adding `date: <date>` unless the
661    /// response set its own `date` field. Keep a
662    /// [`DateCache`](crate::DateCache) per driver thread and pass
663    /// `cache.update(now)`: the value is reformatted once per second, not
664    /// once per response.
665    ///
666    /// # Errors
667    ///
668    /// As [`respond`](Self::respond).
669    ///
670    /// # Examples
671    ///
672    /// ```
673    /// use http_net::{DateCache, Response, ServerConn, ServerEvent};
674    ///
675    /// let mut dates = DateCache::new();
676    /// let mut conn = ServerConn::new();
677    /// let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\n\r\n");
678    /// while !matches!(conn.poll().unwrap(), ServerEvent::RequestEnd) {}
679    /// let mut out = Vec::new();
680    /// conn.respond_with_date(&Response::new(204), dates.update(784_111_777), &mut out)?;
681    /// assert!(out.windows(35).any(|w| w == b"date: Sun, 06 Nov 1994 08:49:37 GMT"));
682    /// # Ok::<(), http_net::HttpError>(())
683    /// ```
684    pub fn respond_with_date(
685        &mut self,
686        response: &Response,
687        date: &HttpDate,
688        out: &mut Vec<u8>,
689    ) -> Result<(), HttpError> {
690        self.respond_dated(response, Some(date.as_bytes()), out)
691    }
692
693    /// As [`respond`](Self::respond), but writes only the head: for a
694    /// full-body response the caller then sends
695    /// [`Response::body_bytes`] itself, so head and body can leave in one
696    /// vectored write (`write_vectored`) without the body being copied into
697    /// `out`. The returned [`BodyPlan`] says what follows:
698    ///
699    /// - [`BodyPlan::Raw`]: send the body bytes, exactly as they are, right
700    ///   after the head; the response already counts as sent.
701    /// - [`BodyPlan::None`]: nothing (an empty body, `HEAD`, 204, 304, a
702    ///   tunnel).
703    /// - [`BodyPlan::Stream`]: a streamed response; continue with
704    ///   [`send_body`](Self::send_body) and [`end_body`](Self::end_body).
705    ///
706    /// # Errors
707    ///
708    /// As [`respond`](Self::respond); nothing is written on error.
709    ///
710    /// # Examples
711    ///
712    /// ```
713    /// use http_net::{BodyPlan, Response, ServerConn, ServerEvent};
714    ///
715    /// let mut conn = ServerConn::new();
716    /// let _ = conn.feed(b"GET /big HTTP/1.1\r\nHost: a\r\n\r\n");
717    /// while !matches!(conn.poll()?, ServerEvent::RequestEnd) {}
718    /// let response = Response::new(200).body(vec![b'x'; 64 * 1024]);
719    /// let mut head = Vec::new();
720    /// let plan = conn.respond_head_only(&response, &mut head)?;
721    /// assert_eq!(plan, BodyPlan::Raw);
722    /// assert!(head.ends_with(b"content-length: 65536\r\n\r\n"));
723    /// // Send `head` and `response.body_bytes()` together, e.g. with
724    /// // `std::io::Write::write_vectored`.
725    /// assert_eq!(response.body_bytes().map(<[u8]>::len), Some(64 * 1024));
726    /// # Ok::<(), http_net::HttpError>(())
727    /// ```
728    pub fn respond_head_only(
729        &mut self,
730        response: &Response,
731        out: &mut Vec<u8>,
732    ) -> Result<BodyPlan, HttpError> {
733        self.start_response(response, None, out)
734    }
735
736    /// [`respond_head_only`](Self::respond_head_only) with a `date` (the
737    /// blocking server's vectored path).
738    #[cfg(feature = "std")]
739    pub(crate) fn respond_head_dated(
740        &mut self,
741        response: &Response,
742        date: Option<&[u8]>,
743        out: &mut Vec<u8>,
744    ) -> Result<BodyPlan, HttpError> {
745        self.start_response(response, date, out)
746    }
747
748    /// Writes an interim (1xx) response other than `100` and `101`, for
749    /// example `103 Early Hints` with `link` fields, before the final
750    /// response. It may be sent more than once, for any request method,
751    /// at any point before the final response starts (RFC 9110 section
752    /// 15.2), but never to an HTTP/1.0 client. Only the status and the
753    /// fields are written; an interim response has no body and does not
754    /// change the connection.
755    ///
756    /// # Errors
757    ///
758    /// The first error recorded by the builder; [`HttpError::InvalidStatus`]
759    /// unless the status is in `102..=199`; [`HttpError::BodyNotAllowed`]
760    /// for a body; [`HttpError::InterimNotAllowed`] for an HTTP/1.0 request
761    /// or once the final response has started; [`HttpError::InvalidState`]
762    /// when there is no request (or after a parse error, an upgrade, or the
763    /// end of the connection).
764    ///
765    /// # Examples
766    ///
767    /// ```
768    /// use http_net::{Response, ServerConn, ServerEvent};
769    ///
770    /// let mut conn = ServerConn::new();
771    /// let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\n\r\n");
772    /// while !matches!(conn.poll().unwrap(), ServerEvent::RequestEnd) {}
773    /// let mut out = Vec::new();
774    /// let hints = Response::new(103).header("link", "</style.css>; rel=preload; as=style");
775    /// conn.send_informational(&hints, &mut out)?;
776    /// conn.respond(&Response::text(200, "page"), &mut out)?;
777    /// assert!(out.starts_with(b"HTTP/1.1 103 Early Hints\r\nlink: </style.css>"));
778    /// # Ok::<(), http_net::HttpError>(())
779    /// ```
780    pub fn send_informational(
781        &mut self,
782        interim: &Response,
783        out: &mut Vec<u8>,
784    ) -> Result<(), HttpError> {
785        if let Some(e) = interim.error() {
786            return Err(e);
787        }
788        let status = interim.status();
789        if !(102..=199).contains(&status) {
790            return Err(HttpError::InvalidStatus);
791        }
792        if !matches!(&interim.body, OutBody::Full(b) if b.is_empty()) {
793            return Err(HttpError::BodyNotAllowed);
794        }
795        if !matches!(self.state, ReqState::Body | ReqState::Complete) {
796            return Err(HttpError::InvalidState(
797                "an interim response needs a request to answer",
798            ));
799        }
800        if self.info.version != Version::Http11 || self.resp != RespState::Idle {
801            return Err(HttpError::InterimNotAllowed);
802        }
803        write_status_line(out, status);
804        out.extend_from_slice(interim.fields());
805        out.extend_from_slice(b"\r\n");
806        Ok(())
807    }
808
809    /// Stops (`false`) or allows (`true`) keep-alive. With `false` the
810    /// current response, or the next one if it has not started, carries
811    /// `connection: close`, and the connection ends after it: the gentlest
812    /// way to shed load or to cap requests per connection. If the current
813    /// response has already been written, the connection ends after it.
814    /// `true` cannot keep open a connection the protocol requires to close
815    /// (the client asked, or body bytes were left unread). A `101` or a 2xx
816    /// to `CONNECT` hands the connection over regardless.
817    ///
818    /// # Examples
819    ///
820    /// ```
821    /// use http_net::{Response, ServerConn, ServerEvent};
822    ///
823    /// let mut conn = ServerConn::new();
824    /// let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\n\r\n");
825    /// while !matches!(conn.poll().unwrap(), ServerEvent::RequestEnd) {}
826    /// conn.set_keep_alive(false);
827    /// let mut out = Vec::new();
828    /// conn.respond(&Response::new(204), &mut out).unwrap();
829    /// assert!(out.windows(17).any(|w| w == b"connection: close"));
830    /// assert!(matches!(conn.poll().unwrap(), ServerEvent::Closed));
831    /// ```
832    pub fn set_keep_alive(&mut self, keep: bool) {
833        self.allow_keep_alive = keep;
834        if !keep && self.resp != RespState::Idle {
835            self.keep_alive = false;
836        }
837    }
838
839    /// Whether the connection can stay open after the current exchange, as
840    /// far as is known now: keep-alive is allowed (see
841    /// [`set_keep_alive`](Self::set_keep_alive)) and neither the request,
842    /// the response, nor an error requires a close.
843    ///
844    /// # Examples
845    ///
846    /// ```
847    /// use http_net::{ServerConn, ServerEvent};
848    ///
849    /// let mut conn = ServerConn::new();
850    /// assert!(conn.keep_alive());
851    /// let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\nConnection: close\r\n\r\n");
852    /// assert!(matches!(conn.poll().unwrap(), ServerEvent::Request(_)));
853    /// assert!(!conn.keep_alive());
854    /// ```
855    #[must_use]
856    pub fn keep_alive(&self) -> bool {
857        self.allow_keep_alive
858            && match self.state {
859                ReqState::Head => true,
860                ReqState::Body | ReqState::Complete => self.keep_alive,
861                ReqState::Upgraded | ReqState::Failed | ReqState::Closed => false,
862            }
863    }
864
865    /// The number of responses completed on this connection (full-body
866    /// responses when written, streamed ones at `end_body`), so a driver can
867    /// cap requests per connection.
868    ///
869    /// # Examples
870    ///
871    /// ```
872    /// use http_net::{Response, ServerConn, ServerEvent};
873    ///
874    /// let mut conn = ServerConn::new();
875    /// let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\n\r\n");
876    /// while !matches!(conn.poll().unwrap(), ServerEvent::RequestEnd) {}
877    /// assert_eq!(conn.requests_served(), 0);
878    /// conn.respond(&Response::new(204), &mut Vec::new()).unwrap();
879    /// assert_eq!(conn.requests_served(), 1);
880    /// ```
881    #[must_use]
882    pub fn requests_served(&self) -> u64 {
883        self.requests_served
884    }
885
886    /// The connection's phase, for header-read, request, and response
887    /// deadlines. [`Progress::Head`] starts at the first byte of a request,
888    /// so idle keep-alive time (`Idle`) is never counted against a request.
889    ///
890    /// # Examples
891    ///
892    /// ```
893    /// use http_net::{Progress, Response, ServerConn, ServerEvent};
894    ///
895    /// let mut conn = ServerConn::new();
896    /// let _ = conn.feed(b"POST / HTTP/1.1\r\nHost: a\r\nContent-Length: 4\r\n\r\nab");
897    /// assert!(matches!(conn.poll().unwrap(), ServerEvent::Request(_)));
898    /// assert!(matches!(conn.poll().unwrap(), ServerEvent::Body(_)));
899    /// assert!(matches!(conn.poll().unwrap(), ServerEvent::NeedInput));
900    /// assert_eq!(conn.progress(), Progress::Body);
901    /// let _ = conn.feed(b"cd");
902    /// while !matches!(conn.poll().unwrap(), ServerEvent::RequestEnd) {}
903    /// assert_eq!(conn.progress(), Progress::AwaitingResponse);
904    /// conn.respond(&Response::new(200).chunked(), &mut Vec::new()).unwrap();
905    /// assert_eq!(conn.progress(), Progress::WritingBody);
906    /// conn.end_body(&mut Vec::new()).unwrap();
907    /// assert_eq!(conn.progress(), Progress::Idle);
908    /// ```
909    #[must_use]
910    pub fn progress(&self) -> Progress {
911        if matches!(self.resp, RespState::Streaming(_)) {
912            return Progress::WritingBody;
913        }
914        match self.state {
915            ReqState::Head if self.buf.from(self.buf.pin()).is_empty() => Progress::Idle,
916            ReqState::Head => Progress::Head,
917            // Answered before `RequestEnd` was polled. An unread body closes
918            // the connection (`poll`); a read one (or none) is the same as
919            // `Complete`.
920            ReqState::Body if self.resp == RespState::Sent => {
921                if self.decoder.is_read() && self.keep_alive {
922                    Progress::Idle
923                } else {
924                    Progress::Closed
925                }
926            }
927            ReqState::Body if !self.decoder.is_read() => Progress::Body,
928            ReqState::Body => Progress::AwaitingResponse,
929            ReqState::Complete if self.resp != RespState::Sent => Progress::AwaitingResponse,
930            ReqState::Complete if self.keep_alive => Progress::Idle,
931            ReqState::Complete => Progress::Closed,
932            // One error response is still expected.
933            ReqState::Failed if self.resp == RespState::Idle => Progress::AwaitingResponse,
934            ReqState::Upgraded => Progress::Upgraded,
935            ReqState::Failed | ReqState::Closed => Progress::Closed,
936        }
937    }
938
939    /// When `true`, a request's trailer fields are kept (bounded by
940    /// [`Limits::max_trailer_fields`] and [`Limits::max_trailer_bytes`]) and
941    /// reported as [`ServerEvent::Trailers`] just before
942    /// [`ServerEvent::RequestEnd`]. When `false` (the default) they are
943    /// validated and discarded. Trailers never change how a message is
944    /// framed either way.
945    ///
946    /// # Examples
947    ///
948    /// ```
949    /// use http_net::{ServerConn, ServerEvent};
950    ///
951    /// let mut conn = ServerConn::new();
952    /// conn.set_report_trailers(true);
953    /// let _ = conn.feed(b"POST / HTTP/1.1\r\nHost: a\r\nTransfer-Encoding: chunked\r\n\r\n2\r\nhi\r\n0\r\nDigest: sha-256=x\r\n\r\n");
954    /// let mut digest = None;
955    /// loop {
956    ///     match conn.poll().unwrap() {
957    ///         ServerEvent::Trailers(t) => digest = t.clone().find(|(n, _)| n.eq_ignore_ascii_case("digest")).map(|(_, v)| v.to_vec()),
958    ///         ServerEvent::RequestEnd => break,
959    ///         _ => {}
960    ///     }
961    /// }
962    /// assert_eq!(digest.as_deref(), Some(&b"sha-256=x"[..]));
963    /// ```
964    pub fn set_report_trailers(&mut self, report: bool) {
965        self.report_trailers = report;
966    }
967
968    /// Returns the connection to its initial state for a new socket,
969    /// keeping the buffer and field-index allocations (and the limits,
970    /// [`set_report_trailers`](Self::set_report_trailers), and
971    /// [`set_wipe`](Self::set_wipe) settings). Everything per connection
972    /// starts over: buffered input, the request in progress, keep-alive
973    /// (allowed again), and the request count. With wiping on, the whole
974    /// buffer is zeroed first.
975    ///
976    /// # Examples
977    ///
978    /// ```
979    /// use http_net::{Progress, ServerConn, ServerEvent};
980    ///
981    /// let mut conn = ServerConn::new();
982    /// let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\n\r\nGET /next");
983    /// assert!(matches!(conn.poll().unwrap(), ServerEvent::Request(_)));
984    /// conn.reset(); // the socket closed; reuse the object for the next one
985    /// assert_eq!(conn.progress(), Progress::Idle);
986    /// assert!(conn.remaining_input().is_empty());
987    /// ```
988    pub fn reset(&mut self) {
989        self.buf.reset();
990        self.buf.pin_at_pos();
991        self.scanner.reset();
992        self.trailers.reset();
993        self.decoder = Decoder::new();
994        self.info = RequestInfo::EMPTY;
995        self.state = ReqState::Head;
996        self.resp = RespState::Idle;
997        self.keep_alive = false;
998        self.allow_keep_alive = true;
999        self.continue_sent = false;
1000        self.body_seen = false;
1001        self.resp_chunked = false;
1002        self.requests_served = 0;
1003        self.preface_undecided = true;
1004    }
1005
1006    /// Gives the input buffer's storage back (for a pool), wiped first when
1007    /// [`set_wipe`](Self::set_wipe) is on.
1008    ///
1009    /// # Examples
1010    ///
1011    /// ```
1012    /// let conn = http_net::ServerConn::new();
1013    /// assert_eq!(conn.into_buffer().capacity(), 0); // nothing was ever buffered
1014    /// ```
1015    #[must_use]
1016    pub fn into_buffer(mut self) -> Vec<u8> {
1017        self.buf.take_storage()
1018    }
1019
1020    /// Frees the input buffer and the field indexes while the connection is
1021    /// idle between requests with nothing buffered, so thousands of idle
1022    /// keep-alive connections cost only their struct size. Returns whether
1023    /// memory was released; the next input allocates again.
1024    ///
1025    /// # Examples
1026    ///
1027    /// ```
1028    /// use http_net::{Response, ServerConn, ServerEvent};
1029    ///
1030    /// let mut conn = ServerConn::new();
1031    /// let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\n\r\n");
1032    /// assert!(matches!(conn.poll().unwrap(), ServerEvent::Request(_)));
1033    /// assert!(!conn.shrink_idle()); // a request is in progress
1034    /// assert!(matches!(conn.poll().unwrap(), ServerEvent::RequestEnd));
1035    /// conn.respond(&Response::new(204), &mut Vec::new()).unwrap();
1036    /// assert!(matches!(conn.poll().unwrap(), ServerEvent::NeedInput));
1037    /// assert!(conn.shrink_idle());
1038    /// ```
1039    pub fn shrink_idle(&mut self) -> bool {
1040        if self.progress() != Progress::Idle || self.state != ReqState::Head {
1041            return false;
1042        }
1043        self.buf.unpin();
1044        let freed = self.buf.shrink();
1045        self.buf.pin_at_pos();
1046        if freed {
1047            self.scanner.fields = Vec::new();
1048            self.trailers.fields = Vec::new();
1049        }
1050        freed
1051    }
1052
1053    /// When `true`, the bytes of every finished request (head, body, and
1054    /// framing) are zeroed before the buffer is reused, stale copies left by
1055    /// compaction are zeroed, and the whole buffer is zeroed on
1056    /// [`reset`](Self::reset), [`into_buffer`](Self::into_buffer), and drop,
1057    /// so credentials do not linger in memory between requests. Costs a
1058    /// `memset` of each request's bytes (about 11 ns per KiB, measured). Off
1059    /// by default.
1060    ///
1061    /// # Examples
1062    ///
1063    /// ```
1064    /// let mut conn = http_net::ServerConn::new();
1065    /// conn.set_wipe(true);
1066    /// ```
1067    pub fn set_wipe(&mut self, wipe: bool) {
1068        self.buf.set_wipe(wipe);
1069    }
1070
1071    #[inline]
1072    pub(crate) fn respond_dated<O: Output + ?Sized>(
1073        &mut self,
1074        response: &Response,
1075        date: Option<&[u8]>,
1076        out: &mut O,
1077    ) -> Result<(), HttpError> {
1078        let plan = self.start_response(response, date, out)?;
1079        if plan == BodyPlan::Raw {
1080            if let OutBody::Full(body) = &response.body {
1081                out.put(body);
1082            }
1083        }
1084        Ok(())
1085    }
1086
1087    /// Validates and writes a response head, and moves the connection to
1088    /// the state it implies: the one code path behind `respond`,
1089    /// `respond_into`, and `write_head`. Nothing is written on error.
1090    // Forced inline: called from several entry points, it otherwise stays
1091    // out of line and `respond` measured about 7% slower than in 0.4.
1092    #[inline(always)]
1093    pub(crate) fn start_response<S: HeadSource + ?Sized, O: Output + ?Sized>(
1094        &mut self,
1095        spec: &S,
1096        date: Option<&[u8]>,
1097        out: &mut O,
1098    ) -> Result<BodyPlan, HttpError> {
1099        // Builder errors (a Response) or field errors (a borrowed head)
1100        // come first, as when a Response is written.
1101        let has_date = spec.check()?;
1102        let failed = self.state == ReqState::Failed;
1103        match self.state {
1104            ReqState::Body | ReqState::Complete | ReqState::Failed => {}
1105            ReqState::Head => return Err(HttpError::InvalidState("no request to respond to")),
1106            ReqState::Upgraded | ReqState::Closed => {
1107                return Err(HttpError::InvalidState(
1108                    "the connection is closed or upgraded",
1109                ));
1110            }
1111        }
1112        if self.resp != RespState::Idle {
1113            return Err(HttpError::InvalidState("a response was already started"));
1114        }
1115        let (status, body, upgrade) = (spec.status(), spec.body(), spec.upgrade());
1116        if !(100..=599).contains(&status) || ((100..200).contains(&status) && status != 101) {
1117            return Err(HttpError::InvalidStatus);
1118        }
1119        if upgrade.is_some() && status != 101 {
1120            return Err(HttpError::InvalidState(
1121                "an upgrade protocol needs status 101",
1122            ));
1123        }
1124        let (method, version) = if failed {
1125            // An answer to `HEAD` carries no content (RFC 9110 section
1126            // 9.3.2); anything else, or no request line yet, is a `GET`.
1127            let method = if self.request_line_is_head() {
1128                Method::Head
1129            } else {
1130                Method::Get
1131            };
1132            (method, Version::Http11)
1133        } else {
1134            (self.info.method, self.info.version)
1135        };
1136        let bodiless = (100..200).contains(&status) || status == 204 || status == 304;
1137        let tunnel = status == 101 || (method == Method::Connect && (200..300).contains(&status));
1138        if (bodiless || tunnel) && !matches!(body, OutgoingBody::Empty | OutgoingBody::Full(0)) {
1139            return Err(HttpError::BodyNotAllowed);
1140        }
1141        if tunnel {
1142            let complete_upgrade =
1143                self.body_read() && (self.info.upgrade || method == Method::Connect);
1144            if !complete_upgrade || (status == 101 && upgrade.is_none()) || failed {
1145                return Err(HttpError::InvalidState(
1146                    "101 (or 2xx to CONNECT) must answer a complete upgrade request; \
1147                     build it with Response::switching_protocols",
1148                ));
1149            }
1150            // RFC 9110 section 7.8: never switch to a protocol the client
1151            // did not offer.
1152            if status == 101 && !upgrade.is_some_and(|p| self.view().offers(p)) {
1153                return Err(HttpError::UpgradeNotOffered);
1154            }
1155        }
1156
1157        let mut close = failed
1158            || spec.close()
1159            || !self.keep_alive
1160            || !self.allow_keep_alive
1161            || !self.body_read();
1162        let head_only = method == Method::Head || bodiless || tunnel;
1163        self.resp_chunked = body == OutgoingBody::Chunked;
1164        let (mut encoder, declared) = match body {
1165            OutgoingBody::Empty => (Encoder::Length { remaining: 0 }, Some(0)),
1166            OutgoingBody::Full(n) | OutgoingBody::Length(n) => {
1167                (Encoder::Length { remaining: n }, Some(n))
1168            }
1169            OutgoingBody::Chunked if version == Version::Http10 => {
1170                close = true;
1171                (Encoder::CloseDelimited, None)
1172            }
1173            OutgoingBody::Chunked => (Encoder::Chunked, None),
1174        };
1175
1176        write_status_line(out, status);
1177        if !(bodiless || tunnel) {
1178            push_framing(out, encoder, declared);
1179        }
1180        if tunnel {
1181            close = false;
1182        } else if close {
1183            out.put(b"connection: close\r\n");
1184        } else if version == Version::Http10 {
1185            out.put(b"connection: keep-alive\r\n");
1186        }
1187        if let Some(date) = date.filter(|_| !has_date) {
1188            out.put(b"date: ");
1189            out.put(date);
1190            out.put(b"\r\n");
1191        }
1192        spec.write_fields(out);
1193        out.put(b"\r\n");
1194
1195        if head_only {
1196            encoder = Encoder::Discard;
1197        }
1198        self.keep_alive = !close;
1199        let plan = match body {
1200            OutgoingBody::Empty | OutgoingBody::Full(_) => {
1201                self.resp = RespState::Sent;
1202                self.requests_served += 1;
1203                match body {
1204                    OutgoingBody::Full(n) if n > 0 && !head_only => BodyPlan::Raw,
1205                    _ => BodyPlan::None,
1206                }
1207            }
1208            OutgoingBody::Length(_) | OutgoingBody::Chunked => {
1209                self.resp = RespState::Streaming(encoder);
1210                BodyPlan::Stream
1211            }
1212        };
1213        if tunnel {
1214            self.state = ReqState::Upgraded;
1215        } else if failed {
1216            self.state = ReqState::Closed;
1217        }
1218        Ok(plan)
1219    }
1220
1221    /// Whether the request being read or answered has a `HEAD` request
1222    /// line, including one whose head was not accepted (a failed head leaves
1223    /// `RequestInfo::EMPTY`, but the scanner still has its start line).
1224    pub(crate) fn request_line_is_head(&self) -> bool {
1225        self.info.method == Method::Head
1226            || self
1227                .scanner
1228                .start_line()
1229                .get(self.buf.from(self.buf.pin()))
1230                .starts_with(b"HEAD ")
1231    }
1232
1233    /// Body bytes of a streamed response, into any output.
1234    pub(crate) fn stream_body<O: Output + ?Sized>(
1235        &mut self,
1236        data: &[u8],
1237        out: &mut O,
1238    ) -> Result<(), HttpError> {
1239        match &mut self.resp {
1240            RespState::Streaming(encoder) => encoder.write(data, out),
1241            _ => Err(HttpError::InvalidState("no streamed response in progress")),
1242        }
1243    }
1244
1245    /// The end of a streamed response, with optional trailers, into any
1246    /// output.
1247    pub(crate) fn finish_body<O: Output + ?Sized>(
1248        &mut self,
1249        trailers: &[(&str, &[u8])],
1250        out: &mut O,
1251    ) -> Result<(), HttpError> {
1252        let RespState::Streaming(encoder) = &mut self.resp else {
1253            return Err(HttpError::InvalidState("no streamed response in progress"));
1254        };
1255        if !trailers.is_empty() && !self.resp_chunked {
1256            return Err(HttpError::TrailerNotAllowed);
1257        }
1258        match encoder {
1259            Encoder::Chunked => push_last_chunk_with_trailers(out, trailers)?,
1260            _ => {
1261                check_trailers(trailers)?;
1262                encoder.finish(out)?;
1263            }
1264        }
1265        if *encoder == Encoder::CloseDelimited {
1266            self.keep_alive = false;
1267        }
1268        self.resp = RespState::Sent;
1269        self.requests_served += 1;
1270        Ok(())
1271    }
1272
1273    /// Writes `HTTP/1.1 100 Continue` into `out`: the answer to
1274    /// [`RequestHead::expects_continue`](crate::RequestHead::expects_continue)
1275    /// that tells the client to send the body.
1276    ///
1277    /// RFC 9110 section 10.1.1 requires a server that receives
1278    /// `Expect: 100-continue` to send either this or a final response before
1279    /// waiting for the body; clients otherwise stall (curl for one second,
1280    /// some indefinitely). Call it after [`ServerEvent::Request`], once the
1281    /// head has been judged acceptable.
1282    ///
1283    /// # Errors
1284    ///
1285    /// [`HttpError::InterimNotAllowed`] for an HTTP/1.0 request (RFC 9110
1286    /// section 15.2 forbids any 1xx to an HTTP/1.0 client), once a body byte
1287    /// has been read or the whole body has arrived, once a response has
1288    /// started, or when `100 Continue` was already sent for this request;
1289    /// [`HttpError::InvalidState`] when no request is waiting for its body
1290    /// (none has arrived, or the connection failed, closed, or upgraded).
1291    ///
1292    /// # Examples
1293    ///
1294    /// ```
1295    /// use http_net::{ServerConn, ServerEvent};
1296    ///
1297    /// let mut conn = ServerConn::new();
1298    /// let _ = conn.feed(b"PUT /f HTTP/1.1\r\nHost: a\r\nExpect: 100-continue\r\nContent-Length: 2\r\n\r\n");
1299    /// let ServerEvent::Request(req) = conn.poll()? else { unreachable!() };
1300    /// assert!(req.expects_continue());
1301    /// let mut out = Vec::new();
1302    /// conn.send_continue(&mut out)?;
1303    /// assert_eq!(out, b"HTTP/1.1 100 Continue\r\n\r\n");
1304    /// # Ok::<(), http_net::HttpError>(())
1305    /// ```
1306    pub fn send_continue(&mut self, out: &mut Vec<u8>) -> Result<(), HttpError> {
1307        if !matches!(self.state, ReqState::Body | ReqState::Complete) {
1308            return Err(HttpError::InvalidState(
1309                "100 Continue needs a request whose body is still to come",
1310            ));
1311        }
1312        if self.state == ReqState::Complete
1313            || self.decoder.is_read()
1314            || self.body_seen
1315            || self.resp != RespState::Idle
1316            || self.info.version != Version::Http11
1317            || self.continue_sent
1318        {
1319            return Err(HttpError::InterimNotAllowed);
1320        }
1321        self.continue_sent = true;
1322        out.extend_from_slice(b"HTTP/1.1 100 Continue\r\n\r\n");
1323        Ok(())
1324    }
1325
1326    /// Writes body bytes of a streamed response into `out`. For a `HEAD`
1327    /// request the bytes are dropped.
1328    ///
1329    /// # Errors
1330    ///
1331    /// [`HttpError::BodyLengthMismatch`] past the declared
1332    /// [`Response::content_length`]; [`HttpError::InvalidState`] when no
1333    /// streamed response is in progress.
1334    ///
1335    /// # Examples
1336    ///
1337    /// ```
1338    /// use http_net::{Response, ServerConn, ServerEvent};
1339    ///
1340    /// let mut conn = ServerConn::new();
1341    /// let _ = conn.feed(b"GET /log HTTP/1.1\r\nHost: a\r\n\r\n");
1342    /// while !matches!(conn.poll().unwrap(), ServerEvent::RequestEnd) {}
1343    /// let mut out = Vec::new();
1344    /// conn.respond(&Response::new(200).chunked(), &mut out).unwrap();
1345    /// conn.send_body(b"line 1\n", &mut out).unwrap();
1346    /// conn.end_body(&mut out).unwrap();
1347    /// assert!(out.ends_with(b"7\r\nline 1\n\r\n0\r\n\r\n"));
1348    /// ```
1349    pub fn send_body(&mut self, data: &[u8], out: &mut Vec<u8>) -> Result<(), HttpError> {
1350        self.stream_body(data, out)
1351    }
1352
1353    /// Ends a streamed response body (the last chunk for chunked encoding).
1354    ///
1355    /// # Errors
1356    ///
1357    /// [`HttpError::BodyLengthMismatch`] when fewer bytes than the declared
1358    /// length were sent; [`HttpError::InvalidState`] when no streamed
1359    /// response is in progress.
1360    ///
1361    /// # Examples
1362    ///
1363    /// ```
1364    /// use http_net::{HttpError, Response, ServerConn, ServerEvent};
1365    ///
1366    /// let mut conn = ServerConn::new();
1367    /// let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\n\r\n");
1368    /// while !matches!(conn.poll().unwrap(), ServerEvent::RequestEnd) {}
1369    /// let mut out = Vec::new();
1370    /// conn.respond(&Response::new(200).content_length(3), &mut out).unwrap();
1371    /// conn.send_body(b"ab", &mut out).unwrap();
1372    /// assert_eq!(conn.end_body(&mut out), Err(HttpError::BodyLengthMismatch));
1373    /// ```
1374    pub fn end_body(&mut self, out: &mut Vec<u8>) -> Result<(), HttpError> {
1375        self.end_body_with_trailers(&[], out)
1376    }
1377
1378    /// Ends a streamed chunked body with a trailer section: the last chunk,
1379    /// then `trailers` as fields. Every field is validated before anything
1380    /// is written.
1381    ///
1382    /// Trailers are optional metadata a recipient may discard (RFC 9110
1383    /// section 6.5), so when the body could not be chunked (an HTTP/1.0
1384    /// client forced a close-delimited body) or is not sent at all (`HEAD`),
1385    /// they are dropped with it and the call still succeeds: the handler
1386    /// does not need to know which framing the client forced.
1387    ///
1388    /// # Errors
1389    ///
1390    /// [`HttpError::TrailerNotAllowed`] for a field RFC 9110 section 6.5.1
1391    /// keeps out of trailers (framing, routing, authentication, request
1392    /// modifiers, response control, content handling: `content-length`,
1393    /// `host`, `authorization`, `set-cookie`, `content-type`, `date`, and
1394    /// the rest of the list in `docs/API.md`) or for a body declared with
1395    /// [`Response::content_length`]; the field errors of
1396    /// [`Response::header`]; [`HttpError::BodyLengthMismatch`] and
1397    /// [`HttpError::InvalidState`] as for [`end_body`](Self::end_body).
1398    ///
1399    /// # Examples
1400    ///
1401    /// ```
1402    /// use http_net::{HttpError, Response, ServerConn, ServerEvent};
1403    ///
1404    /// let mut conn = ServerConn::new();
1405    /// let _ = conn.feed(b"GET /data HTTP/1.1\r\nHost: a\r\nTE: trailers\r\n\r\n");
1406    /// while !matches!(conn.poll().unwrap(), ServerEvent::RequestEnd) {}
1407    /// let mut out = Vec::new();
1408    /// conn.respond(&Response::new(200).chunked(), &mut out)?;
1409    /// conn.send_body(b"rows", &mut out)?;
1410    /// assert_eq!(
1411    ///     conn.end_body_with_trailers(&[("content-type", b"text/csv")], &mut out),
1412    ///     Err(HttpError::TrailerNotAllowed)
1413    /// );
1414    /// conn.end_body_with_trailers(&[("server-timing", b"db;dur=53")], &mut out)?;
1415    /// assert!(out.ends_with(b"4\r\nrows\r\n0\r\nserver-timing: db;dur=53\r\n\r\n"));
1416    /// # Ok::<(), http_net::HttpError>(())
1417    /// ```
1418    pub fn end_body_with_trailers(
1419        &mut self,
1420        trailers: &[(&str, &[u8])],
1421        out: &mut Vec<u8>,
1422    ) -> Result<(), HttpError> {
1423        self.finish_body(trailers, out)
1424    }
1425}
1426
1427/// A response head to write: a [`Response`], whose fields its builder
1428/// already serialized and checked, or a
1429/// [`ResponseHeadRef`](crate::ResponseHeadRef), whose borrowed fields are
1430/// checked here. `start_response` is generic over it, so each source gets
1431/// its own compiled path with no runtime dispatch.
1432pub(crate) trait HeadSource {
1433    fn status(&self) -> u16;
1434    fn body(&self) -> OutgoingBody;
1435    fn close(&self) -> bool;
1436    /// The protocol of a 101.
1437    fn upgrade(&self) -> Option<&[u8]>;
1438    /// Validates what the builder did not: returns whether a `date` field
1439    /// is set.
1440    fn check(&self) -> Result<bool, HttpError>;
1441    fn write_fields<O: Output + ?Sized>(&self, out: &mut O);
1442}
1443
1444impl HeadSource for Response {
1445    #[inline]
1446    fn status(&self) -> u16 {
1447        Response::status(self)
1448    }
1449
1450    #[inline]
1451    fn body(&self) -> OutgoingBody {
1452        match &self.body {
1453            OutBody::Full(b) => OutgoingBody::Full(b.len() as u64),
1454            OutBody::Length(n) => OutgoingBody::Length(*n),
1455            OutBody::Chunked => OutgoingBody::Chunked,
1456        }
1457    }
1458
1459    #[inline]
1460    fn close(&self) -> bool {
1461        self.close
1462    }
1463
1464    #[inline]
1465    fn upgrade(&self) -> Option<&[u8]> {
1466        self.upgrade_protocol()
1467    }
1468
1469    #[inline]
1470    fn check(&self) -> Result<bool, HttpError> {
1471        match self.error() {
1472            Some(e) => Err(e),
1473            None => Ok(self.has_date),
1474        }
1475    }
1476
1477    #[inline]
1478    fn write_fields<O: Output + ?Sized>(&self, out: &mut O) {
1479        out.put(self.fields());
1480    }
1481}
1482
1483impl HeadSource for ResponseHeadRef<'_> {
1484    #[inline]
1485    fn status(&self) -> u16 {
1486        self.status
1487    }
1488
1489    #[inline]
1490    fn body(&self) -> OutgoingBody {
1491        self.body
1492    }
1493
1494    #[inline]
1495    fn close(&self) -> bool {
1496        self.close
1497    }
1498
1499    #[inline]
1500    fn upgrade(&self) -> Option<&[u8]> {
1501        self.upgrade.map(str::as_bytes)
1502    }
1503
1504    fn check(&self) -> Result<bool, HttpError> {
1505        if let Some(protocol) = self.upgrade {
1506            check_upgrade_protocol(protocol.as_bytes())?;
1507        }
1508        let mut has_date = false;
1509        for &(name, value) in self.fields {
1510            has_date |= check_response_field(name, value)?;
1511        }
1512        Ok(has_date)
1513    }
1514
1515    fn write_fields<O: Output + ?Sized>(&self, out: &mut O) {
1516        if let Some(protocol) = self.upgrade {
1517            // The same lines, in the same place, as
1518            // Response::switching_protocols writes.
1519            out.put(b"connection: upgrade\r\nupgrade: ");
1520            out.put(protocol.as_bytes());
1521            out.put(b"\r\n");
1522        }
1523        for &(name, value) in self.fields {
1524            write_field(out, name, value);
1525        }
1526    }
1527}
1528
1529#[cfg(test)]
1530mod tests {
1531    use alloc::vec;
1532
1533    use super::*;
1534
1535    fn events(conn: &mut ServerConn) -> Vec<alloc::string::String> {
1536        let mut log = Vec::new();
1537        loop {
1538            match conn.poll() {
1539                Ok(ServerEvent::Request(r)) => log.push(alloc::format!("req {}", r.target())),
1540                Ok(ServerEvent::Body(b)) => log.push(alloc::format!("body {}", b.len())),
1541                Ok(ServerEvent::RequestEnd) => {
1542                    log.push("end".into());
1543                    return log;
1544                }
1545                Ok(other) => {
1546                    log.push(alloc::format!("{other:?}"));
1547                    return log;
1548                }
1549                Err(e) => {
1550                    log.push(alloc::format!("err {e:?}"));
1551                    return log;
1552                }
1553            }
1554        }
1555    }
1556
1557    #[test]
1558    fn test_early_response_closes_connection() {
1559        let mut conn = ServerConn::new();
1560        let _ = conn.feed(b"POST / HTTP/1.1\r\nHost: a\r\nContent-Length: 10\r\n\r\nab");
1561        assert!(matches!(conn.poll(), Ok(ServerEvent::Request(_))));
1562        let mut out = Vec::new();
1563        conn.respond(&Response::new(413), &mut out).unwrap();
1564        assert!(out.windows(17).any(|w| w == b"connection: close"));
1565        assert!(matches!(conn.poll(), Ok(ServerEvent::Closed)));
1566    }
1567
1568    #[test]
1569    fn test_respond_after_failure_is_once_and_closes() {
1570        let mut conn = ServerConn::new();
1571        let _ = conn.feed(b"GET / HTTP/1.1\r\n\r\n");
1572        assert_eq!(conn.poll().unwrap_err(), HttpError::MissingHost);
1573        let mut out = Vec::new();
1574        conn.respond(&Response::new(400), &mut out).unwrap();
1575        assert!(out.starts_with(b"HTTP/1.1 400 Bad Request\r\n"));
1576        assert!(conn.respond(&Response::new(400), &mut out).is_err());
1577        assert!(matches!(conn.poll(), Ok(ServerEvent::Closed)));
1578    }
1579
1580    #[test]
1581    fn test_state_errors() {
1582        let mut conn = ServerConn::new();
1583        let mut out = Vec::new();
1584        assert!(matches!(
1585            conn.respond(&Response::new(200), &mut out),
1586            Err(HttpError::InvalidState(_))
1587        ));
1588        assert!(matches!(
1589            conn.send_body(b"x", &mut out),
1590            Err(HttpError::InvalidState(_))
1591        ));
1592        assert!(matches!(
1593            conn.end_body(&mut out),
1594            Err(HttpError::InvalidState(_))
1595        ));
1596        let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\n\r\n");
1597        assert_eq!(events(&mut conn), vec!["req /", "end"]);
1598        assert_eq!(
1599            conn.respond(&Response::new(99), &mut out),
1600            Err(HttpError::InvalidStatus)
1601        );
1602        assert_eq!(
1603            conn.respond(&Response::new(100), &mut out),
1604            Err(HttpError::InvalidStatus)
1605        );
1606        assert_eq!(
1607            conn.respond(&Response::new(204).body(&b"x"[..]), &mut out),
1608            Err(HttpError::BodyNotAllowed)
1609        );
1610        assert!(matches!(
1611            conn.respond(&Response::switching_protocols("x"), &mut out),
1612            Err(HttpError::InvalidState(_))
1613        ));
1614        conn.respond(&Response::new(204), &mut out).unwrap();
1615        assert!(matches!(
1616            conn.respond(&Response::new(200), &mut out),
1617            Err(HttpError::InvalidState(_))
1618        ));
1619    }
1620
1621    #[test]
1622    fn test_http10_keep_alive_and_chunked_fallback() {
1623        let mut conn = ServerConn::new();
1624        let _ = conn.feed(b"GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n");
1625        assert_eq!(events(&mut conn), vec!["req /", "end"]);
1626        let mut out = Vec::new();
1627        conn.respond(&Response::text(200, "x"), &mut out).unwrap();
1628        assert!(out.windows(22).any(|w| w == b"connection: keep-alive"));
1629        assert!(matches!(conn.poll(), Ok(ServerEvent::NeedInput)));
1630
1631        let _ = conn.feed(b"GET / HTTP/1.0\r\n\r\n");
1632        assert_eq!(events(&mut conn), vec!["req /", "end"]);
1633        let mut out = Vec::new();
1634        conn.respond(&Response::new(200).chunked(), &mut out)
1635            .unwrap();
1636        conn.send_body(b"abc", &mut out).unwrap();
1637        conn.end_body(&mut out).unwrap();
1638        assert!(out.ends_with(b"\r\n\r\nabc"));
1639        assert!(!out.windows(17).any(|w| w == b"transfer-encoding"));
1640        assert!(matches!(conn.poll(), Ok(ServerEvent::Closed)));
1641    }
1642
1643    fn upgrade_request(conn: &mut ServerConn, offer: &str) {
1644        let msg = alloc::format!(
1645            "GET / HTTP/1.1\r\nHost: a\r\nConnection: upgrade\r\nUpgrade: {offer}\r\n\r\n"
1646        );
1647        let _ = conn.feed(msg.as_bytes());
1648        assert_eq!(events(conn), vec!["req /", "end"]);
1649    }
1650
1651    #[test]
1652    fn test_switching_protocols_must_name_an_offered_protocol() {
1653        let mut conn = ServerConn::new();
1654        upgrade_request(&mut conn, "websocket/13, foo/2");
1655        let mut out = Vec::new();
1656        // `foo` alone would match `foo/2`: a name without a version
1657        // answers an offer of that name with any version.
1658        for refused in ["ftp", "foo/3", "websocket/12", "h2c"] {
1659            assert_eq!(
1660                conn.respond(&Response::switching_protocols(refused), &mut out),
1661                Err(HttpError::UpgradeNotOffered),
1662                "{refused}"
1663            );
1664            assert!(out.is_empty());
1665            assert!(!conn.is_upgraded());
1666        }
1667        conn.respond(&Response::switching_protocols("WebSocket"), &mut out)
1668            .unwrap();
1669        assert!(conn.is_upgraded());
1670        assert!(out.windows(18).any(|w| w == b"upgrade: WebSocket"));
1671    }
1672
1673    #[test]
1674    fn test_refused_switch_leaves_a_normal_response_possible() {
1675        let mut conn = ServerConn::new();
1676        upgrade_request(&mut conn, "websocket");
1677        let mut out = Vec::new();
1678        assert_eq!(
1679            conn.respond(&Response::switching_protocols("irc"), &mut out),
1680            Err(HttpError::UpgradeNotOffered)
1681        );
1682        conn.respond(&Response::new(426), &mut out).unwrap();
1683        assert!(out.starts_with(b"HTTP/1.1 426 Upgrade Required\r\n"));
1684        assert!(matches!(conn.poll(), Ok(ServerEvent::NeedInput)));
1685    }
1686
1687    #[test]
1688    fn test_h2c_only_offer_is_served_as_http11() {
1689        let mut conn = ServerConn::new();
1690        let _ = conn.feed(
1691            b"GET / HTTP/1.1\r\nHost: a\r\nConnection: Upgrade, HTTP2-Settings\r\nUpgrade: h2c\r\nHTTP2-Settings: AAMAAABkAAQAoAAA\r\n\r\n",
1692        );
1693        assert!(matches!(conn.poll(), Ok(ServerEvent::Request(r)) if !r.is_upgrade()));
1694        assert!(matches!(conn.poll(), Ok(ServerEvent::RequestEnd)));
1695        let mut out = Vec::new();
1696        assert!(matches!(
1697            conn.respond(&Response::switching_protocols("websocket"), &mut out),
1698            Err(HttpError::InvalidState(_))
1699        ));
1700        conn.respond(&Response::new(200), &mut out).unwrap();
1701        assert!(matches!(conn.poll(), Ok(ServerEvent::NeedInput)));
1702    }
1703
1704    #[test]
1705    fn test_unregistered_status_keeps_the_space_before_an_empty_reason() {
1706        let mut conn = ServerConn::new();
1707        let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\n\r\n");
1708        assert_eq!(events(&mut conn), vec!["req /", "end"]);
1709        let mut out = Vec::new();
1710        conn.respond(&Response::new(299), &mut out).unwrap();
1711        assert!(out.starts_with(b"HTTP/1.1 299 \r\n"));
1712    }
1713
1714    #[test]
1715    fn test_connect_tunnel() {
1716        let mut conn = ServerConn::new();
1717        let _ = conn.feed(b"CONNECT example.com:443 HTTP/1.1\r\nHost: example.com:443\r\n\r\nTLS");
1718        assert_eq!(events(&mut conn), vec!["req example.com:443", "end"]);
1719        let mut out = Vec::new();
1720        conn.respond(&Response::new(200), &mut out).unwrap();
1721        assert_eq!(out, b"HTTP/1.1 200 OK\r\n\r\n");
1722        assert!(matches!(conn.poll(), Ok(ServerEvent::Upgraded)));
1723        assert_eq!(conn.remaining_input(), b"TLS");
1724        assert!(conn.request().is_some());
1725    }
1726}