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