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