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