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}