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