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 ReqState::Body if self.resp == RespState::Sent => Progress::Closed,
892 ReqState::Body if !self.decoder.is_read() => Progress::Body,
893 ReqState::Body => Progress::AwaitingResponse,
894 ReqState::Complete if self.resp != RespState::Sent => Progress::AwaitingResponse,
895 ReqState::Complete if self.keep_alive => Progress::Idle,
896 ReqState::Complete => Progress::Closed,
897 // One error response is still expected.
898 ReqState::Failed if self.resp == RespState::Idle => Progress::AwaitingResponse,
899 ReqState::Upgraded => Progress::Upgraded,
900 ReqState::Failed | ReqState::Closed => Progress::Closed,
901 }
902 }
903
904 /// When `true`, a request's trailer fields are kept (bounded by
905 /// [`Limits::max_trailer_fields`] and [`Limits::max_trailer_bytes`]) and
906 /// reported as [`ServerEvent::Trailers`] just before
907 /// [`ServerEvent::RequestEnd`]. When `false` (the default) they are
908 /// validated and discarded. Trailers never change how a message is
909 /// framed either way.
910 ///
911 /// # Examples
912 ///
913 /// ```
914 /// use http_net::{ServerConn, ServerEvent};
915 ///
916 /// let mut conn = ServerConn::new();
917 /// conn.set_report_trailers(true);
918 /// 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");
919 /// let mut digest = None;
920 /// loop {
921 /// match conn.poll().unwrap() {
922 /// ServerEvent::Trailers(t) => digest = t.clone().find(|(n, _)| n.eq_ignore_ascii_case("digest")).map(|(_, v)| v.to_vec()),
923 /// ServerEvent::RequestEnd => break,
924 /// _ => {}
925 /// }
926 /// }
927 /// assert_eq!(digest.as_deref(), Some(&b"sha-256=x"[..]));
928 /// ```
929 pub fn set_report_trailers(&mut self, report: bool) {
930 self.report_trailers = report;
931 }
932
933 /// Returns the connection to its initial state for a new socket,
934 /// keeping the buffer and field-index allocations (and the limits,
935 /// [`set_report_trailers`](Self::set_report_trailers), and
936 /// [`set_wipe`](Self::set_wipe) settings). Everything per connection
937 /// starts over: buffered input, the request in progress, keep-alive
938 /// (allowed again), and the request count. With wiping on, the whole
939 /// buffer is zeroed first.
940 ///
941 /// # Examples
942 ///
943 /// ```
944 /// use http_net::{Progress, ServerConn, ServerEvent};
945 ///
946 /// let mut conn = ServerConn::new();
947 /// let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\n\r\nGET /next");
948 /// assert!(matches!(conn.poll().unwrap(), ServerEvent::Request(_)));
949 /// conn.reset(); // the socket closed; reuse the object for the next one
950 /// assert_eq!(conn.progress(), Progress::Idle);
951 /// assert!(conn.remaining_input().is_empty());
952 /// ```
953 pub fn reset(&mut self) {
954 self.buf.reset();
955 self.buf.pin_at_pos();
956 self.scanner.reset();
957 self.trailers.reset();
958 self.decoder = Decoder::new();
959 self.info = RequestInfo::EMPTY;
960 self.state = ReqState::Head;
961 self.resp = RespState::Idle;
962 self.keep_alive = false;
963 self.allow_keep_alive = true;
964 self.continue_sent = false;
965 self.body_seen = false;
966 self.resp_chunked = false;
967 self.requests_served = 0;
968 self.preface_undecided = true;
969 }
970
971 /// Gives the input buffer's storage back (for a pool), wiped first when
972 /// [`set_wipe`](Self::set_wipe) is on.
973 ///
974 /// # Examples
975 ///
976 /// ```
977 /// let conn = http_net::ServerConn::new();
978 /// assert_eq!(conn.into_buffer().capacity(), 0); // nothing was ever buffered
979 /// ```
980 #[must_use]
981 pub fn into_buffer(mut self) -> Vec<u8> {
982 self.buf.take_storage()
983 }
984
985 /// Frees the input buffer and the field indexes while the connection is
986 /// idle between requests with nothing buffered, so thousands of idle
987 /// keep-alive connections cost only their struct size. Returns whether
988 /// memory was released; the next input allocates again.
989 ///
990 /// # Examples
991 ///
992 /// ```
993 /// use http_net::{Response, ServerConn, ServerEvent};
994 ///
995 /// let mut conn = ServerConn::new();
996 /// let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\n\r\n");
997 /// assert!(matches!(conn.poll().unwrap(), ServerEvent::Request(_)));
998 /// assert!(!conn.shrink_idle()); // a request is in progress
999 /// assert!(matches!(conn.poll().unwrap(), ServerEvent::RequestEnd));
1000 /// conn.respond(&Response::new(204), &mut Vec::new()).unwrap();
1001 /// assert!(matches!(conn.poll().unwrap(), ServerEvent::NeedInput));
1002 /// assert!(conn.shrink_idle());
1003 /// ```
1004 pub fn shrink_idle(&mut self) -> bool {
1005 if self.progress() != Progress::Idle || self.state != ReqState::Head {
1006 return false;
1007 }
1008 self.buf.unpin();
1009 let freed = self.buf.shrink();
1010 self.buf.pin_at_pos();
1011 if freed {
1012 self.scanner.fields = Vec::new();
1013 self.trailers.fields = Vec::new();
1014 }
1015 freed
1016 }
1017
1018 /// When `true`, the bytes of every finished request (head, body, and
1019 /// framing) are zeroed before the buffer is reused, stale copies left by
1020 /// compaction are zeroed, and the whole buffer is zeroed on
1021 /// [`reset`](Self::reset), [`into_buffer`](Self::into_buffer), and drop,
1022 /// so credentials do not linger in memory between requests. Costs a
1023 /// `memset` of each request's bytes (about 30 to 60 ns for 2 KiB, an
1024 /// estimate). Off by default.
1025 ///
1026 /// # Examples
1027 ///
1028 /// ```
1029 /// let mut conn = http_net::ServerConn::new();
1030 /// conn.set_wipe(true);
1031 /// ```
1032 pub fn set_wipe(&mut self, wipe: bool) {
1033 self.buf.set_wipe(wipe);
1034 }
1035
1036 #[inline]
1037 pub(crate) fn respond_dated<O: Output + ?Sized>(
1038 &mut self,
1039 response: &Response,
1040 date: Option<&[u8]>,
1041 out: &mut O,
1042 ) -> Result<(), HttpError> {
1043 let plan = self.start_response(response, date, out)?;
1044 if plan == BodyPlan::Raw {
1045 if let OutBody::Full(body) = &response.body {
1046 out.put(body);
1047 }
1048 }
1049 Ok(())
1050 }
1051
1052 /// Validates and writes a response head, and moves the connection to
1053 /// the state it implies: the one code path behind `respond`,
1054 /// `respond_into`, and `write_head`. Nothing is written on error.
1055 // Forced inline: called from several entry points, it otherwise stays
1056 // out of line and `respond` measured about 7% slower than in 0.4.
1057 #[inline(always)]
1058 pub(crate) fn start_response<S: HeadSource + ?Sized, O: Output + ?Sized>(
1059 &mut self,
1060 spec: &S,
1061 date: Option<&[u8]>,
1062 out: &mut O,
1063 ) -> Result<BodyPlan, HttpError> {
1064 // Builder errors (a Response) or field errors (a borrowed head)
1065 // come first, as when a Response is written.
1066 let has_date = spec.check()?;
1067 let failed = self.state == ReqState::Failed;
1068 match self.state {
1069 ReqState::Body | ReqState::Complete | ReqState::Failed => {}
1070 ReqState::Head => return Err(HttpError::InvalidState("no request to respond to")),
1071 ReqState::Upgraded | ReqState::Closed => {
1072 return Err(HttpError::InvalidState(
1073 "the connection is closed or upgraded",
1074 ));
1075 }
1076 }
1077 if self.resp != RespState::Idle {
1078 return Err(HttpError::InvalidState("a response was already started"));
1079 }
1080 let (status, body, upgrade) = (spec.status(), spec.body(), spec.upgrade());
1081 if !(100..=599).contains(&status) || ((100..200).contains(&status) && status != 101) {
1082 return Err(HttpError::InvalidStatus);
1083 }
1084 if upgrade.is_some() && status != 101 {
1085 return Err(HttpError::InvalidState(
1086 "an upgrade protocol needs status 101",
1087 ));
1088 }
1089 let (method, version) = if failed {
1090 (Method::Get, Version::Http11)
1091 } else {
1092 (self.info.method, self.info.version)
1093 };
1094 let bodiless = (100..200).contains(&status) || status == 204 || status == 304;
1095 let tunnel = status == 101 || (method == Method::Connect && (200..300).contains(&status));
1096 if (bodiless || tunnel) && !matches!(body, OutgoingBody::Empty | OutgoingBody::Full(0)) {
1097 return Err(HttpError::BodyNotAllowed);
1098 }
1099 if tunnel {
1100 let complete_upgrade =
1101 self.body_read() && (self.info.upgrade || method == Method::Connect);
1102 if !complete_upgrade || (status == 101 && upgrade.is_none()) || failed {
1103 return Err(HttpError::InvalidState(
1104 "101 (or 2xx to CONNECT) must answer a complete upgrade request; \
1105 build it with Response::switching_protocols",
1106 ));
1107 }
1108 // RFC 9110 section 7.8: never switch to a protocol the client
1109 // did not offer.
1110 if status == 101 && !upgrade.is_some_and(|p| self.view().offers(p)) {
1111 return Err(HttpError::UpgradeNotOffered);
1112 }
1113 }
1114
1115 let mut close = failed
1116 || spec.close()
1117 || !self.keep_alive
1118 || !self.allow_keep_alive
1119 || !self.body_read();
1120 let head_only = method == Method::Head || bodiless || tunnel;
1121 self.resp_chunked = body == OutgoingBody::Chunked;
1122 let (mut encoder, declared) = match body {
1123 OutgoingBody::Empty => (Encoder::Length { remaining: 0 }, Some(0)),
1124 OutgoingBody::Full(n) | OutgoingBody::Length(n) => {
1125 (Encoder::Length { remaining: n }, Some(n))
1126 }
1127 OutgoingBody::Chunked if version == Version::Http10 => {
1128 close = true;
1129 (Encoder::CloseDelimited, None)
1130 }
1131 OutgoingBody::Chunked => (Encoder::Chunked, None),
1132 };
1133
1134 write_status_line(out, status);
1135 if !(bodiless || tunnel) {
1136 push_framing(out, encoder, declared);
1137 }
1138 if tunnel {
1139 close = false;
1140 } else if close {
1141 out.put(b"connection: close\r\n");
1142 } else if version == Version::Http10 {
1143 out.put(b"connection: keep-alive\r\n");
1144 }
1145 if let Some(date) = date.filter(|_| !has_date) {
1146 out.put(b"date: ");
1147 out.put(date);
1148 out.put(b"\r\n");
1149 }
1150 spec.write_fields(out);
1151 out.put(b"\r\n");
1152
1153 if head_only {
1154 encoder = Encoder::Discard;
1155 }
1156 self.keep_alive = !close;
1157 let plan = match body {
1158 OutgoingBody::Empty | OutgoingBody::Full(_) => {
1159 self.resp = RespState::Sent;
1160 self.requests_served += 1;
1161 match body {
1162 OutgoingBody::Full(n) if n > 0 && !head_only => BodyPlan::Raw,
1163 _ => BodyPlan::None,
1164 }
1165 }
1166 OutgoingBody::Length(_) | OutgoingBody::Chunked => {
1167 self.resp = RespState::Streaming(encoder);
1168 BodyPlan::Stream
1169 }
1170 };
1171 if tunnel {
1172 self.state = ReqState::Upgraded;
1173 } else if failed {
1174 self.state = ReqState::Closed;
1175 }
1176 Ok(plan)
1177 }
1178
1179 /// Body bytes of a streamed response, into any output.
1180 pub(crate) fn stream_body<O: Output + ?Sized>(
1181 &mut self,
1182 data: &[u8],
1183 out: &mut O,
1184 ) -> Result<(), HttpError> {
1185 match &mut self.resp {
1186 RespState::Streaming(encoder) => encoder.write(data, out),
1187 _ => Err(HttpError::InvalidState("no streamed response in progress")),
1188 }
1189 }
1190
1191 /// The end of a streamed response, with optional trailers, into any
1192 /// output.
1193 pub(crate) fn finish_body<O: Output + ?Sized>(
1194 &mut self,
1195 trailers: &[(&str, &[u8])],
1196 out: &mut O,
1197 ) -> Result<(), HttpError> {
1198 let RespState::Streaming(encoder) = &mut self.resp else {
1199 return Err(HttpError::InvalidState("no streamed response in progress"));
1200 };
1201 if !trailers.is_empty() && !self.resp_chunked {
1202 return Err(HttpError::TrailerNotAllowed);
1203 }
1204 match encoder {
1205 Encoder::Chunked => push_last_chunk_with_trailers(out, trailers)?,
1206 _ => {
1207 check_trailers(trailers)?;
1208 encoder.finish(out)?;
1209 }
1210 }
1211 if *encoder == Encoder::CloseDelimited {
1212 self.keep_alive = false;
1213 }
1214 self.resp = RespState::Sent;
1215 self.requests_served += 1;
1216 Ok(())
1217 }
1218
1219 /// Writes `HTTP/1.1 100 Continue` into `out`: the answer to
1220 /// [`RequestHead::expects_continue`](crate::RequestHead::expects_continue)
1221 /// that tells the client to send the body.
1222 ///
1223 /// RFC 9110 section 10.1.1 requires a server that receives
1224 /// `Expect: 100-continue` to send either this or a final response before
1225 /// waiting for the body; clients otherwise stall (curl for one second,
1226 /// some indefinitely). Call it after [`ServerEvent::Request`], once the
1227 /// head has been judged acceptable.
1228 ///
1229 /// # Errors
1230 ///
1231 /// [`HttpError::InterimNotAllowed`] for an HTTP/1.0 request (RFC 9110
1232 /// section 15.2 forbids any 1xx to an HTTP/1.0 client), once a body byte
1233 /// has been read or the whole body has arrived, once a response has
1234 /// started, or when `100 Continue` was already sent for this request;
1235 /// [`HttpError::InvalidState`] when no request is waiting for its body
1236 /// (none has arrived, or the connection failed, closed, or upgraded).
1237 ///
1238 /// # Examples
1239 ///
1240 /// ```
1241 /// use http_net::{ServerConn, ServerEvent};
1242 ///
1243 /// let mut conn = ServerConn::new();
1244 /// let _ = conn.feed(b"PUT /f HTTP/1.1\r\nHost: a\r\nExpect: 100-continue\r\nContent-Length: 2\r\n\r\n");
1245 /// let ServerEvent::Request(req) = conn.poll()? else { unreachable!() };
1246 /// assert!(req.expects_continue());
1247 /// let mut out = Vec::new();
1248 /// conn.send_continue(&mut out)?;
1249 /// assert_eq!(out, b"HTTP/1.1 100 Continue\r\n\r\n");
1250 /// # Ok::<(), http_net::HttpError>(())
1251 /// ```
1252 pub fn send_continue(&mut self, out: &mut Vec<u8>) -> Result<(), HttpError> {
1253 if !matches!(self.state, ReqState::Body | ReqState::Complete) {
1254 return Err(HttpError::InvalidState(
1255 "100 Continue needs a request whose body is still to come",
1256 ));
1257 }
1258 if self.state == ReqState::Complete
1259 || self.decoder.is_read()
1260 || self.body_seen
1261 || self.resp != RespState::Idle
1262 || self.info.version != Version::Http11
1263 || self.continue_sent
1264 {
1265 return Err(HttpError::InterimNotAllowed);
1266 }
1267 self.continue_sent = true;
1268 out.extend_from_slice(b"HTTP/1.1 100 Continue\r\n\r\n");
1269 Ok(())
1270 }
1271
1272 /// Writes body bytes of a streamed response into `out`. For a `HEAD`
1273 /// request the bytes are dropped.
1274 ///
1275 /// # Errors
1276 ///
1277 /// [`HttpError::BodyLengthMismatch`] past the declared
1278 /// [`Response::content_length`]; [`HttpError::InvalidState`] when no
1279 /// streamed response is in progress.
1280 ///
1281 /// # Examples
1282 ///
1283 /// ```
1284 /// use http_net::{Response, ServerConn, ServerEvent};
1285 ///
1286 /// let mut conn = ServerConn::new();
1287 /// let _ = conn.feed(b"GET /log HTTP/1.1\r\nHost: a\r\n\r\n");
1288 /// while !matches!(conn.poll().unwrap(), ServerEvent::RequestEnd) {}
1289 /// let mut out = Vec::new();
1290 /// conn.respond(&Response::new(200).chunked(), &mut out).unwrap();
1291 /// conn.send_body(b"line 1\n", &mut out).unwrap();
1292 /// conn.end_body(&mut out).unwrap();
1293 /// assert!(out.ends_with(b"7\r\nline 1\n\r\n0\r\n\r\n"));
1294 /// ```
1295 pub fn send_body(&mut self, data: &[u8], out: &mut Vec<u8>) -> Result<(), HttpError> {
1296 self.stream_body(data, out)
1297 }
1298
1299 /// Ends a streamed response body (the last chunk for chunked encoding).
1300 ///
1301 /// # Errors
1302 ///
1303 /// [`HttpError::BodyLengthMismatch`] when fewer bytes than the declared
1304 /// length were sent; [`HttpError::InvalidState`] when no streamed
1305 /// response is in progress.
1306 ///
1307 /// # Examples
1308 ///
1309 /// ```
1310 /// use http_net::{HttpError, Response, ServerConn, ServerEvent};
1311 ///
1312 /// let mut conn = ServerConn::new();
1313 /// let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\n\r\n");
1314 /// while !matches!(conn.poll().unwrap(), ServerEvent::RequestEnd) {}
1315 /// let mut out = Vec::new();
1316 /// conn.respond(&Response::new(200).content_length(3), &mut out).unwrap();
1317 /// conn.send_body(b"ab", &mut out).unwrap();
1318 /// assert_eq!(conn.end_body(&mut out), Err(HttpError::BodyLengthMismatch));
1319 /// ```
1320 pub fn end_body(&mut self, out: &mut Vec<u8>) -> Result<(), HttpError> {
1321 self.end_body_with_trailers(&[], out)
1322 }
1323
1324 /// Ends a streamed chunked body with a trailer section: the last chunk,
1325 /// then `trailers` as fields. Every field is validated before anything
1326 /// is written.
1327 ///
1328 /// Trailers are optional metadata a recipient may discard (RFC 9110
1329 /// section 6.5), so when the body could not be chunked (an HTTP/1.0
1330 /// client forced a close-delimited body) or is not sent at all (`HEAD`),
1331 /// they are dropped with it and the call still succeeds: the handler
1332 /// does not need to know which framing the client forced.
1333 ///
1334 /// # Errors
1335 ///
1336 /// [`HttpError::TrailerNotAllowed`] for a field RFC 9110 section 6.5.1
1337 /// keeps out of trailers (framing, routing, authentication, request
1338 /// modifiers, response control, content handling: `content-length`,
1339 /// `host`, `authorization`, `set-cookie`, `content-type`, `date`, and
1340 /// the rest of the list in `docs/API.md`) or for a body declared with
1341 /// [`Response::content_length`]; the field errors of
1342 /// [`Response::header`]; [`HttpError::BodyLengthMismatch`] and
1343 /// [`HttpError::InvalidState`] as for [`end_body`](Self::end_body).
1344 ///
1345 /// # Examples
1346 ///
1347 /// ```
1348 /// use http_net::{HttpError, Response, ServerConn, ServerEvent};
1349 ///
1350 /// let mut conn = ServerConn::new();
1351 /// let _ = conn.feed(b"GET /data HTTP/1.1\r\nHost: a\r\nTE: trailers\r\n\r\n");
1352 /// while !matches!(conn.poll().unwrap(), ServerEvent::RequestEnd) {}
1353 /// let mut out = Vec::new();
1354 /// conn.respond(&Response::new(200).chunked(), &mut out)?;
1355 /// conn.send_body(b"rows", &mut out)?;
1356 /// assert_eq!(
1357 /// conn.end_body_with_trailers(&[("content-type", b"text/csv")], &mut out),
1358 /// Err(HttpError::TrailerNotAllowed)
1359 /// );
1360 /// conn.end_body_with_trailers(&[("server-timing", b"db;dur=53")], &mut out)?;
1361 /// assert!(out.ends_with(b"4\r\nrows\r\n0\r\nserver-timing: db;dur=53\r\n\r\n"));
1362 /// # Ok::<(), http_net::HttpError>(())
1363 /// ```
1364 pub fn end_body_with_trailers(
1365 &mut self,
1366 trailers: &[(&str, &[u8])],
1367 out: &mut Vec<u8>,
1368 ) -> Result<(), HttpError> {
1369 self.finish_body(trailers, out)
1370 }
1371}
1372
1373/// A response head to write: a [`Response`], whose fields its builder
1374/// already serialized and checked, or a
1375/// [`ResponseHeadRef`](crate::ResponseHeadRef), whose borrowed fields are
1376/// checked here. `start_response` is generic over it, so each source gets
1377/// its own compiled path with no runtime dispatch.
1378pub(crate) trait HeadSource {
1379 fn status(&self) -> u16;
1380 fn body(&self) -> OutgoingBody;
1381 fn close(&self) -> bool;
1382 /// The protocol of a 101.
1383 fn upgrade(&self) -> Option<&[u8]>;
1384 /// Validates what the builder did not: returns whether a `date` field
1385 /// is set.
1386 fn check(&self) -> Result<bool, HttpError>;
1387 fn write_fields<O: Output + ?Sized>(&self, out: &mut O);
1388}
1389
1390impl HeadSource for Response {
1391 #[inline]
1392 fn status(&self) -> u16 {
1393 Response::status(self)
1394 }
1395
1396 #[inline]
1397 fn body(&self) -> OutgoingBody {
1398 match &self.body {
1399 OutBody::Full(b) => OutgoingBody::Full(b.len() as u64),
1400 OutBody::Length(n) => OutgoingBody::Length(*n),
1401 OutBody::Chunked => OutgoingBody::Chunked,
1402 }
1403 }
1404
1405 #[inline]
1406 fn close(&self) -> bool {
1407 self.close
1408 }
1409
1410 #[inline]
1411 fn upgrade(&self) -> Option<&[u8]> {
1412 self.upgrade_protocol()
1413 }
1414
1415 #[inline]
1416 fn check(&self) -> Result<bool, HttpError> {
1417 match self.error() {
1418 Some(e) => Err(e),
1419 None => Ok(self.has_date),
1420 }
1421 }
1422
1423 #[inline]
1424 fn write_fields<O: Output + ?Sized>(&self, out: &mut O) {
1425 out.put(self.fields());
1426 }
1427}
1428
1429impl HeadSource for ResponseHeadRef<'_> {
1430 #[inline]
1431 fn status(&self) -> u16 {
1432 self.status
1433 }
1434
1435 #[inline]
1436 fn body(&self) -> OutgoingBody {
1437 self.body
1438 }
1439
1440 #[inline]
1441 fn close(&self) -> bool {
1442 self.close
1443 }
1444
1445 #[inline]
1446 fn upgrade(&self) -> Option<&[u8]> {
1447 self.upgrade.map(str::as_bytes)
1448 }
1449
1450 fn check(&self) -> Result<bool, HttpError> {
1451 if let Some(protocol) = self.upgrade {
1452 check_upgrade_protocol(protocol.as_bytes())?;
1453 }
1454 let mut has_date = false;
1455 for &(name, value) in self.fields {
1456 has_date |= check_response_field(name, value)?;
1457 }
1458 Ok(has_date)
1459 }
1460
1461 fn write_fields<O: Output + ?Sized>(&self, out: &mut O) {
1462 if let Some(protocol) = self.upgrade {
1463 // The same lines, in the same place, as
1464 // Response::switching_protocols writes.
1465 out.put(b"connection: upgrade\r\nupgrade: ");
1466 out.put(protocol.as_bytes());
1467 out.put(b"\r\n");
1468 }
1469 for &(name, value) in self.fields {
1470 write_field(out, name, value);
1471 }
1472 }
1473}
1474
1475#[cfg(test)]
1476mod tests {
1477 use alloc::vec;
1478
1479 use super::*;
1480
1481 fn events(conn: &mut ServerConn) -> Vec<alloc::string::String> {
1482 let mut log = Vec::new();
1483 loop {
1484 match conn.poll() {
1485 Ok(ServerEvent::Request(r)) => log.push(alloc::format!("req {}", r.target())),
1486 Ok(ServerEvent::Body(b)) => log.push(alloc::format!("body {}", b.len())),
1487 Ok(ServerEvent::RequestEnd) => {
1488 log.push("end".into());
1489 return log;
1490 }
1491 Ok(other) => {
1492 log.push(alloc::format!("{other:?}"));
1493 return log;
1494 }
1495 Err(e) => {
1496 log.push(alloc::format!("err {e:?}"));
1497 return log;
1498 }
1499 }
1500 }
1501 }
1502
1503 #[test]
1504 fn test_early_response_closes_connection() {
1505 let mut conn = ServerConn::new();
1506 let _ = conn.feed(b"POST / HTTP/1.1\r\nHost: a\r\nContent-Length: 10\r\n\r\nab");
1507 assert!(matches!(conn.poll(), Ok(ServerEvent::Request(_))));
1508 let mut out = Vec::new();
1509 conn.respond(&Response::new(413), &mut out).unwrap();
1510 assert!(out.windows(17).any(|w| w == b"connection: close"));
1511 assert!(matches!(conn.poll(), Ok(ServerEvent::Closed)));
1512 }
1513
1514 #[test]
1515 fn test_respond_after_failure_is_once_and_closes() {
1516 let mut conn = ServerConn::new();
1517 let _ = conn.feed(b"GET / HTTP/1.1\r\n\r\n");
1518 assert_eq!(conn.poll().unwrap_err(), HttpError::MissingHost);
1519 let mut out = Vec::new();
1520 conn.respond(&Response::new(400), &mut out).unwrap();
1521 assert!(out.starts_with(b"HTTP/1.1 400 Bad Request\r\n"));
1522 assert!(conn.respond(&Response::new(400), &mut out).is_err());
1523 assert!(matches!(conn.poll(), Ok(ServerEvent::Closed)));
1524 }
1525
1526 #[test]
1527 fn test_state_errors() {
1528 let mut conn = ServerConn::new();
1529 let mut out = Vec::new();
1530 assert!(matches!(
1531 conn.respond(&Response::new(200), &mut out),
1532 Err(HttpError::InvalidState(_))
1533 ));
1534 assert!(matches!(
1535 conn.send_body(b"x", &mut out),
1536 Err(HttpError::InvalidState(_))
1537 ));
1538 assert!(matches!(
1539 conn.end_body(&mut out),
1540 Err(HttpError::InvalidState(_))
1541 ));
1542 let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\n\r\n");
1543 assert_eq!(events(&mut conn), vec!["req /", "end"]);
1544 assert_eq!(
1545 conn.respond(&Response::new(99), &mut out),
1546 Err(HttpError::InvalidStatus)
1547 );
1548 assert_eq!(
1549 conn.respond(&Response::new(100), &mut out),
1550 Err(HttpError::InvalidStatus)
1551 );
1552 assert_eq!(
1553 conn.respond(&Response::new(204).body(&b"x"[..]), &mut out),
1554 Err(HttpError::BodyNotAllowed)
1555 );
1556 assert!(matches!(
1557 conn.respond(&Response::switching_protocols("x"), &mut out),
1558 Err(HttpError::InvalidState(_))
1559 ));
1560 conn.respond(&Response::new(204), &mut out).unwrap();
1561 assert!(matches!(
1562 conn.respond(&Response::new(200), &mut out),
1563 Err(HttpError::InvalidState(_))
1564 ));
1565 }
1566
1567 #[test]
1568 fn test_http10_keep_alive_and_chunked_fallback() {
1569 let mut conn = ServerConn::new();
1570 let _ = conn.feed(b"GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n");
1571 assert_eq!(events(&mut conn), vec!["req /", "end"]);
1572 let mut out = Vec::new();
1573 conn.respond(&Response::text(200, "x"), &mut out).unwrap();
1574 assert!(out.windows(22).any(|w| w == b"connection: keep-alive"));
1575 assert!(matches!(conn.poll(), Ok(ServerEvent::NeedInput)));
1576
1577 let _ = conn.feed(b"GET / HTTP/1.0\r\n\r\n");
1578 assert_eq!(events(&mut conn), vec!["req /", "end"]);
1579 let mut out = Vec::new();
1580 conn.respond(&Response::new(200).chunked(), &mut out)
1581 .unwrap();
1582 conn.send_body(b"abc", &mut out).unwrap();
1583 conn.end_body(&mut out).unwrap();
1584 assert!(out.ends_with(b"\r\n\r\nabc"));
1585 assert!(!out.windows(17).any(|w| w == b"transfer-encoding"));
1586 assert!(matches!(conn.poll(), Ok(ServerEvent::Closed)));
1587 }
1588
1589 fn upgrade_request(conn: &mut ServerConn, offer: &str) {
1590 let msg = alloc::format!(
1591 "GET / HTTP/1.1\r\nHost: a\r\nConnection: upgrade\r\nUpgrade: {offer}\r\n\r\n"
1592 );
1593 let _ = conn.feed(msg.as_bytes());
1594 assert_eq!(events(conn), vec!["req /", "end"]);
1595 }
1596
1597 #[test]
1598 fn test_switching_protocols_must_name_an_offered_protocol() {
1599 let mut conn = ServerConn::new();
1600 upgrade_request(&mut conn, "websocket/13, foo/2");
1601 let mut out = Vec::new();
1602 // `foo` alone would match `foo/2`: a name without a version
1603 // answers an offer of that name with any version.
1604 for refused in ["ftp", "foo/3", "websocket/12", "h2c"] {
1605 assert_eq!(
1606 conn.respond(&Response::switching_protocols(refused), &mut out),
1607 Err(HttpError::UpgradeNotOffered),
1608 "{refused}"
1609 );
1610 assert!(out.is_empty());
1611 assert!(!conn.is_upgraded());
1612 }
1613 conn.respond(&Response::switching_protocols("WebSocket"), &mut out)
1614 .unwrap();
1615 assert!(conn.is_upgraded());
1616 assert!(out.windows(18).any(|w| w == b"upgrade: WebSocket"));
1617 }
1618
1619 #[test]
1620 fn test_refused_switch_leaves_a_normal_response_possible() {
1621 let mut conn = ServerConn::new();
1622 upgrade_request(&mut conn, "websocket");
1623 let mut out = Vec::new();
1624 assert_eq!(
1625 conn.respond(&Response::switching_protocols("irc"), &mut out),
1626 Err(HttpError::UpgradeNotOffered)
1627 );
1628 conn.respond(&Response::new(426), &mut out).unwrap();
1629 assert!(out.starts_with(b"HTTP/1.1 426 Upgrade Required\r\n"));
1630 assert!(matches!(conn.poll(), Ok(ServerEvent::NeedInput)));
1631 }
1632
1633 #[test]
1634 fn test_h2c_only_offer_is_served_as_http11() {
1635 let mut conn = ServerConn::new();
1636 let _ = conn.feed(
1637 b"GET / HTTP/1.1\r\nHost: a\r\nConnection: Upgrade, HTTP2-Settings\r\nUpgrade: h2c\r\nHTTP2-Settings: AAMAAABkAAQAoAAA\r\n\r\n",
1638 );
1639 assert!(matches!(conn.poll(), Ok(ServerEvent::Request(r)) if !r.is_upgrade()));
1640 assert!(matches!(conn.poll(), Ok(ServerEvent::RequestEnd)));
1641 let mut out = Vec::new();
1642 assert!(matches!(
1643 conn.respond(&Response::switching_protocols("websocket"), &mut out),
1644 Err(HttpError::InvalidState(_))
1645 ));
1646 conn.respond(&Response::new(200), &mut out).unwrap();
1647 assert!(matches!(conn.poll(), Ok(ServerEvent::NeedInput)));
1648 }
1649
1650 #[test]
1651 fn test_unregistered_status_keeps_the_space_before_an_empty_reason() {
1652 let mut conn = ServerConn::new();
1653 let _ = conn.feed(b"GET / HTTP/1.1\r\nHost: a\r\n\r\n");
1654 assert_eq!(events(&mut conn), vec!["req /", "end"]);
1655 let mut out = Vec::new();
1656 conn.respond(&Response::new(299), &mut out).unwrap();
1657 assert!(out.starts_with(b"HTTP/1.1 299 \r\n"));
1658 }
1659
1660 #[test]
1661 fn test_connect_tunnel() {
1662 let mut conn = ServerConn::new();
1663 let _ = conn.feed(b"CONNECT example.com:443 HTTP/1.1\r\nHost: example.com:443\r\n\r\nTLS");
1664 assert_eq!(events(&mut conn), vec!["req example.com:443", "end"]);
1665 let mut out = Vec::new();
1666 conn.respond(&Response::new(200), &mut out).unwrap();
1667 assert_eq!(out, b"HTTP/1.1 200 OK\r\n\r\n");
1668 assert!(matches!(conn.poll(), Ok(ServerEvent::Upgraded)));
1669 assert_eq!(conn.remaining_input(), b"TLS");
1670 assert!(conn.request().is_some());
1671 }
1672}