Skip to main content

http_net/
blocking.rs

1//! A small blocking adapter over `std::net`: the Tier-1 path.
2//!
3//! [`Server`] serves a handler on a socket with one thread per connection
4//! (bounded by [`ServerConfig::with_max_connections`]); [`Connection`] is the
5//! per-connection loop for callers who run their own accept loop or need the
6//! socket back after an upgrade; [`get`] fetches a URL. Everything here is a
7//! thin shell around [`ServerConn`] and [`ClientConn`]: all parsing, framing,
8//! and limit enforcement happens in the sans-IO core.
9//!
10//! Only plain `http://` is spoken; there is no TLS in this crate.
11//!
12//! The server is for local, development, and trusted-network use. One
13//! thread serves each connection, up to the connection cap (64 by
14//! default), and the cap is the only admission control: a peer that holds
15//! that many slow connections keeps other clients waiting until the
16//! request timeout ends each one. An internet-facing server drives
17//! [`ServerConn`] from an event loop with per-peer limits (serve-net does).
18
19use std::{
20    cell::Cell,
21    fmt, io,
22    io::{IoSlice, Read, Write},
23    net::{
24        IpAddr, Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr, TcpListener, TcpStream, ToSocketAddrs,
25    },
26    string::{String, ToString},
27    sync::{
28        Arc, Condvar, Mutex,
29        atomic::{AtomicBool, Ordering},
30    },
31    thread,
32    time::{Duration, Instant, SystemTime, UNIX_EPOCH},
33    vec::Vec,
34};
35
36use crate::{
37    BodyPlan, ClientConn, ClientEvent, DateCache, HttpDate, HttpError, Limits, Method, Progress,
38    Request, RequestHead, Response, ServerConn, ServerEvent,
39    message::OutBody,
40    redact::{FieldValue, Target, serialized_fields},
41};
42
43/// Bytes a closing connection reads and discards so the peer's unread data
44/// does not turn the close into a reset that destroys the last response.
45const DRAIN_LIMIT: usize = 256 * 1024;
46/// How long one read of the lingering close may wait.
47const DRAIN_READ_TIMEOUT: Duration = Duration::from_millis(250);
48/// How long the whole lingering close may take, however the peer behaves:
49/// a peer that keeps sending must not keep the connection (and its slot).
50const DRAIN_TOTAL: Duration = Duration::from_secs(1);
51/// Responses larger than this do not keep their output buffer afterwards.
52const OUT_RETAIN: usize = 64 * 1024;
53/// Full bodies larger than this are written after the head with one
54/// vectored write instead of being copied into the output buffer.
55const VECTORED_BODY: usize = 4 * 1024;
56
57/// What can go wrong in the blocking adapter.
58///
59/// # Examples
60///
61/// ```
62/// let err = http_net::blocking::get("https://example.com/").unwrap_err();
63/// assert!(matches!(err, http_net::blocking::Error::InvalidUrl(_)));
64/// ```
65#[non_exhaustive]
66#[derive(Debug)]
67pub enum Error {
68    /// The socket failed (connect, read, write, or timeout).
69    Io(io::Error),
70    /// The peer sent a message this crate refuses, or a call was out of
71    /// order.
72    Http(HttpError),
73    /// The URL is not `http://host[:port][/path[?query]]` (a `#fragment` is
74    /// dropped); the text says which part is wrong.
75    InvalidUrl(&'static str),
76}
77
78impl fmt::Display for Error {
79    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80        match self {
81            Self::Io(e) => write!(f, "I/O error: {e}"),
82            Self::Http(e) => write!(f, "HTTP error: {e}"),
83            Self::InvalidUrl(why) => write!(f, "invalid URL: {why}"),
84        }
85    }
86}
87
88impl std::error::Error for Error {
89    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
90        match self {
91            Self::Io(e) => Some(e),
92            Self::Http(e) => Some(e),
93            Self::InvalidUrl(_) => None,
94        }
95    }
96}
97
98impl From<io::Error> for Error {
99    fn from(e: io::Error) -> Self {
100        Self::Io(e)
101    }
102}
103
104impl From<HttpError> for Error {
105    fn from(e: HttpError) -> Self {
106        Self::Http(e)
107    }
108}
109
110/// Settings for [`Server`].
111///
112/// | Setting | Default |
113/// |---|---|
114/// | limits | [`Limits::new`] |
115/// | concurrent connections | 64 (the 65th is answered `503` and closed) |
116/// | read timeout (also the idle keep-alive timeout) | 10 s |
117/// | request timeout (first byte of a request to the end of its body) | 30 s |
118/// | write timeout (each write) | 10 s |
119/// | response deadline (writing one whole response) | 60 s |
120/// | requests per connection | no cap |
121///
122/// # Examples
123///
124/// ```
125/// use std::time::Duration;
126/// use http_net::{blocking::ServerConfig, Limits};
127///
128/// let config = ServerConfig::new()
129///     .with_limits(Limits::new().with_max_body(16 * 1024))
130///     .with_max_connections(8)
131///     .with_read_timeout(Duration::from_secs(5));
132/// assert_eq!(config.max_connections(), 8);
133/// ```
134#[derive(Clone, Copy, Debug, PartialEq, Eq)]
135pub struct ServerConfig {
136    limits: Limits,
137    max_connections: usize,
138    read_timeout: Option<Duration>,
139    request_timeout: Option<Duration>,
140    write_timeout: Option<Duration>,
141    response_deadline: Option<Duration>,
142    max_requests: Option<u64>,
143}
144
145impl Default for ServerConfig {
146    fn default() -> Self {
147        Self::new()
148    }
149}
150
151impl ServerConfig {
152    /// The defaults (see the table on [`ServerConfig`]).
153    ///
154    /// # Examples
155    ///
156    /// ```
157    /// assert_eq!(http_net::blocking::ServerConfig::new().max_connections(), 64);
158    /// ```
159    #[must_use]
160    pub const fn new() -> Self {
161        Self {
162            limits: Limits::new(),
163            max_connections: 64,
164            read_timeout: Some(Duration::from_secs(10)),
165            request_timeout: Some(Duration::from_secs(30)),
166            write_timeout: Some(Duration::from_secs(10)),
167            response_deadline: Some(Duration::from_secs(60)),
168            max_requests: None,
169        }
170    }
171
172    /// Sets the message limits for every connection.
173    ///
174    /// # Examples
175    ///
176    /// ```
177    /// let c = http_net::blocking::ServerConfig::new()
178    ///     .with_limits(http_net::Limits::new().with_max_headers(10));
179    /// assert_eq!(c.limits().max_headers(), 10);
180    /// ```
181    #[must_use]
182    pub const fn with_limits(mut self, limits: Limits) -> Self {
183        self.limits = limits;
184        self
185    }
186
187    /// Sets how many connections are served at once (at least 1).
188    ///
189    /// # Examples
190    ///
191    /// ```
192    /// let c = http_net::blocking::ServerConfig::new().with_max_connections(0);
193    /// assert_eq!(c.max_connections(), 1);
194    /// ```
195    #[must_use]
196    pub const fn with_max_connections(mut self, n: usize) -> Self {
197        self.max_connections = if n == 0 { 1 } else { n };
198        self
199    }
200
201    /// Sets the socket read timeout: the longest a single read may wait for
202    /// bytes (the longest pause within a request), and how long an idle
203    /// keep-alive connection is held. Pass a `Duration`, or `None` to wait
204    /// forever.
205    ///
206    /// # Examples
207    ///
208    /// ```
209    /// use std::time::Duration;
210    /// use http_net::blocking::ServerConfig;
211    ///
212    /// let c = ServerConfig::new().with_read_timeout(Duration::from_secs(5));
213    /// assert_eq!(c.read_timeout(), Some(Duration::from_secs(5)));
214    /// assert_eq!(c.with_read_timeout(None).read_timeout(), None);
215    /// ```
216    #[must_use]
217    pub fn with_read_timeout(mut self, timeout: impl Into<Option<Duration>>) -> Self {
218        self.read_timeout = timeout.into();
219        self
220    }
221
222    /// Sets the request timeout: the most time one request may take to
223    /// arrive, from its first byte to the end of its body. The read timeout
224    /// alone cannot stop a client that sends one byte just inside it
225    /// ("slowloris"); this deadline can. A request still incomplete when it
226    /// passes is answered `408 Request Timeout` and the connection closed.
227    /// Time spent idle between keep-alive requests does not count (the read
228    /// timeout governs that). Pass a `Duration`, or `None` to disable the
229    /// deadline.
230    ///
231    /// # Examples
232    ///
233    /// ```
234    /// use std::time::Duration;
235    /// let c = http_net::blocking::ServerConfig::new().with_request_timeout(Duration::from_secs(10));
236    /// assert_eq!(c.request_timeout(), Some(Duration::from_secs(10)));
237    /// ```
238    #[must_use]
239    pub fn with_request_timeout(mut self, timeout: impl Into<Option<Duration>>) -> Self {
240        self.request_timeout = timeout.into();
241        self
242    }
243
244    /// Sets the socket write timeout. Pass a `Duration`, or `None` to wait
245    /// forever.
246    ///
247    /// # Examples
248    ///
249    /// ```
250    /// use std::time::Duration;
251    /// let c = http_net::blocking::ServerConfig::new().with_write_timeout(Duration::from_secs(1));
252    /// assert_eq!(c.write_timeout(), Some(Duration::from_secs(1)));
253    /// ```
254    #[must_use]
255    pub fn with_write_timeout(mut self, timeout: impl Into<Option<Duration>>) -> Self {
256        self.write_timeout = timeout.into();
257        self
258    }
259
260    /// Sets the response deadline: the most time writing one response may
261    /// take, from its first byte to its last (a streamed body included).
262    /// The write timeout bounds each write; it cannot stop a client that
263    /// reads one byte just inside it and so holds a thread for as long as a
264    /// large response takes. This deadline can: when it passes, the
265    /// connection is closed. Pass a `Duration`, or `None` to disable it.
266    ///
267    /// # Examples
268    ///
269    /// ```
270    /// use std::time::Duration;
271    /// let c = http_net::blocking::ServerConfig::new().with_response_deadline(Duration::from_secs(5));
272    /// assert_eq!(c.response_deadline(), Some(Duration::from_secs(5)));
273    /// ```
274    #[must_use]
275    pub fn with_response_deadline(mut self, deadline: impl Into<Option<Duration>>) -> Self {
276        self.response_deadline = deadline.into();
277        self
278    }
279
280    /// Sets the most requests served on one connection: the response that
281    /// reaches the cap carries `connection: close` and the connection ends
282    /// after it. Pass a count (0 is raised to 1), or `None` (the default)
283    /// for no cap.
284    ///
285    /// # Examples
286    ///
287    /// ```
288    /// let c = http_net::blocking::ServerConfig::new().with_max_requests_per_connection(100);
289    /// assert_eq!(c.max_requests_per_connection(), Some(100));
290    /// ```
291    #[must_use]
292    pub fn with_max_requests_per_connection(mut self, max: impl Into<Option<u64>>) -> Self {
293        self.max_requests = match max.into() {
294            Some(0) => Some(1),
295            other => other,
296        };
297        self
298    }
299
300    /// The message limits.
301    ///
302    /// # Examples
303    ///
304    /// ```
305    /// assert_eq!(http_net::blocking::ServerConfig::new().limits(), http_net::Limits::new());
306    /// ```
307    #[must_use]
308    pub const fn limits(&self) -> Limits {
309        self.limits
310    }
311
312    /// The concurrent connection cap.
313    ///
314    /// # Examples
315    ///
316    /// ```
317    /// assert_eq!(http_net::blocking::ServerConfig::new().max_connections(), 64);
318    /// ```
319    #[must_use]
320    pub const fn max_connections(&self) -> usize {
321        self.max_connections
322    }
323
324    /// The read timeout.
325    ///
326    /// # Examples
327    ///
328    /// ```
329    /// use std::time::Duration;
330    /// assert_eq!(http_net::blocking::ServerConfig::new().read_timeout(), Some(Duration::from_secs(10)));
331    /// ```
332    #[must_use]
333    pub const fn read_timeout(&self) -> Option<Duration> {
334        self.read_timeout
335    }
336
337    /// The request timeout.
338    ///
339    /// # Examples
340    ///
341    /// ```
342    /// use std::time::Duration;
343    /// assert_eq!(http_net::blocking::ServerConfig::new().request_timeout(), Some(Duration::from_secs(30)));
344    /// ```
345    #[must_use]
346    pub const fn request_timeout(&self) -> Option<Duration> {
347        self.request_timeout
348    }
349
350    /// The write timeout.
351    ///
352    /// # Examples
353    ///
354    /// ```
355    /// use std::time::Duration;
356    /// assert_eq!(http_net::blocking::ServerConfig::new().write_timeout(), Some(Duration::from_secs(10)));
357    /// ```
358    #[must_use]
359    pub const fn write_timeout(&self) -> Option<Duration> {
360        self.write_timeout
361    }
362
363    /// The response deadline.
364    ///
365    /// # Examples
366    ///
367    /// ```
368    /// use std::time::Duration;
369    /// assert_eq!(http_net::blocking::ServerConfig::new().response_deadline(), Some(Duration::from_secs(60)));
370    /// ```
371    #[must_use]
372    pub const fn response_deadline(&self) -> Option<Duration> {
373        self.response_deadline
374    }
375
376    /// The cap on requests per connection.
377    ///
378    /// # Examples
379    ///
380    /// ```
381    /// assert_eq!(http_net::blocking::ServerConfig::new().max_requests_per_connection(), None);
382    /// ```
383    #[must_use]
384    pub const fn max_requests_per_connection(&self) -> Option<u64> {
385        self.max_requests
386    }
387}
388
389/// A connection handed over by a `101 Switching Protocols` (or a 2xx to
390/// `CONNECT`): the socket, the bytes of the new protocol that already
391/// arrived, and the target of the request that asked for the switch.
392///
393/// # Examples
394///
395/// Not run: it serves until the process ends.
396///
397/// ```no_run
398/// use http_net::{blocking::Server, Response};
399///
400/// let server = Server::bind("127.0.0.1:0")?.on_upgrade(|up| {
401///     // Hand `up.stream` and `up.leftover` to a protocol engine.
402///     let _ = (up.stream, up.leftover, up.target);
403/// });
404/// server.serve(|req, _body| {
405///     if req.is_upgrade() {
406///         Response::switching_protocols("x")
407///     } else {
408///         Response::new(404)
409///     }
410/// })?;
411/// # Ok::<(), std::io::Error>(())
412/// ```
413#[non_exhaustive]
414pub struct Upgraded {
415    /// The socket, now speaking the new protocol.
416    pub stream: TcpStream,
417    /// Bytes of the new protocol received together with the request.
418    pub leftover: Vec<u8>,
419    /// The target of the request that asked for the switch.
420    pub target: String,
421}
422
423/// `leftover` prints as its length: after a `CONNECT` it can be a whole
424/// request in clear text, credentials included.
425impl fmt::Debug for Upgraded {
426    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
427        f.debug_struct("Upgraded")
428            .field("stream", &self.stream)
429            .field("leftover", &format_args!("{} bytes", self.leftover.len()))
430            .field("target", &Target(&self.target))
431            .finish()
432    }
433}
434
435type UpgradeHook = Arc<dyn Fn(Upgraded) + Send + Sync>;
436
437/// A blocking HTTP/1.1 server: one thread per connection, bounded.
438///
439/// # Examples
440///
441/// ```
442/// use http_net::{blocking::{self, Server}, Response};
443///
444/// let server = Server::bind("127.0.0.1:0")?;
445/// let addr = server.local_addr();
446/// let stop = server.shutdown_handle();
447/// let thread = std::thread::spawn(move || {
448///     server.serve(|req, _body| Response::text(200, &format!("you asked for {}", req.path())))
449/// });
450///
451/// let resp = blocking::get(&format!("http://{addr}/hello"))?;
452/// assert_eq!(resp.status(), 200);
453/// assert_eq!(resp.text(), Some("you asked for /hello"));
454///
455/// stop.shutdown();
456/// thread.join().unwrap()?;
457/// # Ok::<(), Box<dyn std::error::Error>>(())
458/// ```
459pub struct Server {
460    listener: TcpListener,
461    local: SocketAddr,
462    config: ServerConfig,
463    stop: Arc<AtomicBool>,
464    upgrade: Option<UpgradeHook>,
465}
466
467impl fmt::Debug for Server {
468    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
469        f.debug_struct("Server")
470            .field("local_addr", &self.local)
471            .field("config", &self.config)
472            .finish()
473    }
474}
475
476/// Stops a running [`Server::serve`] from another thread.
477///
478/// # Examples
479///
480/// ```
481/// let server = http_net::blocking::Server::bind("127.0.0.1:0")?;
482/// let stop = server.shutdown_handle();
483/// let t = std::thread::spawn(move || server.serve(|_, _| http_net::Response::new(204)));
484/// stop.shutdown();
485/// t.join().unwrap()?;
486/// # Ok::<(), std::io::Error>(())
487/// ```
488#[derive(Clone, Debug)]
489pub struct ShutdownHandle {
490    stop: Arc<AtomicBool>,
491    wake: SocketAddr,
492}
493
494impl ShutdownHandle {
495    /// Asks the server to stop: it accepts no new connections and returns
496    /// from `serve` once every open connection has ended. The stop is
497    /// checked between exchanges, so an exchange in progress finishes. An
498    /// idle keep-alive connection ends when its read timeout passes, or
499    /// after one more request if the client sends one first; with no read
500    /// timeout, `serve` does not return while a client holds an idle
501    /// connection.
502    ///
503    /// # Examples
504    ///
505    /// See [`ShutdownHandle`].
506    pub fn shutdown(&self) {
507        self.stop.store(true, Ordering::SeqCst);
508        // `accept` blocks; a throwaway connection wakes it so it sees the
509        // flag. If the connect fails the listener is already gone, which is
510        // the outcome being asked for, so the error carries no information.
511        if let Ok(stream) = TcpStream::connect_timeout(&self.wake, Duration::from_secs(1)) {
512            drop(stream);
513        }
514    }
515}
516
517/// Counts live connection threads so shutdown can wait for them.
518#[derive(Default)]
519struct Active {
520    count: Mutex<usize>,
521    idle: Condvar,
522}
523
524impl Active {
525    fn try_enter(&self, max: usize) -> bool {
526        let mut n = self
527            .count
528            .lock()
529            .unwrap_or_else(std::sync::PoisonError::into_inner);
530        if *n >= max {
531            return false;
532        }
533        *n += 1;
534        true
535    }
536
537    fn leave(&self) {
538        let mut n = self
539            .count
540            .lock()
541            .unwrap_or_else(std::sync::PoisonError::into_inner);
542        *n = n.saturating_sub(1);
543        if *n == 0 {
544            self.idle.notify_all();
545        }
546    }
547
548    fn wait_idle(&self) {
549        let mut n = self
550            .count
551            .lock()
552            .unwrap_or_else(std::sync::PoisonError::into_inner);
553        while *n > 0 {
554            n = self
555                .idle
556                .wait(n)
557                .unwrap_or_else(std::sync::PoisonError::into_inner);
558        }
559    }
560}
561
562/// Leaves the active set even if the handler panics.
563struct ActiveGuard(Arc<Active>);
564
565impl Drop for ActiveGuard {
566    fn drop(&mut self) {
567        self.0.leave();
568    }
569}
570
571impl Server {
572    /// Binds a listening socket. Use `127.0.0.1:0` for an ephemeral
573    /// localhost port and read it back with [`local_addr`](Self::local_addr).
574    ///
575    /// # Errors
576    ///
577    /// The bind error from the operating system.
578    ///
579    /// # Examples
580    ///
581    /// ```
582    /// let server = http_net::blocking::Server::bind("127.0.0.1:0")?;
583    /// assert!(server.local_addr().ip().is_loopback());
584    /// # Ok::<(), std::io::Error>(())
585    /// ```
586    pub fn bind(addr: impl ToSocketAddrs) -> io::Result<Self> {
587        let listener = TcpListener::bind(addr)?;
588        let local = listener.local_addr()?;
589        Ok(Self {
590            listener,
591            local,
592            config: ServerConfig::new(),
593            stop: Arc::new(AtomicBool::new(false)),
594            upgrade: None,
595        })
596    }
597
598    /// Replaces the configuration.
599    ///
600    /// # Examples
601    ///
602    /// ```
603    /// use http_net::blocking::{Server, ServerConfig};
604    /// let s = Server::bind("127.0.0.1:0")?.with_config(ServerConfig::new().with_max_connections(4));
605    /// # Ok::<(), std::io::Error>(())
606    /// ```
607    #[must_use]
608    pub fn with_config(mut self, config: ServerConfig) -> Self {
609        self.config = config;
610        self
611    }
612
613    /// Sets what happens to a connection after the handler answers with
614    /// `101 Switching Protocols` (or a 2xx to `CONNECT`): `hook` receives
615    /// the socket on the
616    /// connection's thread. Without a hook such connections are closed.
617    ///
618    /// # Examples
619    ///
620    /// See [`Upgraded`].
621    #[must_use]
622    pub fn on_upgrade(mut self, hook: impl Fn(Upgraded) + Send + Sync + 'static) -> Self {
623        self.upgrade = Some(Arc::new(hook));
624        self
625    }
626
627    /// The bound address (with the real port when bound to port 0).
628    ///
629    /// # Examples
630    ///
631    /// ```
632    /// let server = http_net::blocking::Server::bind("127.0.0.1:0")?;
633    /// assert_ne!(server.local_addr().port(), 0);
634    /// # Ok::<(), std::io::Error>(())
635    /// ```
636    #[must_use]
637    pub fn local_addr(&self) -> SocketAddr {
638        self.local
639    }
640
641    /// A handle that stops [`serve`](Self::serve) from another thread.
642    ///
643    /// # Examples
644    ///
645    /// See [`ShutdownHandle`].
646    #[must_use]
647    pub fn shutdown_handle(&self) -> ShutdownHandle {
648        let mut wake = self.local;
649        if wake.ip().is_unspecified() {
650            wake.set_ip(match wake.ip() {
651                IpAddr::V4(_) => IpAddr::V4(Ipv4Addr::LOCALHOST),
652                IpAddr::V6(_) => IpAddr::V6(Ipv6Addr::LOCALHOST),
653            });
654        }
655        ShutdownHandle {
656            stop: Arc::clone(&self.stop),
657            wake,
658        }
659    }
660
661    /// Serves `handler` until [`ShutdownHandle::shutdown`] is called.
662    ///
663    /// The handler gets each request's head and its complete body (bounded
664    /// by [`Limits::max_body`]) and returns the response. Requests that fail
665    /// to parse are answered with [`Response::from_error`] and the
666    /// connection is closed; the handler never sees them. A request with
667    /// `Expect: 100-continue` gets `100 Continue` before its body is read;
668    /// one with any other expectation is answered `417 Expectation Failed`
669    /// without reading its body (RFC 9110 section 10.1.1), and the
670    /// connection is closed. A handler that returns a streamed response
671    /// (`chunked` or `content_length`, except to `HEAD`), or one that
672    /// [`ServerConn::respond`] refuses, is replaced by a `500` with
673    /// `connection: close`. Every response gets a `date` field (from
674    /// [`now_date`]) unless the handler set one, except the `503` sent to a
675    /// connection over the connection cap. The time limits and the request
676    /// cap of [`ServerConfig`] apply to every connection.
677    ///
678    /// # Errors
679    ///
680    /// Only if accepting connections fails persistently; transient accept
681    /// errors are retried. Before the error is returned, live connections
682    /// finish their current exchange, as after a shutdown.
683    ///
684    /// # Examples
685    ///
686    /// See [`Server`].
687    pub fn serve<H>(self, handler: H) -> io::Result<()>
688    where
689        H: Fn(&RequestHead<'_>, &[u8]) -> Response + Send + Sync + 'static,
690    {
691        let handler = Arc::new(handler);
692        let active = Arc::new(Active::default());
693        let mut backoff = AcceptBackoff::default();
694        for incoming in self.listener.incoming() {
695            if self.stop.load(Ordering::SeqCst) {
696                break;
697            }
698            let stream = match incoming {
699                Ok(stream) => {
700                    backoff.success();
701                    stream
702                }
703                Err(e) => match backoff.failure(e) {
704                    Ok(wait) => {
705                        thread::sleep(wait);
706                        continue;
707                    }
708                    Err(e) => {
709                        // Give up as a shutdown does: live connections
710                        // finish their exchange before `serve` returns.
711                        self.stop.store(true, Ordering::SeqCst);
712                        active.wait_idle();
713                        return Err(e);
714                    }
715                },
716            };
717            if !active.try_enter(self.config.max_connections) {
718                refuse_busy(stream, &self.config);
719                continue;
720            }
721            let guard = ActiveGuard(Arc::clone(&active));
722            let handler = Arc::clone(&handler);
723            let upgrade = self.upgrade.clone();
724            let stop = Arc::clone(&self.stop);
725            let config = self.config;
726            let spawned = thread::Builder::new()
727                .name("http-net-conn".into())
728                .spawn(move || {
729                    let _guard = guard;
730                    serve_stream(stream, &config, &*handler, upgrade.as_deref(), &stop);
731                });
732            // A failed spawn drops the closure, its guard, and the stream:
733            // the connection is closed and the slot released.
734            drop(spawned);
735        }
736        active.wait_idle();
737        Ok(())
738    }
739}
740
741/// What the accept loop does after an accept error (threat T-41). Aborted
742/// handshakes and descriptor exhaustion are transient, so it waits instead
743/// of spinning a core, and gives up only when accept never recovers.
744#[derive(Debug, Default)]
745struct AcceptBackoff {
746    consecutive: u32,
747}
748
749impl AcceptBackoff {
750    /// The wait after each failed accept.
751    const WAIT: Duration = Duration::from_millis(10);
752    /// Consecutive failures tolerated before `serve` returns the error.
753    const LIMIT: u32 = 1000;
754
755    fn success(&mut self) {
756        self.consecutive = 0;
757    }
758
759    /// The wait before the next accept, or the error to stop with.
760    fn failure(&mut self, error: io::Error) -> io::Result<Duration> {
761        self.consecutive += 1;
762        if self.consecutive > Self::LIMIT {
763            Err(error)
764        } else {
765            Ok(Self::WAIT)
766        }
767    }
768}
769
770fn refuse_busy(mut stream: TcpStream, config: &ServerConfig) {
771    const BUSY: &[u8] =
772        b"HTTP/1.1 503 Service Unavailable\r\ncontent-length: 0\r\nconnection: close\r\n\r\n";
773    // Best effort on a connection being turned away: a failure here only
774    // means the client already left. This runs on the accept thread, so it
775    // must never wait on the peer: the 503 fits in an empty send buffer,
776    // and only what has already arrived is drained (without blocking) so
777    // that it does not turn the close into a reset.
778    if stream.set_write_timeout(config.write_timeout).is_err()
779        || stream.write_all(BUSY).is_err()
780        || stream.shutdown(Shutdown::Write).is_err()
781        || stream.set_nonblocking(true).is_err()
782    {
783        return;
784    }
785    let mut scratch = [0u8; 4096];
786    let mut drained = 0;
787    while drained < DRAIN_LIMIT {
788        match stream.read(&mut scratch) {
789            Ok(n) if n > 0 => drained += n,
790            _ => break,
791        }
792    }
793}
794
795fn serve_stream(
796    stream: TcpStream,
797    config: &ServerConfig,
798    handler: &(dyn Fn(&RequestHead<'_>, &[u8]) -> Response + Send + Sync),
799    upgrade: Option<&(dyn Fn(Upgraded) + Send + Sync)>,
800    stop: &AtomicBool,
801) {
802    let configured = stream.set_read_timeout(config.read_timeout).is_ok()
803        && stream.set_write_timeout(config.write_timeout).is_ok()
804        && stream.set_nodelay(true).is_ok();
805    if !configured {
806        return;
807    }
808    let mut conn = Connection::new(stream)
809        .with_limits(config.limits)
810        .with_request_timeout(config.request_timeout)
811        .with_response_deadline(config.response_deadline);
812    conn.refuse_unknown_expectations = true;
813    while !stop.load(Ordering::SeqCst) {
814        // The handler runs inside the first match; errors (which borrow
815        // nothing) are handled in the second, where `conn` is free again.
816        let outcome = match conn.next_request() {
817            Ok(Some(incoming)) => {
818                let head = incoming.head();
819                Ok((
820                    handler(&head, incoming.body()),
821                    head.method() == Method::Head,
822                ))
823            }
824            Ok(None) => break,
825            Err(e) => Err(e),
826        };
827        let (response, is_head) = match outcome {
828            Ok(answer) => answer,
829            Err(Error::Http(e)) => {
830                if conn.respond(&Response::from_error(&e)).is_err() {
831                    return;
832                }
833                break;
834            }
835            Err(Error::Io(e)) if is_timeout(&e) && conn.request_in_progress() => {
836                // A request that did not arrive in time: say so, then
837                // close (the rest of it can no longer be framed).
838                if conn.send_request_timeout().is_ok() {
839                    conn.close();
840                }
841                return;
842            }
843            Err(_) => return,
844        };
845        // `Server` writes full bodies only: the handler has no way to send
846        // a streamed one, so it would leave the client waiting. A `HEAD`
847        // answer is the exception: it announces a length or chunked
848        // framing but carries no body, so it is complete once written.
849        let streamed = response.body_bytes().is_none();
850        let response = if streamed && !is_head {
851            Response::text(
852                500,
853                "handler error: Server cannot send a streamed response; \
854                 use Connection for streaming",
855            )
856            .close()
857        } else {
858            response
859        };
860        if config
861            .max_requests
862            .is_some_and(|max| conn.conn.requests_served().saturating_add(1) >= max)
863        {
864            // This response reaches the cap: it carries `connection: close`.
865            conn.conn.set_keep_alive(false);
866        }
867        match conn.respond(&response) {
868            Ok(()) if streamed && is_head => {
869                if conn.end_body().is_err() {
870                    return;
871                }
872            }
873            Ok(()) => {}
874            // Refused before anything was written (a builder error, or a
875            // 101 to a request that did not ask): answer 500 instead.
876            Err(Error::Http(e)) => {
877                let message = format!("handler error: invalid response: {e}");
878                if conn
879                    .respond(&Response::text(500, &message).close())
880                    .is_err()
881                {
882                    return;
883                }
884            }
885            Err(_) => return,
886        }
887        if conn.is_upgraded() {
888            match (conn.into_upgraded(), upgrade) {
889                (Some(up), Some(hook)) => hook(up),
890                (Some(up), None) => drain_and_close(up.stream),
891                (None, _) => {}
892            }
893            return;
894        }
895    }
896    conn.close();
897}
898
899fn drain_and_close(mut stream: TcpStream) {
900    let _ = lingering_drain(&mut stream);
901}
902
903/// Lingering close (RFC 9112 section 9.6): stops sending, then reads what
904/// the peer is still sending so the close does not become a reset that
905/// discards the response before the peer reads it. Returns the bytes
906/// drained.
907///
908/// The drain is bounded in bytes and in total time, not only per read: a
909/// peer that keeps trickling data must not hold the thread.
910fn lingering_drain(stream: &mut TcpStream) -> usize {
911    if stream.flush().is_err() || stream.shutdown(Shutdown::Write).is_err() {
912        return 0;
913    }
914    let deadline = Instant::now() + DRAIN_TOTAL;
915    let mut scratch = [0u8; 4096];
916    let mut drained = 0;
917    while drained < DRAIN_LIMIT {
918        let left = deadline.saturating_duration_since(Instant::now());
919        if left.is_zero()
920            || stream
921                .set_read_timeout(Some(left.min(DRAIN_READ_TIMEOUT)))
922                .is_err()
923        {
924            break;
925        }
926        match stream.read(&mut scratch) {
927            Ok(0) | Err(_) => break,
928            Ok(n) => drained += n,
929        }
930    }
931    drained
932}
933
934fn response_timed_out() -> Error {
935    Error::Io(io::Error::new(
936        io::ErrorKind::TimedOut,
937        "the response was not written within the response deadline",
938    ))
939}
940
941/// The error for a request that missed its deadline.
942fn request_timed_out() -> Error {
943    Error::Io(io::Error::new(
944        io::ErrorKind::TimedOut,
945        "the request did not arrive within the request timeout",
946    ))
947}
948
949fn is_timeout(e: &io::Error) -> bool {
950    // Unix reports an expired socket timeout as WouldBlock, Windows as
951    // TimedOut.
952    matches!(
953        e.kind(),
954        io::ErrorKind::TimedOut | io::ErrorKind::WouldBlock
955    )
956}
957
958/// One request read by [`Connection::next_request`]: its head and its
959/// complete body.
960///
961/// # Examples
962///
963/// See [`Connection`].
964pub struct Incoming<'a> {
965    head: RequestHead<'a>,
966    body: &'a [u8],
967}
968
969/// The body prints as its length, as in [`Connection`] and
970/// [`ClientResponse`].
971impl fmt::Debug for Incoming<'_> {
972    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
973        f.debug_struct("Incoming")
974            .field("head", &self.head)
975            .field("body", &format_args!("{} bytes", self.body.len()))
976            .finish()
977    }
978}
979
980impl<'a> Incoming<'a> {
981    /// The request head.
982    ///
983    /// # Examples
984    ///
985    /// See [`Connection`].
986    #[must_use]
987    pub fn head(&self) -> RequestHead<'a> {
988        self.head
989    }
990
991    /// The complete request body (empty when there is none).
992    ///
993    /// # Examples
994    ///
995    /// See [`Connection`].
996    #[must_use]
997    pub fn body(&self) -> &'a [u8] {
998        self.body
999    }
1000}
1001
1002/// A blocking server connection: [`ServerConn`] driven over a `TcpStream`.
1003///
1004/// Use it for your own accept loop, or to keep the socket after an
1005/// upgrade with [`into_upgraded`](Self::into_upgraded).
1006///
1007/// # Examples
1008///
1009/// ```
1010/// use std::net::{TcpListener, TcpStream};
1011/// use std::io::{Read, Write};
1012/// use http_net::{blocking::Connection, Response};
1013///
1014/// let listener = TcpListener::bind("127.0.0.1:0")?;
1015/// let addr = listener.local_addr()?;
1016/// let client = std::thread::spawn(move || -> std::io::Result<Vec<u8>> {
1017///     let mut s = TcpStream::connect(addr)?;
1018///     s.write_all(b"POST /sum HTTP/1.1\r\nHost: x\r\nContent-Length: 3\r\nConnection: close\r\n\r\n1 2")?;
1019///     let mut reply = Vec::new();
1020///     s.read_to_end(&mut reply)?;
1021///     Ok(reply)
1022/// });
1023///
1024/// let (stream, _) = listener.accept()?;
1025/// let mut conn = Connection::new(stream);
1026/// while let Some(req) = conn.next_request()? {
1027///     let sum: u32 = std::str::from_utf8(req.body())?.split(' ').filter_map(|n| n.parse::<u32>().ok()).sum();
1028///     let response = Response::text(200, &sum.to_string());
1029///     conn.respond(&response)?;
1030/// }
1031/// conn.close();
1032/// let reply = client.join().unwrap()?;
1033/// assert!(reply.ends_with(b"\r\n\r\n3"));
1034/// # Ok::<(), Box<dyn std::error::Error>>(())
1035/// ```
1036pub struct Connection {
1037    stream: TcpStream,
1038    conn: ServerConn,
1039    body: Vec<u8>,
1040    out: Vec<u8>,
1041    /// The socket's own read timeout, restored once a request deadline no
1042    /// longer applies.
1043    read_timeout: Option<Duration>,
1044    request_timeout: Option<Duration>,
1045    /// When the request being read must be complete.
1046    deadline: Option<Instant>,
1047    /// Whether the socket's read timeout is currently shortened to the
1048    /// deadline.
1049    shortened: bool,
1050    /// The socket's own write timeout, restored after a response deadline
1051    /// shortened it.
1052    write_timeout: Option<Duration>,
1053    response_deadline: Option<Duration>,
1054    /// When the response being written must be complete.
1055    write_deadline: Option<Instant>,
1056    write_shortened: bool,
1057    /// `Server` answers expectations other than `100-continue` with 417
1058    /// before the body is read; a bare `Connection` leaves them to the
1059    /// caller.
1060    refuse_unknown_expectations: bool,
1061}
1062
1063/// The buffers print as lengths only: they hold the last request body and
1064/// the last serialized response, which may carry credentials.
1065impl fmt::Debug for Connection {
1066    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1067        f.debug_struct("Connection")
1068            .field("stream", &self.stream)
1069            .field("conn", &self.conn)
1070            .field("body_len", &self.body.len())
1071            .field("out_len", &self.out.len())
1072            .field("read_timeout", &self.read_timeout)
1073            .field("request_timeout", &self.request_timeout)
1074            .field("write_timeout", &self.write_timeout)
1075            .field("response_deadline", &self.response_deadline)
1076            .finish_non_exhaustive()
1077    }
1078}
1079
1080impl Connection {
1081    /// Wraps an accepted socket, with the default [`Limits`]. Set its
1082    /// timeouts first if you want them: the read timeout set on `stream` is
1083    /// the idle timeout, and
1084    /// [`with_request_timeout`](Self::with_request_timeout) adds a deadline
1085    /// for each request as a whole.
1086    ///
1087    /// # Examples
1088    ///
1089    /// See [`Connection`].
1090    #[must_use]
1091    pub fn new(stream: TcpStream) -> Self {
1092        let read_timeout = stream.read_timeout().ok().flatten();
1093        let write_timeout = stream.write_timeout().ok().flatten();
1094        Self {
1095            stream,
1096            conn: ServerConn::new(),
1097            body: Vec::new(),
1098            out: Vec::new(),
1099            read_timeout,
1100            request_timeout: None,
1101            deadline: None,
1102            shortened: false,
1103            write_timeout,
1104            response_deadline: None,
1105            write_deadline: None,
1106            write_shortened: false,
1107            refuse_unknown_expectations: false,
1108        }
1109    }
1110
1111    /// Sets a deadline for writing each response, from its first byte to
1112    /// its last, a streamed body included (see
1113    /// [`ServerConfig::with_response_deadline`]). When it passes, the write
1114    /// fails with an [`Error::Io`] of kind `TimedOut`; close the connection
1115    /// then (the response cannot be finished). `None` (the default for a
1116    /// bare `Connection`) leaves only the socket's own write timeout.
1117    ///
1118    /// # Examples
1119    ///
1120    /// ```
1121    /// use std::time::Duration;
1122    /// # fn demo(stream: std::net::TcpStream) {
1123    /// let conn = http_net::blocking::Connection::new(stream)
1124    ///     .with_response_deadline(Duration::from_secs(60));
1125    /// # let _ = conn;
1126    /// # }
1127    /// ```
1128    #[must_use]
1129    pub fn with_response_deadline(mut self, deadline: impl Into<Option<Duration>>) -> Self {
1130        self.response_deadline = deadline.into();
1131        self
1132    }
1133
1134    /// Sets the message limits. Call it before the first
1135    /// [`next_request`](Self::next_request): it starts the connection's
1136    /// state again.
1137    ///
1138    /// # Examples
1139    ///
1140    /// ```
1141    /// # fn demo(stream: std::net::TcpStream) {
1142    /// use http_net::{Limits, blocking::Connection};
1143    ///
1144    /// let conn = Connection::new(stream).with_limits(Limits::new().with_max_body(64 * 1024));
1145    /// # let _ = conn;
1146    /// # }
1147    /// ```
1148    #[must_use]
1149    pub fn with_limits(mut self, limits: Limits) -> Self {
1150        self.conn = ServerConn::with_limits(limits);
1151        self
1152    }
1153
1154    /// Sets a deadline for each request: from the moment its first byte is
1155    /// seen to the end of its body (see
1156    /// [`ServerConfig::with_request_timeout`]). When it passes,
1157    /// [`next_request`](Self::next_request) fails with an [`Error::Io`] of
1158    /// kind `TimedOut`. `None` (the default for a bare `Connection`) leaves
1159    /// only the socket's own read timeout.
1160    ///
1161    /// # Examples
1162    ///
1163    /// ```
1164    /// use std::time::Duration;
1165    /// # fn demo(stream: std::net::TcpStream) {
1166    /// let conn = http_net::blocking::Connection::new(stream)
1167    ///     .with_request_timeout(Duration::from_secs(10));
1168    /// # let _ = conn;
1169    /// # }
1170    /// ```
1171    #[must_use]
1172    pub fn with_request_timeout(mut self, timeout: impl Into<Option<Duration>>) -> Self {
1173        self.request_timeout = timeout.into();
1174        self
1175    }
1176
1177    /// Whether part of a request has arrived and the rest is outstanding.
1178    fn request_in_progress(&self) -> bool {
1179        self.conn.request().is_some() || !self.conn.remaining_input().is_empty()
1180    }
1181
1182    /// Answers a request that did not arrive in time with `408`, unless a
1183    /// response is already on its way.
1184    fn send_request_timeout(&mut self) -> Result<(), Error> {
1185        if self.conn.response_started() {
1186            return Err(Error::Http(HttpError::InvalidState(
1187                "a response was already started",
1188            )));
1189        }
1190        const BODY: &[u8] = b"request timed out";
1191        self.out.clear();
1192        self.out.extend_from_slice(
1193            b"HTTP/1.1 408 Request Timeout\r\ncontent-type: text/plain; charset=utf-8\r\n\
1194              content-length: ",
1195        );
1196        self.out
1197            .extend_from_slice(BODY.len().to_string().as_bytes());
1198        self.out
1199            .extend_from_slice(b"\r\nconnection: close\r\ndate: ");
1200        self.out.extend_from_slice(now_date().as_bytes());
1201        self.out.extend_from_slice(b"\r\n\r\n");
1202        // An answer to HEAD carries no content (RFC 9110 section 9.3.2).
1203        if !self.conn.request_line_is_head() {
1204            self.out.extend_from_slice(BODY);
1205        }
1206        self.flush_out()
1207    }
1208
1209    /// Reads into the parser's buffer, under the request deadline if one
1210    /// is running.
1211    fn fill(&mut self) -> Result<(), Error> {
1212        if let Some(limit) = self.request_timeout {
1213            if self.deadline.is_none() && self.request_in_progress() {
1214                self.deadline = Some(Instant::now() + limit);
1215            }
1216        }
1217        // Whether this read's timeout is the time left before the deadline,
1218        // so a timeout means the deadline passed.
1219        let mut at_deadline = false;
1220        match self.deadline {
1221            Some(deadline) => {
1222                let left = deadline.saturating_duration_since(Instant::now());
1223                if left.is_zero() {
1224                    return Err(request_timed_out());
1225                }
1226                let wait = self.read_timeout.map_or(left, |t| t.min(left));
1227                at_deadline = wait == left;
1228                self.stream.set_read_timeout(Some(wait))?;
1229                self.shortened = true;
1230            }
1231            None if self.shortened => {
1232                self.stream.set_read_timeout(self.read_timeout)?;
1233                self.shortened = false;
1234            }
1235            None => {}
1236        }
1237        let spare = self.conn.read_buf();
1238        if spare.is_empty() {
1239            return Err(Error::Http(HttpError::InvalidState(
1240                "input buffer full while the parser needs input",
1241            )));
1242        }
1243        let n = loop {
1244            match self.stream.read(spare) {
1245                Err(e) if e.kind() == io::ErrorKind::Interrupted => {}
1246                // Unix reports the expired socket timeout as `WouldBlock`;
1247                // the deadline is reported as `TimedOut` on every platform.
1248                Err(e) if at_deadline && is_timeout(&e) => return Err(request_timed_out()),
1249                other => break other?,
1250            }
1251        };
1252        if n == 0 {
1253            self.conn.feed_eof();
1254        } else {
1255            self.conn.commit(n);
1256        }
1257        Ok(())
1258    }
1259
1260    /// Reads the next complete request. `Ok(None)` means the connection is
1261    /// finished (the client closed between requests, the previous exchange
1262    /// ended with `connection: close`, or the connection was upgraded).
1263    ///
1264    /// A request that carries `Expect: 100-continue` is answered with
1265    /// `100 Continue` before its body is read. Other expectations are left
1266    /// to the caller (see [`RequestHead::has_unknown_expectation`]);
1267    /// [`Server`] answers them with 417.
1268    ///
1269    /// # Errors
1270    ///
1271    /// [`Error::Http`] for a request this crate refuses (answer it with its
1272    /// [`HttpError::status`] and close), [`Error::Io`] for socket failures
1273    /// and timeouts (including the request deadline, as `TimedOut`), and
1274    /// [`Error::Http`] with [`HttpError::InvalidState`] if the previous
1275    /// request has not been answered.
1276    ///
1277    /// # Examples
1278    ///
1279    /// See [`Connection`].
1280    pub fn next_request(&mut self) -> Result<Option<Incoming<'_>>, Error> {
1281        self.body.clear();
1282        self.deadline = None;
1283        loop {
1284            match self.conn.poll()? {
1285                ServerEvent::Request(head) => {
1286                    // The whole body is read before the caller sees the
1287                    // request, so the expectation is answered here (RFC 9110
1288                    // section 10.1.1). A body over the limit was already
1289                    // refused from its Content-Length.
1290                    let unknown = head.has_unknown_expectation();
1291                    let expects_continue = head.expects_continue();
1292                    if self.refuse_unknown_expectations && unknown {
1293                        // An expectation this server cannot meet: 417, the
1294                        // body left unread, so the connection closes after.
1295                        let refusal =
1296                            Response::text(417, "expectation not supported; send without Expect")
1297                                .close();
1298                        self.respond(&refusal)?;
1299                        return Ok(None);
1300                    }
1301                    if expects_continue {
1302                        self.out.clear();
1303                        self.conn.send_continue(&mut self.out)?;
1304                        self.flush_out()?;
1305                    }
1306                }
1307                ServerEvent::Body(chunk) => self.body.extend_from_slice(chunk),
1308                ServerEvent::RequestEnd => break,
1309                ServerEvent::NeedInput => self.fill()?,
1310                ServerEvent::AwaitingResponse => {
1311                    return Err(Error::Http(HttpError::InvalidState(
1312                        "respond to the previous request first",
1313                    )));
1314                }
1315                _ => return Ok(None),
1316            }
1317        }
1318        match self.conn.request() {
1319            Some(head) => Ok(Some(Incoming {
1320                head,
1321                body: &self.body,
1322            })),
1323            None => Ok(None),
1324        }
1325    }
1326
1327    /// Writes `response` to the socket. A streamed response continues with
1328    /// [`send_body`](Self::send_body) and [`end_body`](Self::end_body).
1329    ///
1330    /// # Errors
1331    ///
1332    /// [`Error::Http`] when the response is invalid or out of order (see
1333    /// [`ServerConn::respond`]); [`Error::Io`] when the write fails.
1334    ///
1335    /// # Examples
1336    ///
1337    /// See [`Connection`].
1338    pub fn respond(&mut self, response: &Response) -> Result<(), Error> {
1339        self.out.clear();
1340        let date = now_date();
1341        // A large full body goes out after the head in one vectored write
1342        // instead of being copied into the output buffer.
1343        let tail = match response.body_bytes() {
1344            Some(body) if body.len() > VECTORED_BODY => {
1345                let plan = self.conn.respond_head_dated(
1346                    response,
1347                    Some(&date.as_bytes()[..]),
1348                    &mut self.out,
1349                )?;
1350                if plan == BodyPlan::Raw { body } else { &[][..] }
1351            }
1352            _ => {
1353                self.conn
1354                    .respond_with_date(response, &date, &mut self.out)?;
1355                &[][..]
1356            }
1357        };
1358        self.write_deadline = self.response_deadline.map(|d| Instant::now() + d);
1359        self.flush_with(tail)
1360    }
1361
1362    /// Writes an interim response (for example `103 Early Hints`) before
1363    /// the final one, through [`ServerConn::send_informational`].
1364    ///
1365    /// # Errors
1366    ///
1367    /// As [`ServerConn::send_informational`], plus [`Error::Io`].
1368    ///
1369    /// # Examples
1370    ///
1371    /// ```
1372    /// # fn demo(conn: &mut http_net::blocking::Connection) -> Result<(), http_net::blocking::Error> {
1373    /// use http_net::Response;
1374    ///
1375    /// conn.send_informational(&Response::new(103).header("link", "</app.css>; rel=preload; as=style"))?;
1376    /// conn.respond(&Response::text(200, "page"))?;
1377    /// # Ok(()) }
1378    /// ```
1379    pub fn send_informational(&mut self, response: &Response) -> Result<(), Error> {
1380        self.out.clear();
1381        self.conn.send_informational(response, &mut self.out)?;
1382        self.flush_out()
1383    }
1384
1385    /// Writes body bytes of a streamed response.
1386    ///
1387    /// # Errors
1388    ///
1389    /// As [`ServerConn::send_body`], plus [`Error::Io`].
1390    ///
1391    /// # Examples
1392    ///
1393    /// ```
1394    /// # fn demo(conn: &mut http_net::blocking::Connection) -> Result<(), http_net::blocking::Error> {
1395    /// conn.respond(&http_net::Response::new(200).chunked())?;
1396    /// conn.send_body(b"first")?;
1397    /// conn.end_body()?;
1398    /// # Ok(()) }
1399    /// ```
1400    pub fn send_body(&mut self, data: &[u8]) -> Result<(), Error> {
1401        self.out.clear();
1402        self.conn.send_body(data, &mut self.out)?;
1403        self.flush_out()
1404    }
1405
1406    /// Ends a streamed response.
1407    ///
1408    /// # Errors
1409    ///
1410    /// As [`ServerConn::end_body`], plus [`Error::Io`].
1411    ///
1412    /// # Examples
1413    ///
1414    /// See [`send_body`](Self::send_body).
1415    pub fn end_body(&mut self) -> Result<(), Error> {
1416        self.out.clear();
1417        self.conn.end_body(&mut self.out)?;
1418        self.flush_out()
1419    }
1420
1421    /// Writes `out`. While a response deadline runs, each write waits at
1422    /// most the time left (and never longer than the socket's own write
1423    /// timeout); the deadline ends with the response.
1424    fn flush_out(&mut self) -> Result<(), Error> {
1425        self.flush_with(&[])
1426    }
1427
1428    /// Writes the serialized bytes in `out` and then `tail` (a full body
1429    /// sent as it is, not copied into `out`), with vectored writes while
1430    /// both remain.
1431    fn flush_with(&mut self, tail: &[u8]) -> Result<(), Error> {
1432        let head_len = self.out.len();
1433        let total = head_len + tail.len();
1434        let mut written = 0;
1435        while written < total {
1436            if let Some(deadline) = self.write_deadline {
1437                let left = deadline.saturating_duration_since(Instant::now());
1438                if left.is_zero() {
1439                    return Err(response_timed_out());
1440                }
1441                let wait = self.write_timeout.map_or(left, |t| t.min(left));
1442                self.stream.set_write_timeout(Some(wait))?;
1443                self.write_shortened = true;
1444            }
1445            let result = if written >= head_len {
1446                self.stream.write(&tail[written - head_len..])
1447            } else if tail.is_empty() {
1448                self.stream.write(&self.out[written..])
1449            } else {
1450                let parts = [IoSlice::new(&self.out[written..]), IoSlice::new(tail)];
1451                self.stream.write_vectored(&parts)
1452            };
1453            match result {
1454                Ok(0) => return Err(Error::Io(io::ErrorKind::WriteZero.into())),
1455                Ok(n) => written += n,
1456                Err(e) if e.kind() == io::ErrorKind::Interrupted => {}
1457                Err(e)
1458                    if is_timeout(&e)
1459                        && self.write_deadline.is_some_and(|d| Instant::now() >= d) =>
1460                {
1461                    return Err(response_timed_out());
1462                }
1463                Err(e) => return Err(Error::Io(e)),
1464            }
1465        }
1466        if self.conn.progress() != Progress::WritingBody {
1467            self.write_deadline = None;
1468            if self.write_shortened {
1469                self.stream.set_write_timeout(self.write_timeout)?;
1470                self.write_shortened = false;
1471            }
1472        }
1473        if self.out.capacity() > OUT_RETAIN {
1474            self.out = Vec::new();
1475        }
1476        Ok(())
1477    }
1478
1479    /// Whether a `101` (or a 2xx to `CONNECT`) was sent.
1480    ///
1481    /// # Examples
1482    ///
1483    /// See [`into_upgraded`](Self::into_upgraded).
1484    #[must_use]
1485    pub fn is_upgraded(&self) -> bool {
1486        self.conn.is_upgraded()
1487    }
1488
1489    /// The socket and the bytes of the new protocol, after an upgrade;
1490    /// `None` if the connection was not upgraded. The socket's read timeout
1491    /// is the one it had when the `Connection` was created (a request
1492    /// deadline may have shortened it while the request was read).
1493    ///
1494    /// # Examples
1495    ///
1496    /// ```
1497    /// # fn demo(mut conn: http_net::blocking::Connection) {
1498    /// if conn.is_upgraded() {
1499    ///     let up = conn.into_upgraded().unwrap();
1500    ///     // speak the new protocol on up.stream, starting with up.leftover
1501    /// #   let _ = up;
1502    /// }
1503    /// # }
1504    /// ```
1505    #[must_use]
1506    pub fn into_upgraded(self) -> Option<Upgraded> {
1507        if !self.is_upgraded() {
1508            return None;
1509        }
1510        let target = self
1511            .conn
1512            .request()
1513            .map(|r| r.target().to_string())
1514            .unwrap_or_default();
1515        if self.shortened {
1516            // Best effort: the new protocol must not inherit what was left
1517            // of the request deadline. Setting a timeout this socket has
1518            // already accepted does not fail in practice, and the hand-off
1519            // is more useful than refusing it over one.
1520            let _ = self.stream.set_read_timeout(self.read_timeout);
1521        }
1522        Some(Upgraded {
1523            leftover: self.conn.remaining_input().to_vec(),
1524            target,
1525            stream: self.stream,
1526        })
1527    }
1528
1529    /// Closes the connection gracefully: stops sending, briefly drains what
1530    /// the client is still sending, and drops the socket.
1531    ///
1532    /// # Examples
1533    ///
1534    /// See [`Connection`].
1535    pub fn close(self) {
1536        drain_and_close(self.stream);
1537    }
1538}
1539
1540/// A response fetched by [`get`], [`post`], [`Client::get`], or
1541/// [`Client::request`], fully read.
1542///
1543/// # Examples
1544///
1545/// See [`Server`].
1546#[derive(Clone, PartialEq, Eq)]
1547pub struct ClientResponse {
1548    status: u16,
1549    headers: Vec<(String, Vec<u8>)>,
1550    body: Vec<u8>,
1551}
1552
1553/// Shows status, fields, and body size; the values of credential fields
1554/// (`set-cookie` above all) are replaced by `<redacted N bytes>`.
1555impl fmt::Debug for ClientResponse {
1556    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1557        struct Fields<'a>(&'a [(String, Vec<u8>)]);
1558        impl fmt::Debug for Fields<'_> {
1559            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1560                f.debug_list()
1561                    .entries(self.0.iter().map(|(name, value)| {
1562                        (
1563                            name.as_str(),
1564                            FieldValue {
1565                                name: name.as_bytes(),
1566                                value,
1567                            },
1568                        )
1569                    }))
1570                    .finish()
1571            }
1572        }
1573        f.debug_struct("ClientResponse")
1574            .field("status", &self.status)
1575            .field("headers", &Fields(&self.headers))
1576            .field("body", &format_args!("{} bytes", self.body.len()))
1577            .finish()
1578    }
1579}
1580
1581impl ClientResponse {
1582    /// The status code.
1583    ///
1584    /// # Examples
1585    ///
1586    /// See [`Server`].
1587    #[must_use]
1588    pub fn status(&self) -> u16 {
1589        self.status
1590    }
1591
1592    /// The fields in arrival order.
1593    ///
1594    /// # Examples
1595    ///
1596    /// Not run: it needs a server on port 8080.
1597    ///
1598    /// ```no_run
1599    /// let resp = http_net::blocking::get("http://127.0.0.1:8080/")?;
1600    /// for (name, value) in resp.headers() {
1601    ///     let _ = (name, value);
1602    /// }
1603    /// # Ok::<(), http_net::blocking::Error>(())
1604    /// ```
1605    pub fn headers(&self) -> impl Iterator<Item = (&str, &[u8])> {
1606        self.headers.iter().map(|(n, v)| (n.as_str(), v.as_slice()))
1607    }
1608
1609    /// The first field named `name` (ASCII case-insensitive).
1610    ///
1611    /// # Examples
1612    ///
1613    /// Not run: it needs a server on port 8080.
1614    ///
1615    /// ```no_run
1616    /// let resp = http_net::blocking::get("http://127.0.0.1:8080/")?;
1617    /// let _ = resp.header("content-type");
1618    /// # Ok::<(), http_net::blocking::Error>(())
1619    /// ```
1620    #[must_use]
1621    pub fn header(&self, name: &str) -> Option<&[u8]> {
1622        self.headers
1623            .iter()
1624            .find(|(n, _)| n.eq_ignore_ascii_case(name))
1625            .map(|(_, v)| v.as_slice())
1626    }
1627
1628    /// The body.
1629    ///
1630    /// # Examples
1631    ///
1632    /// See [`Server`].
1633    #[must_use]
1634    pub fn body(&self) -> &[u8] {
1635        &self.body
1636    }
1637
1638    /// The body, if it is UTF-8.
1639    ///
1640    /// # Examples
1641    ///
1642    /// See [`Server`].
1643    #[must_use]
1644    pub fn text(&self) -> Option<&str> {
1645        core::str::from_utf8(&self.body).ok()
1646    }
1647
1648    /// Takes the body.
1649    ///
1650    /// # Examples
1651    ///
1652    /// Not run: it needs a server on port 8080.
1653    ///
1654    /// ```no_run
1655    /// let bytes = http_net::blocking::get("http://127.0.0.1:8080/")?.into_body();
1656    /// # let _ = bytes;
1657    /// # Ok::<(), http_net::blocking::Error>(())
1658    /// ```
1659    #[must_use]
1660    pub fn into_body(self) -> Vec<u8> {
1661        self.body
1662    }
1663}
1664
1665/// Fetches `url` with `GET` using the default [`Client`].
1666///
1667/// # Errors
1668///
1669/// [`Error::InvalidUrl`] for anything but `http://host[:port][/path[?query]]`
1670/// (a `#fragment` is dropped),
1671/// [`Error::Io`] for connection failures and timeouts, [`Error::Http`] for
1672/// a response this crate refuses (including one over the body limit).
1673///
1674/// # Examples
1675///
1676/// See [`Server`].
1677pub fn get(url: &str) -> Result<ClientResponse, Error> {
1678    Client::new().get(url)
1679}
1680
1681/// Sends `body` to `url` with `POST` and `content-type: content_type`,
1682/// using the default [`Client`].
1683///
1684/// # Errors
1685///
1686/// As [`get`], plus [`Error::Http`] for a content type that is not a valid
1687/// field value.
1688///
1689/// # Examples
1690///
1691/// ```
1692/// use http_net::{blocking, Response};
1693///
1694/// let server = blocking::Server::bind("127.0.0.1:0")?;
1695/// let addr = server.local_addr();
1696/// let stop = server.shutdown_handle();
1697/// let t = std::thread::spawn(move || server.serve(|_, body| Response::text(200, &body.len().to_string())));
1698///
1699/// let resp = blocking::post(&format!("http://{addr}/notes"), "text/plain", b"hello")?;
1700/// assert_eq!(resp.text(), Some("5"));
1701///
1702/// stop.shutdown();
1703/// t.join().unwrap()?;
1704/// # Ok::<(), Box<dyn std::error::Error>>(())
1705/// ```
1706pub fn post(url: &str, content_type: &str, body: &[u8]) -> Result<ClientResponse, Error> {
1707    let request = Request::post("/")
1708        .header("content-type", content_type)
1709        .body(body.to_vec());
1710    Client::new().request(url, request)
1711}
1712
1713/// Binds `addr` and serves `handler` with the default [`ServerConfig`]
1714/// until the process ends: the shortest way to run a server. Use
1715/// [`Server`] for a shutdown handle, settings, or an upgrade hook.
1716///
1717/// # Errors
1718///
1719/// The bind error, or a persistent accept failure (see [`Server::serve`]).
1720///
1721/// # Examples
1722///
1723/// Not run: it serves until the process ends.
1724///
1725/// ```no_run
1726/// use http_net::{blocking, Response};
1727///
1728/// blocking::serve("127.0.0.1:8080", |req, _body| Response::text(200, req.path()))?;
1729/// # Ok::<(), std::io::Error>(())
1730/// ```
1731pub fn serve<H>(addr: impl ToSocketAddrs, handler: H) -> io::Result<()>
1732where
1733    H: Fn(&RequestHead<'_>, &[u8]) -> Response + Send + Sync + 'static,
1734{
1735    Server::bind(addr)?.serve(handler)
1736}
1737
1738/// A blocking HTTP/1.1 client: one connection per request.
1739///
1740/// | Setting | Default |
1741/// |---|---|
1742/// | limits | [`Limits::new`] with a 16 MiB body |
1743/// | connect, read, and write timeout | 30 s each |
1744/// | total deadline for one exchange (connect, write, read) | none |
1745///
1746/// # Examples
1747///
1748/// Not run: it needs a server on port 8080.
1749///
1750/// ```no_run
1751/// use std::time::Duration;
1752/// use http_net::{blocking::Client, Limits};
1753///
1754/// let client = Client::new()
1755///     .with_limits(Limits::new().with_max_body(64 << 20))
1756///     .with_timeout(Duration::from_secs(5));
1757/// let resp = client.get("http://127.0.0.1:8080/big")?;
1758/// # let _ = resp;
1759/// # Ok::<(), http_net::blocking::Error>(())
1760/// ```
1761#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1762pub struct Client {
1763    limits: Limits,
1764    timeout: Duration,
1765    deadline: Option<Duration>,
1766}
1767
1768impl Default for Client {
1769    fn default() -> Self {
1770        Self::new()
1771    }
1772}
1773
1774impl Client {
1775    /// The defaults (see the table on [`Client`]).
1776    ///
1777    /// # Examples
1778    ///
1779    /// ```
1780    /// let _ = http_net::blocking::Client::new();
1781    /// ```
1782    #[must_use]
1783    pub const fn new() -> Self {
1784        Self {
1785            limits: Limits::new().with_max_body(16 * 1024 * 1024),
1786            timeout: Duration::from_secs(30),
1787            deadline: None,
1788        }
1789    }
1790
1791    /// Sets the response limits.
1792    ///
1793    /// # Examples
1794    ///
1795    /// ```
1796    /// let _ = http_net::blocking::Client::new().with_limits(http_net::Limits::new());
1797    /// ```
1798    #[must_use]
1799    pub const fn with_limits(mut self, limits: Limits) -> Self {
1800        self.limits = limits;
1801        self
1802    }
1803
1804    /// Sets the connect, read, and write timeout (zero is raised to 1 ms).
1805    ///
1806    /// # Examples
1807    ///
1808    /// ```
1809    /// let _ = http_net::blocking::Client::new().with_timeout(std::time::Duration::from_secs(2));
1810    /// ```
1811    #[must_use]
1812    pub const fn with_timeout(mut self, timeout: Duration) -> Self {
1813        self.timeout = if timeout.is_zero() {
1814            Duration::from_millis(1)
1815        } else {
1816            timeout
1817        };
1818        self
1819    }
1820
1821    /// Sets a total deadline for one exchange: connecting, writing the
1822    /// request, and reading the whole response. The per-operation timeout
1823    /// of [`with_timeout`](Self::with_timeout) cannot stop a server that
1824    /// sends one byte just inside it; this deadline can. Name resolution is
1825    /// not bounded: `std` offers no timeout for it. Pass a `Duration`, or
1826    /// `None` (the default) for no deadline.
1827    ///
1828    /// # Examples
1829    ///
1830    /// ```
1831    /// use std::time::Duration;
1832    /// let _ = http_net::blocking::Client::new().with_deadline(Duration::from_secs(10));
1833    /// ```
1834    #[must_use]
1835    pub fn with_deadline(mut self, deadline: impl Into<Option<Duration>>) -> Self {
1836        self.deadline = deadline.into();
1837        self
1838    }
1839
1840    /// Fetches `url` with `GET`.
1841    ///
1842    /// # Errors
1843    ///
1844    /// As [`get`].
1845    ///
1846    /// # Examples
1847    ///
1848    /// See [`Client`].
1849    pub fn get(&self, url: &str) -> Result<ClientResponse, Error> {
1850        self.request(url, Request::get("/"))
1851    }
1852
1853    /// Sends `request` to the `http://` URL `url` and reads the response.
1854    /// The URL gives the authority (written as `host`) and the target, which
1855    /// replaces the target `request` was built with; the method, fields,
1856    /// and body come from `request`. The request is sent with
1857    /// `connection: close` on a connection of its own.
1858    ///
1859    /// # Errors
1860    ///
1861    /// As [`get`]; [`Error::Http`] with the builder's first error;
1862    /// [`HttpError::InvalidHost`] when `request` already has a `host` (the
1863    /// URL supplies it); [`HttpError::InvalidState`] for a streamed body
1864    /// (`chunked` or `content_length`: this client sends full bodies) or an
1865    /// upgrade request (it cannot hand the connection over; use
1866    /// [`ClientConn`]). A [`Request::expect_continue`] request with its full
1867    /// body fails with [`Error::Http`] of [`HttpError::InvalidState`] (the
1868    /// expectation needs a streamed body).
1869    ///
1870    /// # Examples
1871    ///
1872    /// ```
1873    /// use http_net::{blocking::{self, Client}, Request, Response};
1874    ///
1875    /// let server = blocking::Server::bind("127.0.0.1:0")?;
1876    /// let addr = server.local_addr();
1877    /// let stop = server.shutdown_handle();
1878    /// let t = std::thread::spawn(move || {
1879    ///     server.serve(|req, body| Response::text(200, &format!("{} {} {}", req.method_str(), req.path(), body.len())))
1880    /// });
1881    ///
1882    /// let put = Request::put("/").header("content-type", "application/json").body(&b"{}"[..]);
1883    /// let resp = Client::new().request(&format!("http://{addr}/items/7"), put)?;
1884    /// assert_eq!(resp.text(), Some("PUT /items/7 2"));
1885    ///
1886    /// stop.shutdown();
1887    /// t.join().unwrap()?;
1888    /// # Ok::<(), Box<dyn std::error::Error>>(())
1889    /// ```
1890    pub fn request(&self, url: &str, request: Request) -> Result<ClientResponse, Error> {
1891        let url = Url::parse(url)?;
1892        let request = retarget(&request, url.target, url.authority)?;
1893        let deadline = self.deadline.map(|d| Instant::now() + d);
1894        let addrs = (url.host, url.port).to_socket_addrs()?;
1895        let mut stream = connect_any(addrs, self.timeout, deadline)?;
1896        let mut conn = ClientConn::with_limits(self.limits);
1897        let mut out = Vec::new();
1898        conn.send_request(&request, &mut out)?;
1899        let mut io = Timed {
1900            stream: &mut stream,
1901            timeout: self.timeout,
1902            deadline,
1903        };
1904        io.write_all(&out)?;
1905        read_response(&mut io, &mut conn)
1906    }
1907}
1908
1909/// Rebuilds `request` for a URL: the URL's target, `host` from its
1910/// authority first, then the request's own fields, body, and flags, and
1911/// always `connection: close` (one connection per exchange).
1912fn retarget(request: &Request, target: &str, authority: &str) -> Result<Request, Error> {
1913    if let Some(e) = request.error() {
1914        return Err(Error::Http(e));
1915    }
1916    if request.has_host {
1917        return Err(Error::Http(HttpError::InvalidHost));
1918    }
1919    if request.upgrade {
1920        return Err(Error::Http(HttpError::InvalidState(
1921            "the blocking client cannot hand over an upgraded connection; use ClientConn",
1922        )));
1923    }
1924    let mut rebuilt = Request::new(request.method(), target).header("host", authority);
1925    for (name, value) in serialized_fields(request.fields()) {
1926        let name = core::str::from_utf8(name).unwrap_or("");
1927        if request.expect_continue
1928            && name.eq_ignore_ascii_case("expect")
1929            && value.eq_ignore_ascii_case(b"100-continue")
1930        {
1931            // Added again below by its builder method.
1932            continue;
1933        }
1934        rebuilt = rebuilt.header(name, value);
1935    }
1936    if request.expect_continue {
1937        rebuilt = rebuilt.expect_continue();
1938    }
1939    rebuilt = match &request.body {
1940        OutBody::Full(body) => rebuilt.body(body.clone()),
1941        OutBody::Length(_) | OutBody::Chunked => {
1942            return Err(Error::Http(HttpError::InvalidState(
1943                "the blocking client sends full bodies only; use ClientConn to stream",
1944            )));
1945        }
1946    };
1947    let rebuilt = rebuilt.close();
1948    match rebuilt.error() {
1949        Some(e) => Err(Error::Http(e)),
1950        None => Ok(rebuilt),
1951    }
1952}
1953
1954/// Connects to the first address that accepts, each attempt bounded by
1955/// `timeout` and by what is left before `deadline`.
1956fn connect_any(
1957    addrs: impl IntoIterator<Item = SocketAddr>,
1958    timeout: Duration,
1959    deadline: Option<Instant>,
1960) -> Result<TcpStream, Error> {
1961    let stream = first_connected(addrs, timeout, deadline, TcpStream::connect_timeout)?;
1962    stream.set_read_timeout(Some(timeout))?;
1963    stream.set_write_timeout(Some(timeout))?;
1964    stream.set_nodelay(true)?;
1965    Ok(stream)
1966}
1967
1968/// Tries each address in turn with `connect`, each attempt waiting at most
1969/// `timeout` and what is left of `deadline`; the first success wins, and
1970/// the last failure is the error. The connect function is a parameter so
1971/// the fallback logic is tested without sockets.
1972fn first_connected<S>(
1973    addrs: impl IntoIterator<Item = SocketAddr>,
1974    timeout: Duration,
1975    deadline: Option<Instant>,
1976    mut connect: impl FnMut(&SocketAddr, Duration) -> io::Result<S>,
1977) -> Result<S, Error> {
1978    let mut last = None;
1979    for addr in addrs {
1980        let wait = match deadline {
1981            Some(d) => {
1982                let left = d.saturating_duration_since(Instant::now());
1983                if left.is_zero() {
1984                    return Err(exchange_timed_out());
1985                }
1986                left.min(timeout)
1987            }
1988            None => timeout,
1989        };
1990        match connect(&addr, wait) {
1991            Ok(stream) => return Ok(stream),
1992            Err(e) => last = Some(e),
1993        }
1994    }
1995    Err(Error::Io(last.unwrap_or_else(|| {
1996        io::Error::new(io::ErrorKind::NotFound, "the host resolved to no address")
1997    })))
1998}
1999
2000fn exchange_timed_out() -> Error {
2001    Error::Io(io::Error::new(
2002        io::ErrorKind::TimedOut,
2003        "the exchange did not finish within the client deadline",
2004    ))
2005}
2006
2007/// A client socket whose reads and writes stop at a total deadline: each
2008/// operation waits at most the time left, and never longer than the
2009/// per-operation timeout.
2010struct Timed<'a> {
2011    stream: &'a mut TcpStream,
2012    timeout: Duration,
2013    deadline: Option<Instant>,
2014}
2015
2016impl Timed<'_> {
2017    /// Sets the socket timeouts for the next operation.
2018    fn arm(&mut self) -> Result<(), Error> {
2019        if let Some(d) = self.deadline {
2020            let left = d.saturating_duration_since(Instant::now());
2021            if left.is_zero() {
2022                return Err(exchange_timed_out());
2023            }
2024            let wait = left.min(self.timeout);
2025            self.stream.set_read_timeout(Some(wait))?;
2026            self.stream.set_write_timeout(Some(wait))?;
2027        }
2028        Ok(())
2029    }
2030
2031    /// Maps a timeout that ran into the deadline to the deadline's error.
2032    fn check(&self, e: io::Error) -> Error {
2033        if is_timeout(&e) && self.deadline.is_some_and(|d| Instant::now() >= d) {
2034            exchange_timed_out()
2035        } else {
2036            Error::Io(e)
2037        }
2038    }
2039
2040    fn write_all(&mut self, mut data: &[u8]) -> Result<(), Error> {
2041        while !data.is_empty() {
2042            self.arm()?;
2043            match self.stream.write(data) {
2044                Ok(0) => return Err(Error::Io(io::ErrorKind::WriteZero.into())),
2045                Ok(n) => data = &data[n..],
2046                Err(e) if e.kind() == io::ErrorKind::Interrupted => {}
2047                Err(e) => return Err(self.check(e)),
2048            }
2049        }
2050        Ok(())
2051    }
2052
2053    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
2054        loop {
2055            self.arm()?;
2056            match self.stream.read(buf) {
2057                Err(e) if e.kind() == io::ErrorKind::Interrupted => {}
2058                Err(e) => return Err(self.check(e)),
2059                Ok(n) => return Ok(n),
2060            }
2061        }
2062    }
2063}
2064
2065fn read_response(stream: &mut Timed<'_>, conn: &mut ClientConn) -> Result<ClientResponse, Error> {
2066    let mut response = ClientResponse {
2067        status: 0,
2068        headers: Vec::new(),
2069        body: Vec::new(),
2070    };
2071    loop {
2072        match conn.poll()? {
2073            ClientEvent::Response(head) => {
2074                response.status = head.status();
2075                response.headers = head
2076                    .headers()
2077                    .map(|(n, v)| (n.to_string(), v.to_vec()))
2078                    .collect();
2079            }
2080            ClientEvent::Body(chunk) => response.body.extend_from_slice(chunk),
2081            ClientEvent::ResponseEnd => return Ok(response),
2082            ClientEvent::NeedInput => {
2083                let spare = conn.read_buf();
2084                if spare.is_empty() {
2085                    return Err(Error::Http(HttpError::InvalidState(
2086                        "input buffer full while the parser needs input",
2087                    )));
2088                }
2089                let n = stream.read(spare)?;
2090                if n == 0 {
2091                    conn.feed_eof();
2092                } else {
2093                    conn.commit(n);
2094                }
2095            }
2096            _ => {
2097                return Err(Error::Http(HttpError::InvalidState(
2098                    "the connection ended without a complete response",
2099                )));
2100            }
2101        }
2102    }
2103}
2104
2105/// The parts of an `http://` URL needed to send a request.
2106#[derive(Debug, PartialEq, Eq)]
2107struct Url<'a> {
2108    /// `host[:port]` as written, for the Host header.
2109    authority: &'a str,
2110    /// The host for name resolution (brackets removed from IPv6 literals).
2111    host: &'a str,
2112    port: u16,
2113    /// Path and query; `/` when the URL has no path.
2114    target: &'a str,
2115}
2116
2117impl<'a> Url<'a> {
2118    fn parse(url: &'a str) -> Result<Self, Error> {
2119        let scheme_end = url.find("://").ok_or(Error::InvalidUrl("missing scheme"))?;
2120        if !url[..scheme_end].eq_ignore_ascii_case("http") {
2121            return Err(Error::InvalidUrl(
2122                "only http:// is supported (no TLS in this crate)",
2123            ));
2124        }
2125        let rest = &url[scheme_end + 3..];
2126        // The fragment is never sent.
2127        let rest = rest.split_once('#').map_or(rest, |(r, _)| r);
2128        let auth_end = rest.find(['/', '?']).unwrap_or(rest.len());
2129        let authority = &rest[..auth_end];
2130        let target = match &rest[auth_end..] {
2131            "" => "/",
2132            t if t.starts_with('?') => {
2133                return Err(Error::InvalidUrl("a query needs a path, for example /?q"));
2134            }
2135            t => t,
2136        };
2137        if authority.is_empty() {
2138            return Err(Error::InvalidUrl("missing host"));
2139        }
2140        if authority.contains('@') {
2141            return Err(Error::InvalidUrl(
2142                "credentials in the URL are not supported",
2143            ));
2144        }
2145        let (host, port) = if let Some(v6) = authority.strip_prefix('[') {
2146            let (inside, after) = v6.split_once(']').ok_or(Error::InvalidUrl("unclosed ["))?;
2147            let port = match after {
2148                "" => None,
2149                p => Some(
2150                    p.strip_prefix(':')
2151                        .ok_or(Error::InvalidUrl("junk after ]"))?,
2152                ),
2153            };
2154            (inside, port)
2155        } else {
2156            match authority.rsplit_once(':') {
2157                Some((h, p)) => (h, Some(p)),
2158                None => (authority, None),
2159            }
2160        };
2161        let port = match port {
2162            None => 80,
2163            Some(p) => p.parse().map_err(|_| Error::InvalidUrl("bad port"))?,
2164        };
2165        if host.is_empty() {
2166            return Err(Error::InvalidUrl("missing host"));
2167        }
2168        Ok(Self {
2169            authority,
2170            host,
2171            port,
2172            target,
2173        })
2174    }
2175}
2176
2177thread_local! {
2178    /// One date cache per thread: each connection thread formats `date` at
2179    /// most once per second, and nothing is shared between threads.
2180    static DATE: Cell<DateCache> = const { Cell::new(DateCache::new()) };
2181}
2182
2183/// The current time as a `Date` value, from a per-thread
2184/// [`DateCache`]: the system clock is read on every call, the value is
2185/// reformatted only when the second changes. [`Connection::respond`] and
2186/// [`Server`] write it on every response that did not set its own `date`.
2187///
2188/// # Examples
2189///
2190/// ```
2191/// let date = http_net::blocking::now_date();
2192/// assert_eq!(date.as_bytes().len(), 29);
2193/// assert!(date.as_str().ends_with(" GMT"));
2194/// ```
2195#[must_use]
2196pub fn now_date() -> HttpDate {
2197    let secs = SystemTime::now()
2198        .duration_since(UNIX_EPOCH)
2199        .map_or(0, |d| d.as_secs());
2200    DATE.with(|cell| {
2201        let mut cache = cell.get();
2202        let date = *cache.update(secs);
2203        cell.set(cache);
2204        date
2205    })
2206}
2207
2208#[cfg(test)]
2209mod tests {
2210    use super::*;
2211
2212    /// T-41: a listener whose accept keeps failing never spins a core (every
2213    /// failure waits) and the loop gives up only after 1,000 failures in a
2214    /// row; a success in between starts the count again.
2215    #[test]
2216    fn test_accept_errors_back_off_and_end_after_the_limit() {
2217        let error = || io::Error::from(io::ErrorKind::ConnectionAborted);
2218        let mut backoff = AcceptBackoff::default();
2219        for _ in 0..AcceptBackoff::LIMIT {
2220            let wait = backoff.failure(error()).expect("still tolerated");
2221            assert!(wait >= Duration::from_millis(10), "a failure must wait");
2222        }
2223        let last = backoff.failure(error()).expect_err("the limit is reached");
2224        assert_eq!(last.kind(), io::ErrorKind::ConnectionAborted);
2225
2226        let mut backoff = AcceptBackoff::default();
2227        for _ in 0..3 {
2228            for _ in 0..AcceptBackoff::LIMIT {
2229                assert!(backoff.failure(error()).is_ok());
2230            }
2231            backoff.success();
2232        }
2233        assert!(
2234            backoff.failure(error()).is_ok(),
2235            "a success resets the count"
2236        );
2237    }
2238
2239    /// T-40, byte cap: a peer that keeps sending as fast as it can is
2240    /// drained by at most `DRAIN_LIMIT` bytes (plus the last read), then
2241    /// the drain stops though the peer has neither stopped nor closed. The
2242    /// socket tests in `tests/localhost.rs` show the slot is freed; this
2243    /// one shows which cap freed it.
2244    #[test]
2245    fn test_lingering_drain_stops_at_the_byte_cap() {
2246        let listener = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
2247        let mut client = TcpStream::connect(listener.local_addr().unwrap()).unwrap();
2248        let (mut server, _) = listener.accept().unwrap();
2249        let flood = thread::spawn(move || {
2250            // Ends when the server closes its side; the error is expected.
2251            let _ = client.write_all(&vec![b'x'; 16 * DRAIN_LIMIT]);
2252            client
2253        });
2254        let started = Instant::now();
2255        let drained = lingering_drain(&mut server);
2256        let took = started.elapsed();
2257        drop(server);
2258        drop(flood.join().unwrap());
2259        assert!(
2260            (DRAIN_LIMIT..DRAIN_LIMIT + 4096).contains(&drained),
2261            "drained {drained} bytes"
2262        );
2263        assert!(took < DRAIN_TOTAL, "the byte cap ended it, after {took:?}");
2264    }
2265
2266    #[test]
2267    fn test_time_setters_take_a_duration_an_option_or_none() {
2268        let five = Duration::from_secs(5);
2269        let c = ServerConfig::new()
2270            .with_read_timeout(five)
2271            .with_request_timeout(Some(five))
2272            .with_write_timeout(None)
2273            .with_response_deadline(five)
2274            .with_max_requests_per_connection(0);
2275        assert_eq!(c.read_timeout(), Some(five));
2276        assert_eq!(c.request_timeout(), Some(five));
2277        assert_eq!(c.write_timeout(), None);
2278        assert_eq!(c.response_deadline(), Some(five));
2279        assert_eq!(c.max_requests_per_connection(), Some(1));
2280        let c = c.with_max_requests_per_connection(None);
2281        assert_eq!(c.max_requests_per_connection(), None);
2282        assert_eq!(Client::new().with_deadline(five).deadline, Some(five));
2283        assert_eq!(Client::new().with_deadline(None).deadline, None);
2284    }
2285
2286    #[test]
2287    fn test_now_date_is_the_current_second() {
2288        let before = SystemTime::now()
2289            .duration_since(UNIX_EPOCH)
2290            .map_or(0, |d| d.as_secs());
2291        let shown = now_date();
2292        let after = SystemTime::now()
2293            .duration_since(UNIX_EPOCH)
2294            .map_or(0, |d| d.as_secs());
2295        assert!(
2296            shown == HttpDate::from_unix_seconds(before)
2297                || shown == HttpDate::from_unix_seconds(after),
2298            "{shown}"
2299        );
2300        // The same second twice comes from the cache and is equal.
2301        assert_eq!(now_date().as_bytes().len(), 29);
2302    }
2303
2304    /// E-198: a name that resolves to several addresses is tried in order;
2305    /// an address that refuses the connection does not end the attempt. The
2306    /// fallback is tested with a scripted connect, so no port has to stay
2307    /// closed (a freed ephemeral port can be taken again by another test or
2308    /// process, which made a socket version of this test flaky).
2309    #[test]
2310    fn test_first_connected_refused_first_address_tries_the_next() {
2311        let a: SocketAddr = "127.0.0.1:1".parse().unwrap();
2312        let b: SocketAddr = "127.0.0.1:2".parse().unwrap();
2313        let mut tried = Vec::new();
2314        let got = first_connected([a, b], Duration::from_secs(5), None, |addr, _| {
2315            tried.push(*addr);
2316            if *addr == a {
2317                Err(io::Error::from(io::ErrorKind::ConnectionRefused))
2318            } else {
2319                Ok(*addr)
2320            }
2321        });
2322        assert_eq!(got.unwrap(), b);
2323        assert_eq!(tried, [a, b]);
2324
2325        let err = first_connected([a, b], Duration::from_secs(5), None, |addr, _| {
2326            Err::<(), _>(io::Error::new(
2327                io::ErrorKind::ConnectionRefused,
2328                addr.to_string(),
2329            ))
2330        })
2331        .unwrap_err();
2332        assert!(
2333            matches!(&err, Error::Io(e) if e.to_string() == b.to_string()),
2334            "the last failure is reported: {err}"
2335        );
2336        let err = first_connected(
2337            Vec::<SocketAddr>::new(),
2338            Duration::from_secs(5),
2339            None,
2340            |_, _| Ok(()),
2341        )
2342        .unwrap_err();
2343        assert!(
2344            matches!(&err, Error::Io(e) if e.kind() == io::ErrorKind::NotFound),
2345            "{err}"
2346        );
2347    }
2348
2349    /// Each attempt waits at most the timeout and what is left of the
2350    /// deadline.
2351    #[test]
2352    fn test_first_connected_each_wait_is_capped_by_the_deadline() {
2353        let a: SocketAddr = "127.0.0.1:1".parse().unwrap();
2354        let mut waits = Vec::new();
2355        let deadline = Instant::now() + Duration::from_secs(60);
2356        let _ = first_connected([a, a], Duration::from_secs(5), Some(deadline), |_, wait| {
2357            waits.push(wait);
2358            Err::<(), _>(io::Error::from(io::ErrorKind::ConnectionRefused))
2359        });
2360        assert_eq!(waits, [Duration::from_secs(5), Duration::from_secs(5)]);
2361        waits.clear();
2362        let soon = Instant::now() + Duration::from_secs(2);
2363        let _ = first_connected([a], Duration::from_secs(5), Some(soon), |_, wait| {
2364            waits.push(wait);
2365            Err::<(), _>(io::Error::from(io::ErrorKind::ConnectionRefused))
2366        });
2367        assert!(waits[0] <= Duration::from_secs(2), "{waits:?}");
2368    }
2369
2370    /// The socket path: a live listener is reached and the stream gets its
2371    /// timeouts.
2372    #[test]
2373    fn test_connect_any_reaches_a_listener() {
2374        let open = TcpListener::bind("127.0.0.1:0").unwrap();
2375        let good = open.local_addr().unwrap();
2376        let stream = connect_any([good], Duration::from_secs(5), None).unwrap();
2377        assert_eq!(stream.peer_addr().unwrap(), good);
2378        assert_eq!(stream.read_timeout().unwrap(), Some(Duration::from_secs(5)));
2379    }
2380
2381    #[test]
2382    fn test_connect_any_past_the_deadline_times_out() {
2383        let open = TcpListener::bind("127.0.0.1:0").unwrap();
2384        let good = open.local_addr().unwrap();
2385        let err = connect_any([good], Duration::from_secs(5), Some(Instant::now())).unwrap_err();
2386        assert!(
2387            matches!(&err, Error::Io(e) if e.kind() == io::ErrorKind::TimedOut),
2388            "{err}"
2389        );
2390    }
2391
2392    #[test]
2393    fn test_client_request_with_host_is_refused() {
2394        let req = Request::get("/").header("host", "a");
2395        let err = Client::new()
2396            .request("http://127.0.0.1:1/", req)
2397            .unwrap_err();
2398        assert!(matches!(err, Error::Http(HttpError::InvalidHost)), "{err}");
2399    }
2400
2401    #[test]
2402    fn test_client_request_streamed_body_is_refused() {
2403        for req in [
2404            Request::post("/").chunked(),
2405            Request::put("/").content_length(3),
2406        ] {
2407            let err = Client::new()
2408                .request("http://127.0.0.1:1/", req)
2409                .unwrap_err();
2410            assert!(
2411                matches!(err, Error::Http(HttpError::InvalidState(_))),
2412                "{err}"
2413            );
2414        }
2415    }
2416
2417    #[test]
2418    fn test_retarget_keeps_method_fields_body_and_flags() {
2419        let original = Request::new("PATCH", "/ignored")
2420            .header("x-a", "1")
2421            .header("content-type", "text/plain")
2422            .body(&b"xyz"[..]);
2423        let r = retarget(&original, "/real?q", "example.com:8080").unwrap();
2424        assert_eq!(r.method(), "PATCH");
2425        assert_eq!(r.target(), "/real?q");
2426        assert_eq!(r.header_value("host"), Some(&b"example.com:8080"[..]));
2427        assert_eq!(r.header_value("x-a"), Some(&b"1"[..]));
2428        assert_eq!(r.body_bytes(), Some(&b"xyz"[..]));
2429        let mut out = Vec::new();
2430        ClientConn::new().send_request(&r, &mut out).unwrap();
2431        let text = String::from_utf8(out).unwrap();
2432        assert!(
2433            text.starts_with("PATCH /real?q HTTP/1.1\r\nhost: example.com:8080\r\nx-a: 1\r\n"),
2434            "{text}"
2435        );
2436        assert!(text.contains("connection: close\r\n"), "{text}");
2437        assert!(text.ends_with("\r\n\r\nxyz"), "{text}");
2438
2439        // The blocking client reads one response to its end, so it cannot
2440        // hand over an upgraded connection.
2441        let up = Request::get("/").upgrade("websocket");
2442        assert!(matches!(
2443            retarget(&up, "/", "a"),
2444            Err(Error::Http(HttpError::InvalidState(_)))
2445        ));
2446        // A builder error surfaces first.
2447        let bad = Request::get("/").header("bad name", "x");
2448        assert!(matches!(
2449            retarget(&bad, "/", "a"),
2450            Err(Error::Http(HttpError::InvalidHeaderName))
2451        ));
2452    }
2453
2454    #[test]
2455    fn test_url_parsing() {
2456        let u = Url::parse("http://127.0.0.1:8080/a/b?c=d#frag").unwrap();
2457        assert_eq!(
2458            u,
2459            Url {
2460                authority: "127.0.0.1:8080",
2461                host: "127.0.0.1",
2462                port: 8080,
2463                target: "/a/b?c=d"
2464            }
2465        );
2466        let u = Url::parse("HTTP://[::1]/").unwrap();
2467        assert_eq!((u.host, u.port, u.authority), ("::1", 80, "[::1]"));
2468        assert_eq!(Url::parse("http://example.com").unwrap().target, "/");
2469        for bad in [
2470            "example.com",
2471            "https://x/",
2472            "http:///x",
2473            "http://u:p@x/",
2474            "http://x:99999/",
2475            "http://[::1/",
2476            "http://[::1]x/",
2477            "http://x?q",
2478            "http://:80/",
2479        ] {
2480            assert!(
2481                matches!(Url::parse(bad), Err(Error::InvalidUrl(_))),
2482                "{bad}"
2483            );
2484        }
2485    }
2486
2487    #[test]
2488    fn test_error_display_and_source() {
2489        use std::error::Error as _;
2490        let e = Error::from(HttpError::BareCr);
2491        assert!(e.to_string().starts_with("HTTP error"));
2492        assert!(e.source().is_some());
2493        let e = Error::from(io::Error::other("x"));
2494        assert!(e.source().is_some());
2495        assert!(Error::InvalidUrl("y").source().is_none());
2496    }
2497}