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