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