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