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