Skip to main content

hyper/proto/h1/
conn.rs

1use std::fmt;
2#[cfg(feature = "server")]
3use std::future::Future;
4use std::io;
5use std::marker::{PhantomData, Unpin};
6use std::pin::Pin;
7use std::task::{Context, Poll};
8#[cfg(feature = "server")]
9use std::time::Duration;
10
11use crate::rt::{Read, Write};
12use bytes::{Buf, Bytes};
13use futures_core::ready;
14use http::header::{HeaderValue, CONNECTION};
15use http::{HeaderMap, Method, Version};
16use http_body::Frame;
17use httparse::ParserConfig;
18
19use super::io::Buffered;
20use super::{Decoder, Encode, EncodedBuf, Encoder, Http1Transaction, ParseContext, Wants};
21use crate::body::DecodedLength;
22#[cfg(feature = "server")]
23use crate::common::time::Time;
24use crate::headers;
25use crate::proto::{BodyLength, MessageHead};
26#[cfg(feature = "server")]
27use crate::rt::Sleep;
28
29const H2_PREFACE: &[u8] = b"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n";
30
31/// This handles a connection, which will have been established over an
32/// `Read + Write` (like a socket), and will likely include multiple
33/// `Transaction`s over HTTP.
34///
35/// The connection will determine when a message begins and ends as well as
36/// determine if this connection can be kept alive after the message,
37/// or if it is complete.
38pub(crate) struct Conn<I, B, T> {
39    io: Buffered<I, EncodedBuf<B>>,
40    state: State,
41    _marker: PhantomData<fn(T)>,
42}
43
44impl<I, B, T> Conn<I, B, T>
45where
46    I: Read + Write + Unpin,
47    B: Buf,
48    T: Http1Transaction,
49{
50    pub(crate) fn new(io: I) -> Conn<I, B, T> {
51        Conn {
52            io: Buffered::new(io),
53            state: State {
54                allow_half_close: false,
55                cached_headers: None,
56                error: None,
57                keep_alive: KA::Busy,
58                method: None,
59                h1_parser_config: ParserConfig::default(),
60                h1_max_headers: None,
61                #[cfg(feature = "server")]
62                h1_header_read_timeout: None,
63                #[cfg(feature = "server")]
64                h1_header_read_timeout_fut: None,
65                #[cfg(feature = "server")]
66                h1_header_read_timeout_running: false,
67                #[cfg(feature = "server")]
68                date_header: true,
69                #[cfg(feature = "server")]
70                timer: Time::Empty,
71                preserve_header_case: false,
72                #[cfg(feature = "ffi")]
73                preserve_header_order: false,
74                title_case_headers: false,
75                h09_responses: false,
76                #[cfg(feature = "client")]
77                on_informational: None,
78                notify_read: false,
79                reading: Reading::Init,
80                writing: Writing::Init,
81                upgrade: None,
82                // We assume a modern world where the remote speaks HTTP/1.1.
83                // If they tell us otherwise, we'll downgrade in `read_head`.
84                version: Version::HTTP_11,
85                allow_trailer_fields: false,
86            },
87            _marker: PhantomData,
88        }
89    }
90
91    #[cfg(feature = "server")]
92    pub(crate) fn set_timer(&mut self, timer: Time) {
93        self.state.timer = timer;
94    }
95
96    #[cfg(feature = "server")]
97    pub(crate) fn set_flush_pipeline(&mut self, enabled: bool) {
98        self.io.set_flush_pipeline(enabled);
99    }
100
101    pub(crate) fn set_write_strategy_queue(&mut self) {
102        self.io.set_write_strategy_queue();
103    }
104
105    pub(crate) fn set_max_buf_size(&mut self, max: usize) {
106        self.io.set_max_buf_size(max);
107    }
108
109    #[cfg(feature = "client")]
110    pub(crate) fn set_read_buf_exact_size(&mut self, sz: usize) {
111        self.io.set_read_buf_exact_size(sz);
112    }
113
114    pub(crate) fn set_write_strategy_flatten(&mut self) {
115        self.io.set_write_strategy_flatten();
116    }
117
118    pub(crate) fn set_h1_parser_config(&mut self, parser_config: ParserConfig) {
119        self.state.h1_parser_config = parser_config;
120    }
121
122    pub(crate) fn set_title_case_headers(&mut self) {
123        self.state.title_case_headers = true;
124    }
125
126    pub(crate) fn set_preserve_header_case(&mut self) {
127        self.state.preserve_header_case = true;
128    }
129
130    #[cfg(feature = "ffi")]
131    pub(crate) fn set_preserve_header_order(&mut self) {
132        self.state.preserve_header_order = true;
133    }
134
135    #[cfg(feature = "client")]
136    pub(crate) fn set_h09_responses(&mut self) {
137        self.state.h09_responses = true;
138    }
139
140    pub(crate) fn set_http1_max_headers(&mut self, val: usize) {
141        self.state.h1_max_headers = Some(val);
142    }
143
144    #[cfg(feature = "server")]
145    pub(crate) fn set_http1_header_read_timeout(&mut self, val: Duration) {
146        self.state.h1_header_read_timeout = Some(val);
147    }
148
149    #[cfg(feature = "server")]
150    pub(crate) fn set_allow_half_close(&mut self) {
151        self.state.allow_half_close = true;
152    }
153
154    #[cfg(feature = "server")]
155    pub(crate) fn disable_date_header(&mut self) {
156        self.state.date_header = false;
157    }
158
159    pub(crate) fn into_inner(self) -> (I, Bytes) {
160        self.io.into_inner()
161    }
162
163    pub(crate) fn pending_upgrade(&mut self) -> Option<crate::upgrade::Pending> {
164        self.state.upgrade.take()
165    }
166
167    pub(crate) fn is_read_closed(&self) -> bool {
168        self.state.is_read_closed()
169    }
170
171    pub(crate) fn is_write_closed(&self) -> bool {
172        self.state.is_write_closed()
173    }
174
175    pub(crate) fn can_read_head(&self) -> bool {
176        if !matches!(self.state.reading, Reading::Init) {
177            return false;
178        }
179
180        if T::should_read_first() {
181            return true;
182        }
183
184        !matches!(self.state.writing, Writing::Init)
185    }
186
187    pub(crate) fn can_read_body(&self) -> bool {
188        matches!(
189            self.state.reading,
190            Reading::Body(..) | Reading::Continue(..)
191        )
192    }
193
194    #[cfg(feature = "server")]
195    pub(crate) fn has_initial_read_write_state(&self) -> bool {
196        matches!(self.state.reading, Reading::Init)
197            && matches!(self.state.writing, Writing::Init)
198            && self.io.read_buf().is_empty()
199    }
200
201    fn should_error_on_eof(&self) -> bool {
202        // If we're idle, it's probably just the connection closing gracefully.
203        T::should_error_on_parse_eof() && !self.state.is_idle()
204    }
205
206    fn has_h2_prefix(&self) -> bool {
207        let read_buf = self.io.read_buf();
208        read_buf.len() >= 24 && read_buf[..24] == *H2_PREFACE
209    }
210
211    pub(super) fn poll_read_head(
212        &mut self,
213        cx: &mut Context<'_>,
214    ) -> Poll<Option<crate::Result<(MessageHead<T::Incoming>, DecodedLength, Wants)>>> {
215        debug_assert!(self.can_read_head());
216        trace!("Conn::read_head");
217
218        #[cfg(feature = "server")]
219        if !self.state.h1_header_read_timeout_running {
220            if let Some(h1_header_read_timeout) = self.state.h1_header_read_timeout {
221                let deadline = self.state.timer.now() + h1_header_read_timeout;
222                self.state.h1_header_read_timeout_running = true;
223                match &mut self.state.h1_header_read_timeout_fut {
224                    Some(h1_header_read_timeout_fut) => {
225                        trace!("resetting h1 header read timeout timer");
226                        self.state.timer.reset(h1_header_read_timeout_fut, deadline);
227                    }
228                    None => {
229                        trace!("setting h1 header read timeout timer");
230                        self.state.h1_header_read_timeout_fut =
231                            Some(self.state.timer.sleep_until(deadline));
232                    }
233                }
234            }
235        }
236
237        let msg = match self.io.parse::<T>(
238            cx,
239            ParseContext {
240                cached_headers: &mut self.state.cached_headers,
241                req_method: &mut self.state.method,
242                h1_parser_config: self.state.h1_parser_config.clone(),
243                h1_max_headers: self.state.h1_max_headers,
244                preserve_header_case: self.state.preserve_header_case,
245                #[cfg(feature = "ffi")]
246                preserve_header_order: self.state.preserve_header_order,
247                h09_responses: self.state.h09_responses,
248                #[cfg(feature = "client")]
249                on_informational: &mut self.state.on_informational,
250            },
251        ) {
252            Poll::Ready(Ok(msg)) => msg,
253            Poll::Ready(Err(e)) => return self.on_read_head_error(e),
254            Poll::Pending => {
255                #[cfg(feature = "server")]
256                if self.state.h1_header_read_timeout_running {
257                    if let Some(h1_header_read_timeout_fut) =
258                        &mut self.state.h1_header_read_timeout_fut
259                    {
260                        if Pin::new(h1_header_read_timeout_fut).poll(cx).is_ready() {
261                            self.state.h1_header_read_timeout_running = false;
262
263                            warn!("read header from client timeout");
264                            return Poll::Ready(Some(Err(crate::Error::new_header_timeout())));
265                        }
266                    }
267                }
268
269                return Poll::Pending;
270            }
271        };
272
273        #[cfg(feature = "server")]
274        {
275            self.state.h1_header_read_timeout_running = false;
276            self.state.h1_header_read_timeout_fut = None;
277        }
278
279        // Note: don't deconstruct `msg` into local variables, it appears
280        // the optimizer doesn't remove the extra copies.
281
282        debug!("incoming body is {}", msg.decode);
283
284        // Prevent accepting HTTP/0.9 responses after the initial one, if any.
285        self.state.h09_responses = false;
286
287        // Drop any OnInformational callbacks, we're done there!
288        #[cfg(feature = "client")]
289        {
290            self.state.on_informational = None;
291        }
292
293        self.state.busy();
294        self.state.keep_alive &= msg.keep_alive;
295        self.state.version = msg.head.version;
296
297        let mut wants = if msg.wants_upgrade {
298            Wants::UPGRADE
299        } else {
300            Wants::EMPTY
301        };
302
303        if msg.decode == DecodedLength::ZERO {
304            if msg.expect_continue {
305                debug!("ignoring expect-continue since body is empty");
306            }
307            self.state.reading = Reading::KeepAlive;
308            if !T::should_read_first() {
309                self.try_keep_alive(cx);
310            }
311        } else if msg.expect_continue && msg.head.version.gt(&Version::HTTP_10) {
312            let h1_max_header_size = None; // TODO: remove this when we land h1_max_header_size support
313            self.state.reading = Reading::Continue(Decoder::new(
314                msg.decode,
315                self.state.h1_max_headers,
316                h1_max_header_size,
317            ));
318            wants = wants.add(Wants::EXPECT);
319        } else {
320            let h1_max_header_size = None; // TODO: remove this when we land h1_max_header_size support
321            self.state.reading = Reading::Body(Decoder::new(
322                msg.decode,
323                self.state.h1_max_headers,
324                h1_max_header_size,
325            ));
326        }
327
328        self.state.allow_trailer_fields = headers::te_is_trailers(&msg.head.headers);
329
330        Poll::Ready(Some(Ok((msg.head, msg.decode, wants))))
331    }
332
333    fn on_read_head_error<Z>(&mut self, e: crate::Error) -> Poll<Option<crate::Result<Z>>> {
334        // If we are currently waiting on a message, then an empty
335        // message should be reported as an error. If not, it is just
336        // the connection closing gracefully.
337        let must_error = self.should_error_on_eof();
338        self.close_read();
339        self.io.consume_leading_lines();
340        let was_mid_parse = e.is_parse() || !self.io.read_buf().is_empty();
341        if was_mid_parse || must_error {
342            // We check if the buf contains the h2 Preface
343            debug!(
344                "parse error ({}) with {} bytes",
345                e,
346                self.io.read_buf().len()
347            );
348            match self.on_parse_error(e) {
349                Ok(()) => Poll::Pending, // XXX: wat?
350                Err(e) => Poll::Ready(Some(Err(e))),
351            }
352        } else {
353            debug!("read eof");
354            self.close_write();
355            Poll::Ready(None)
356        }
357    }
358
359    pub(crate) fn poll_read_body(
360        &mut self,
361        cx: &mut Context<'_>,
362    ) -> Poll<Option<io::Result<Frame<Bytes>>>> {
363        debug_assert!(self.can_read_body());
364
365        let (reading, ret) = match &mut self.state.reading {
366            Reading::Body(decoder) => {
367                match ready!(decoder.decode(cx, &mut self.io)) {
368                    Ok(frame) => {
369                        if frame.is_data() {
370                            let slice = frame.data_ref().unwrap_or_else(|| unreachable!());
371                            let (reading, maybe_frame) = if decoder.is_eof() {
372                                debug!("incoming body completed");
373                                (
374                                    Reading::KeepAlive,
375                                    if !slice.is_empty() {
376                                        Some(Ok(frame))
377                                    } else {
378                                        None
379                                    },
380                                )
381                            } else if slice.is_empty() {
382                                error!("incoming body unexpectedly ended");
383                                // This should be unreachable, since all 3 decoders
384                                // either set eof=true or return an Err when reading
385                                // an empty slice...
386                                (Reading::Closed, None)
387                            } else {
388                                return Poll::Ready(Some(Ok(frame)));
389                            };
390                            (reading, Poll::Ready(maybe_frame))
391                        } else if frame.is_trailers() {
392                            debug!("incoming body completed with trailers");
393                            (Reading::KeepAlive, Poll::Ready(Some(Ok(frame))))
394                        } else {
395                            trace!("discarding unknown frame");
396                            (Reading::Closed, Poll::Ready(None))
397                        }
398                    }
399                    Err(e) => {
400                        debug!("incoming body decode error: {}", e);
401                        (Reading::Closed, Poll::Ready(Some(Err(e))))
402                    }
403                }
404            }
405            Reading::Continue(decoder) => {
406                // Write the 100 Continue if not already responded...
407                if let Writing::Init = self.state.writing {
408                    trace!("automatically sending 100 Continue");
409                    let cont = b"HTTP/1.1 100 Continue\r\n\r\n";
410                    self.io.headers_buf().extend_from_slice(cont);
411                }
412
413                // And now recurse once in the Reading::Body state...
414                self.state.reading = Reading::Body(decoder.clone());
415                return self.poll_read_body(cx);
416            }
417            _ => unreachable!("poll_read_body invalid state: {:?}", self.state.reading),
418        };
419
420        self.state.reading = reading;
421        self.try_keep_alive(cx);
422        ret
423    }
424
425    pub(crate) fn wants_read_again(&mut self) -> bool {
426        let ret = self.state.notify_read;
427        self.state.notify_read = false;
428        ret
429    }
430
431    pub(crate) fn poll_read_keep_alive(&mut self, cx: &mut Context<'_>) -> Poll<crate::Result<()>> {
432        debug_assert!(!self.can_read_head() && !self.can_read_body());
433
434        if self.is_read_closed() {
435            Poll::Pending
436        } else if self.is_mid_message() {
437            self.mid_message_detect_eof(cx)
438        } else {
439            self.require_empty_read(cx)
440        }
441    }
442
443    fn is_mid_message(&self) -> bool {
444        !matches!(
445            (&self.state.reading, &self.state.writing),
446            (&Reading::Init, &Writing::Init)
447        )
448    }
449
450    // This will check to make sure the io object read is empty.
451    //
452    // This should only be called for Clients wanting to enter the idle
453    // state.
454    fn require_empty_read(&mut self, cx: &mut Context<'_>) -> Poll<crate::Result<()>> {
455        debug_assert!(!self.can_read_head() && !self.can_read_body() && !self.is_read_closed());
456        debug_assert!(!self.is_mid_message());
457        debug_assert!(T::is_client());
458
459        if !self.io.read_buf().is_empty() {
460            debug!("received an unexpected {} bytes", self.io.read_buf().len());
461            return Poll::Ready(Err(crate::Error::new_unexpected_message()));
462        }
463
464        let num_read = ready!(self.force_io_read(cx)).map_err(crate::Error::new_io)?;
465
466        if num_read == 0 {
467            let ret = if self.should_error_on_eof() {
468                trace!("found unexpected EOF on busy connection: {:?}", self.state);
469                Poll::Ready(Err(crate::Error::new_incomplete()))
470            } else {
471                trace!("found EOF on idle connection, closing");
472                Poll::Ready(Ok(()))
473            };
474
475            // order is important: should_error needs state BEFORE close_read
476            self.state.close_read();
477            return ret;
478        }
479
480        debug!(
481            "received unexpected {} bytes on an idle connection",
482            num_read
483        );
484        Poll::Ready(Err(crate::Error::new_unexpected_message()))
485    }
486
487    fn mid_message_detect_eof(&mut self, cx: &mut Context<'_>) -> Poll<crate::Result<()>> {
488        debug_assert!(!self.can_read_head() && !self.can_read_body() && !self.is_read_closed());
489        debug_assert!(self.is_mid_message());
490
491        if self.state.allow_half_close || !self.io.read_buf().is_empty() {
492            return Poll::Pending;
493        }
494
495        let num_read = ready!(self.force_io_read(cx)).map_err(crate::Error::new_io)?;
496
497        if num_read == 0 {
498            trace!("found unexpected EOF on busy connection: {:?}", self.state);
499            self.state.close_read();
500            Poll::Ready(Err(crate::Error::new_incomplete()))
501        } else {
502            Poll::Ready(Ok(()))
503        }
504    }
505
506    fn force_io_read(&mut self, cx: &mut Context<'_>) -> Poll<io::Result<usize>> {
507        debug_assert!(!self.state.is_read_closed());
508
509        let result = ready!(self.io.poll_read_from_io(cx));
510        Poll::Ready(result.map_err(|e| {
511            trace!(error = %e, "force_io_read; io error");
512            self.state.close();
513            e
514        }))
515    }
516
517    fn maybe_notify(&mut self, cx: &mut Context<'_>) {
518        // its possible that we returned NotReady from poll() without having
519        // exhausted the underlying Io. We would have done this when we
520        // determined we couldn't keep reading until we knew how writing
521        // would finish.
522
523        match self.state.reading {
524            Reading::Continue(..) | Reading::Body(..) | Reading::KeepAlive | Reading::Closed => {
525                return
526            }
527            Reading::Init => (),
528        }
529
530        match self.state.writing {
531            Writing::Body(..) => return,
532            Writing::Init | Writing::KeepAlive | Writing::Closed => (),
533        }
534
535        if !self.io.is_read_blocked() {
536            if self.io.read_buf().is_empty() {
537                match self.io.poll_read_from_io(cx) {
538                    Poll::Ready(Ok(n)) => {
539                        if n == 0 {
540                            trace!("maybe_notify; read eof");
541                            if self.state.is_idle() {
542                                self.state.close();
543                            } else {
544                                self.close_read();
545                            }
546                            return;
547                        }
548                    }
549                    Poll::Pending => {
550                        trace!("maybe_notify; read_from_io blocked");
551                        return;
552                    }
553                    Poll::Ready(Err(e)) => {
554                        trace!("maybe_notify; read_from_io error: {}", e);
555                        self.state.close();
556                        self.state.error = Some(crate::Error::new_io(e));
557                    }
558                }
559            }
560            self.state.notify_read = true;
561        }
562    }
563
564    fn try_keep_alive(&mut self, cx: &mut Context<'_>) {
565        self.state.try_keep_alive::<T>();
566        self.maybe_notify(cx);
567    }
568
569    pub(crate) fn can_write_head(&self) -> bool {
570        if !T::should_read_first() && matches!(self.state.reading, Reading::Closed) {
571            return false;
572        }
573
574        match self.state.writing {
575            Writing::Init => self.io.can_headers_buf(),
576            _ => false,
577        }
578    }
579
580    pub(crate) fn can_write_body(&self) -> bool {
581        match self.state.writing {
582            Writing::Body(..) => true,
583            Writing::Init | Writing::KeepAlive | Writing::Closed => false,
584        }
585    }
586
587    pub(crate) fn can_buffer_body(&self) -> bool {
588        self.io.can_buffer()
589    }
590
591    /// Whether bytes are sitting in the write buffer waiting to be flushed.
592    pub(crate) fn has_buffered_write(&self) -> bool {
593        self.io.has_buffered_write()
594    }
595
596    pub(crate) fn write_head(&mut self, head: MessageHead<T::Outgoing>, body: Option<BodyLength>) {
597        if let Some(encoder) = self.encode_head(head, body) {
598            self.state.writing = if !encoder.is_eof() {
599                Writing::Body(encoder)
600            } else if encoder.is_last() {
601                Writing::Closed
602            } else {
603                Writing::KeepAlive
604            };
605        }
606    }
607
608    fn encode_head(
609        &mut self,
610        mut head: MessageHead<T::Outgoing>,
611        body: Option<BodyLength>,
612    ) -> Option<Encoder> {
613        debug_assert!(self.can_write_head());
614
615        if !T::should_read_first() {
616            self.state.busy();
617            // A client request carrying `Connection: close` must not be pooled or
618            // reused. hyper otherwise derives connection reuse from the response
619            // alone, so a backend that ignores the request-side close (omits
620            // `Connection: close` in its response) would leave the connection in
621            // the pool. Disable keep-alive up front so the connection is evicted
622            // regardless of the response.
623            if headers::connection_any_close(&head.headers) {
624                self.state.disable_keep_alive();
625            }
626        }
627
628        self.enforce_version(&mut head);
629
630        let buf = self.io.headers_buf();
631        match super::role::encode_headers::<T>(
632            Encode {
633                head: &mut head,
634                body,
635                #[cfg(feature = "server")]
636                keep_alive: self.state.wants_keep_alive(),
637                req_method: &mut self.state.method,
638                title_case_headers: self.state.title_case_headers,
639                #[cfg(feature = "server")]
640                date_header: self.state.date_header,
641            },
642            buf,
643        ) {
644            Ok(encoder) => {
645                debug_assert!(self.state.cached_headers.is_none());
646                debug_assert!(head.headers.is_empty());
647                self.state.cached_headers = Some(head.headers);
648
649                #[cfg(feature = "client")]
650                {
651                    self.state.on_informational =
652                        head.extensions.remove::<crate::ext::OnInformational>();
653                }
654
655                Some(encoder)
656            }
657            Err(err) => {
658                self.state.error = Some(err);
659                self.state.writing = Writing::Closed;
660                None
661            }
662        }
663    }
664
665    // Fix keep-alive when Connection: keep-alive header is not present
666    fn fix_keep_alive(&mut self, head: &mut MessageHead<T::Outgoing>) {
667        let outgoing_is_keep_alive = head
668            .headers
669            .get(CONNECTION)
670            .map_or(false, headers::connection_keep_alive);
671
672        if !outgoing_is_keep_alive {
673            match head.version {
674                // If response is version 1.0 and keep-alive is not present in the response,
675                // disable keep-alive so the server closes the connection
676                Version::HTTP_10 => self.state.disable_keep_alive(),
677                // If response is version 1.1 and keep-alive is wanted, add
678                // Connection: keep-alive header when not present
679                Version::HTTP_11 => {
680                    if self.state.wants_keep_alive() {
681                        head.headers
682                            .insert(CONNECTION, HeaderValue::from_static("keep-alive"));
683                    }
684                }
685                _ => (),
686            }
687        }
688    }
689
690    // If we know the remote speaks an older version, we try to fix up any messages
691    // to work with our older peer.
692    fn enforce_version(&mut self, head: &mut MessageHead<T::Outgoing>) {
693        match self.state.version {
694            Version::HTTP_10 => {
695                // Fixes response or connection when keep-alive header is not present
696                self.fix_keep_alive(head);
697                // If the remote only knows HTTP/1.0, we should force ourselves
698                // to do only speak HTTP/1.0 as well.
699                head.version = Version::HTTP_10;
700            }
701            Version::HTTP_11 => {
702                if let KA::Disabled = self.state.keep_alive.status() {
703                    head.headers
704                        .insert(CONNECTION, HeaderValue::from_static("close"));
705                }
706            }
707            _ => (),
708        }
709        // If the remote speaks HTTP/1.1, then it *should* be fine with
710        // both HTTP/1.0 and HTTP/1.1 from us. So again, we just let
711        // the user's headers be.
712    }
713
714    pub(crate) fn write_body(&mut self, chunk: B) {
715        debug_assert!(self.can_write_body() && self.can_buffer_body());
716        // empty chunks should be discarded at Dispatcher level
717        debug_assert!(chunk.remaining() != 0);
718
719        let state = match &mut self.state.writing {
720            Writing::Body(encoder) => {
721                self.io.buffer(encoder.encode(chunk));
722
723                if !encoder.is_eof() {
724                    return;
725                }
726
727                if encoder.is_last() {
728                    Writing::Closed
729                } else {
730                    Writing::KeepAlive
731                }
732            }
733            _ => unreachable!("write_body invalid state: {:?}", self.state.writing),
734        };
735
736        self.state.writing = state;
737    }
738
739    pub(crate) fn write_trailers(&mut self, trailers: HeaderMap) {
740        if T::is_server() && !self.state.allow_trailer_fields {
741            debug!("trailers not allowed to be sent");
742            return;
743        }
744        debug_assert!(self.can_write_body() && self.can_buffer_body());
745
746        match &mut self.state.writing {
747            Writing::Body(encoder) => {
748                if let Some(enc_buf) =
749                    encoder.encode_trailers(trailers, self.state.title_case_headers)
750                {
751                    self.io.buffer(enc_buf);
752
753                    self.state.writing = if encoder.is_last() || encoder.is_close_delimited() {
754                        Writing::Closed
755                    } else {
756                        Writing::KeepAlive
757                    };
758                }
759            }
760            _ => unreachable!("write_trailers invalid state: {:?}", self.state.writing),
761        }
762    }
763
764    pub(crate) fn write_body_and_end(&mut self, chunk: B) {
765        debug_assert!(self.can_write_body() && self.can_buffer_body());
766        // empty chunks should be discarded at Dispatcher level
767        debug_assert!(chunk.remaining() != 0);
768
769        let state = match &mut self.state.writing {
770            Writing::Body(encoder) => {
771                let can_keep_alive = encoder.encode_and_end(chunk, self.io.write_buf());
772                if can_keep_alive {
773                    Writing::KeepAlive
774                } else {
775                    Writing::Closed
776                }
777            }
778            _ => unreachable!("write_body invalid state: {:?}", self.state.writing),
779        };
780
781        self.state.writing = state;
782    }
783
784    pub(crate) fn end_body(&mut self) -> crate::Result<()> {
785        debug_assert!(self.can_write_body());
786
787        let encoder = match &mut self.state.writing {
788            Writing::Body(enc) => enc,
789            _ => return Ok(()),
790        };
791
792        // end of stream, that means we should try to eof
793        match encoder.end() {
794            Ok(end) => {
795                if let Some(end) = end {
796                    self.io.buffer(end);
797                }
798
799                self.state.writing = if encoder.is_last() || encoder.is_close_delimited() {
800                    Writing::Closed
801                } else {
802                    Writing::KeepAlive
803                };
804
805                Ok(())
806            }
807            Err(not_eof) => {
808                self.state.writing = Writing::Closed;
809                Err(crate::Error::new_body_write_aborted().with(not_eof))
810            }
811        }
812    }
813
814    // When we get a parse error, depending on what side we are, we might be able
815    // to write a response before closing the connection.
816    //
817    // - Client: there is nothing we can do
818    // - Server: if Response hasn't been written yet, we can send a 4xx response
819    fn on_parse_error(&mut self, err: crate::Error) -> crate::Result<()> {
820        if let Writing::Init = self.state.writing {
821            if self.has_h2_prefix() {
822                return Err(crate::Error::new_version_h2());
823            }
824            if let Some(msg) = T::on_error(&err) {
825                // Drop the cached headers so as to not trigger a debug
826                // assert in `write_head`...
827                self.state.cached_headers.take();
828                self.write_head(msg, None);
829                self.state.error = Some(err);
830                return Ok(());
831            }
832        }
833
834        // fallback is pass the error back up
835        Err(err)
836    }
837
838    pub(crate) fn poll_flush(&mut self, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
839        ready!(Pin::new(&mut self.io).poll_flush(cx))?;
840        self.try_keep_alive(cx);
841        trace!("flushed({}): {:?}", T::LOG, self.state);
842        Poll::Ready(Ok(()))
843    }
844
845    pub(crate) fn poll_shutdown(&mut self, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
846        match ready!(self.io.poll_shutdown(cx)) {
847            Ok(()) => {
848                trace!("shut down IO complete");
849                Poll::Ready(Ok(()))
850            }
851            Err(e) => {
852                debug!("error shutting down IO: {}", e);
853                Poll::Ready(Err(e))
854            }
855        }
856    }
857
858    /// If the read side can be cheaply drained, do so. Otherwise, close.
859    pub(super) fn poll_drain_or_close_read(&mut self, cx: &mut Context<'_>) {
860        if let Reading::Continue(decoder) = &mut self.state.reading {
861            // skip sending the 100-continue
862            // just move forward to a read, in case a tiny body was included
863            self.state.reading = Reading::Body(decoder.clone());
864        }
865
866        let _ = self.poll_read_body(cx);
867
868        // If still in Reading::Body, just give up
869        match self.state.reading {
870            Reading::Init | Reading::KeepAlive => {
871                trace!("body drained")
872            }
873            _ => self.close_read(),
874        }
875    }
876
877    pub(crate) fn close_read(&mut self) {
878        self.state.close_read();
879    }
880
881    pub(crate) fn close_write(&mut self) {
882        self.state.close_write();
883    }
884
885    #[cfg(feature = "server")]
886    pub(crate) fn disable_keep_alive(&mut self) {
887        if self.state.is_idle() {
888            trace!("disable_keep_alive; closing idle connection");
889            self.state.close();
890        } else {
891            trace!("disable_keep_alive; in-progress connection");
892            self.state.disable_keep_alive();
893        }
894    }
895
896    pub(crate) fn take_error(&mut self) -> crate::Result<()> {
897        if let Some(err) = self.state.error.take() {
898            Err(err)
899        } else {
900            Ok(())
901        }
902    }
903
904    pub(super) fn on_upgrade(&mut self) -> crate::upgrade::OnUpgrade {
905        trace!("{}: prepare possible HTTP upgrade", T::LOG);
906        self.state.prepare_upgrade()
907    }
908}
909
910impl<I, B: Buf, T> fmt::Debug for Conn<I, B, T> {
911    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
912        f.debug_struct("Conn")
913            .field("state", &self.state)
914            .field("io", &self.io)
915            .finish()
916    }
917}
918
919// B and T are never pinned
920impl<I: Unpin, B, T> Unpin for Conn<I, B, T> {}
921
922struct State {
923    allow_half_close: bool,
924    /// Re-usable `HeaderMap` to reduce allocating new ones.
925    cached_headers: Option<HeaderMap>,
926    /// If an error occurs when there wasn't a direct way to return it
927    /// back to the user, this is set.
928    error: Option<crate::Error>,
929    /// Current keep-alive status.
930    keep_alive: KA,
931    /// If mid-message, the HTTP Method that started it.
932    ///
933    /// This is used to know things such as if the message can include
934    /// a body or not.
935    method: Option<Method>,
936    h1_parser_config: ParserConfig,
937    h1_max_headers: Option<usize>,
938    #[cfg(feature = "server")]
939    h1_header_read_timeout: Option<Duration>,
940    #[cfg(feature = "server")]
941    h1_header_read_timeout_fut: Option<Pin<Box<dyn Sleep>>>,
942    #[cfg(feature = "server")]
943    h1_header_read_timeout_running: bool,
944    #[cfg(feature = "server")]
945    date_header: bool,
946    #[cfg(feature = "server")]
947    timer: Time,
948    preserve_header_case: bool,
949    #[cfg(feature = "ffi")]
950    preserve_header_order: bool,
951    title_case_headers: bool,
952    h09_responses: bool,
953    /// If set, called with each 1xx informational response received for
954    /// the current request. MUST be unset after a non-1xx response is
955    /// received.
956    #[cfg(feature = "client")]
957    on_informational: Option<crate::ext::OnInformational>,
958    /// Set to true when the Dispatcher should poll read operations
959    /// again. See the `maybe_notify` method for more.
960    notify_read: bool,
961    /// State of allowed reads.
962    reading: Reading,
963    /// State of allowed writes.
964    writing: Writing,
965    /// An expected pending HTTP upgrade.
966    upgrade: Option<crate::upgrade::Pending>,
967    /// Either HTTP/1.0 or 1.1 connection.
968    version: Version,
969    /// Flag to track if trailer fields are allowed to be sent.
970    allow_trailer_fields: bool,
971}
972
973#[derive(Debug)]
974enum Reading {
975    Init,
976    Continue(Decoder),
977    Body(Decoder),
978    KeepAlive,
979    Closed,
980}
981
982enum Writing {
983    Init,
984    Body(Encoder),
985    KeepAlive,
986    Closed,
987}
988
989impl fmt::Debug for State {
990    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
991        let mut builder = f.debug_struct("State");
992        builder
993            .field("reading", &self.reading)
994            .field("writing", &self.writing)
995            .field("keep_alive", &self.keep_alive);
996
997        // Only show error field if it's interesting...
998        if let Some(error) = &self.error {
999            builder.field("error", error);
1000        }
1001
1002        if self.allow_half_close {
1003            builder.field("allow_half_close", &true);
1004        }
1005
1006        // Purposefully leaving off other fields..
1007
1008        builder.finish()
1009    }
1010}
1011
1012impl fmt::Debug for Writing {
1013    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1014        match self {
1015            Writing::Init => f.write_str("Init"),
1016            Writing::Body(enc) => f.debug_tuple("Body").field(enc).finish(),
1017            Writing::KeepAlive => f.write_str("KeepAlive"),
1018            Writing::Closed => f.write_str("Closed"),
1019        }
1020    }
1021}
1022
1023impl std::ops::BitAndAssign<bool> for KA {
1024    fn bitand_assign(&mut self, enabled: bool) {
1025        if !enabled {
1026            trace!("remote disabling keep-alive");
1027            *self = KA::Disabled;
1028        }
1029    }
1030}
1031
1032#[derive(Clone, Copy, Debug, Default)]
1033enum KA {
1034    Idle,
1035    #[default]
1036    Busy,
1037    Disabled,
1038}
1039
1040impl KA {
1041    fn idle(&mut self) {
1042        *self = KA::Idle;
1043    }
1044
1045    fn busy(&mut self) {
1046        *self = KA::Busy;
1047    }
1048
1049    fn disable(&mut self) {
1050        *self = KA::Disabled;
1051    }
1052
1053    fn status(&self) -> KA {
1054        *self
1055    }
1056}
1057
1058impl State {
1059    fn close(&mut self) {
1060        trace!("State::close()");
1061        self.reading = Reading::Closed;
1062        self.writing = Writing::Closed;
1063        self.keep_alive.disable();
1064    }
1065
1066    fn close_read(&mut self) {
1067        trace!("State::close_read()");
1068        self.reading = Reading::Closed;
1069        self.keep_alive.disable();
1070    }
1071
1072    fn close_write(&mut self) {
1073        trace!("State::close_write()");
1074        self.writing = Writing::Closed;
1075        self.keep_alive.disable();
1076    }
1077
1078    fn wants_keep_alive(&self) -> bool {
1079        !matches!(self.keep_alive.status(), KA::Disabled)
1080    }
1081
1082    fn try_keep_alive<T: Http1Transaction>(&mut self) {
1083        match (&self.reading, &self.writing) {
1084            (&Reading::KeepAlive, &Writing::KeepAlive) => {
1085                if let KA::Busy = self.keep_alive.status() {
1086                    self.idle::<T>();
1087                } else {
1088                    trace!(
1089                        "try_keep_alive({}): could keep-alive, but status = {:?}",
1090                        T::LOG,
1091                        self.keep_alive
1092                    );
1093                    self.close();
1094                }
1095            }
1096            (&Reading::Closed, &Writing::KeepAlive) | (&Reading::KeepAlive, &Writing::Closed) => {
1097                self.close();
1098            }
1099            _ => (),
1100        }
1101    }
1102
1103    fn disable_keep_alive(&mut self) {
1104        self.keep_alive.disable();
1105    }
1106
1107    fn busy(&mut self) {
1108        if let KA::Disabled = self.keep_alive.status() {
1109            return;
1110        }
1111        self.keep_alive.busy();
1112    }
1113
1114    fn idle<T: Http1Transaction>(&mut self) {
1115        debug_assert!(!self.is_idle(), "State::idle() called while idle");
1116
1117        self.method = None;
1118        self.keep_alive.idle();
1119
1120        if !self.is_idle() {
1121            self.close();
1122            return;
1123        }
1124
1125        self.reading = Reading::Init;
1126        self.writing = Writing::Init;
1127
1128        // !T::should_read_first() means Client.
1129        //
1130        // If Client connection has just gone idle, the Dispatcher
1131        // should try the poll loop one more time, so as to poll the
1132        // pending requests stream.
1133        if !T::should_read_first() {
1134            self.notify_read = true;
1135        }
1136
1137        #[cfg(feature = "server")]
1138        if self.h1_header_read_timeout.is_some() {
1139            // Next read will start and poll the header read timeout,
1140            // so we can close the connection if another header isn't
1141            // received in a timely manner.
1142            self.notify_read = true;
1143        }
1144    }
1145
1146    fn is_idle(&self) -> bool {
1147        matches!(self.keep_alive.status(), KA::Idle)
1148    }
1149
1150    fn is_read_closed(&self) -> bool {
1151        matches!(self.reading, Reading::Closed)
1152    }
1153
1154    fn is_write_closed(&self) -> bool {
1155        matches!(self.writing, Writing::Closed)
1156    }
1157
1158    fn prepare_upgrade(&mut self) -> crate::upgrade::OnUpgrade {
1159        let (tx, rx) = crate::upgrade::pending();
1160        self.upgrade = Some(tx);
1161        rx
1162    }
1163}
1164
1165#[cfg(test)]
1166mod tests {
1167    #[cfg(all(feature = "nightly", not(miri)))]
1168    #[bench]
1169    fn bench_read_head_short(b: &mut ::test::Bencher) {
1170        use super::*;
1171        use crate::common::io::Compat;
1172        let s = b"GET / HTTP/1.1\r\nHost: localhost:8080\r\n\r\n";
1173        let len = s.len();
1174        b.bytes = len as u64;
1175
1176        // an empty IO, we'll be skipping and using the read buffer anyways
1177        let io = Compat(tokio_test::io::Builder::new().build());
1178        let mut conn = Conn::<_, bytes::Bytes, crate::proto::h1::ServerTransaction>::new(io);
1179        *conn.io.read_buf_mut() = ::bytes::BytesMut::from(&s[..]);
1180        conn.state.cached_headers = Some(HeaderMap::with_capacity(2));
1181
1182        let rt = tokio::runtime::Builder::new_current_thread()
1183            .enable_all()
1184            .build()
1185            .unwrap();
1186
1187        b.iter(|| {
1188            rt.block_on(futures_util::future::poll_fn(|cx| {
1189                match conn.poll_read_head(cx) {
1190                    Poll::Ready(Some(Ok(x))) => {
1191                        ::test::black_box(&x);
1192                        let mut headers = x.0.headers;
1193                        headers.clear();
1194                        conn.state.cached_headers = Some(headers);
1195                    }
1196                    f => panic!("expected Ready(Some(Ok(..))): {:?}", f),
1197                }
1198
1199                conn.io.read_buf_mut().reserve(1);
1200                unsafe {
1201                    conn.io.read_buf_mut().set_len(len);
1202                }
1203                conn.state.reading = Reading::Init;
1204                Poll::Ready(())
1205            }));
1206        });
1207    }
1208
1209    // A client request carrying `Connection: close` must evict the connection
1210    // (disable keep-alive) at request-encode time, so it is never returned to the
1211    // pool for reuse — independent of whether the backend response echoes
1212    // `Connection: close`. hyper otherwise derives reuse from the response alone.
1213    #[cfg(feature = "client")]
1214    #[test]
1215    fn client_request_connection_close_disables_keep_alive() {
1216        use super::*;
1217        use crate::common::io::Compat;
1218        use crate::proto::RequestLine;
1219
1220        // Encodes a client GET (with the given Connection header lines, one
1221        // `append` each) on a fresh client Conn and returns whether the
1222        // connection remains reusable.
1223        fn remains_reusable_after_get(connection_values: &[&'static str]) -> bool {
1224            let io = Compat(tokio_test::io::Builder::new().build());
1225            let mut conn = Conn::<_, bytes::Bytes, crate::proto::h1::ClientTransaction>::new(io);
1226            assert!(
1227                conn.state.wants_keep_alive(),
1228                "a fresh client connection should want keep-alive"
1229            );
1230
1231            let mut headers = HeaderMap::new();
1232            for value in connection_values {
1233                headers.append(CONNECTION, HeaderValue::from_static(value));
1234            }
1235            let head = MessageHead {
1236                version: Version::HTTP_11,
1237                subject: RequestLine(Method::GET, "/".parse().unwrap()),
1238                headers,
1239                extensions: http::Extensions::new(),
1240            };
1241            conn.write_head(head, None);
1242            conn.state.wants_keep_alive()
1243        }
1244
1245        // Control: a request without `Connection: close` leaves the connection reusable.
1246        assert!(
1247            remains_reusable_after_get(&[]),
1248            "a keep-alive request must leave the connection reusable"
1249        );
1250        // Fix: a `Connection: close` request must disable keep-alive so the
1251        // connection is evicted regardless of the response.
1252        assert!(
1253            !remains_reusable_after_get(&["close"]),
1254            "a `Connection: close` request must disable keep-alive (connection evicted)"
1255        );
1256        // A `close` token in a comma-separated value is honored.
1257        assert!(
1258            !remains_reusable_after_get(&["keep-alive, close"]),
1259            "a `close` token in a comma-separated Connection value must disable keep-alive"
1260        );
1261        // A `close` in ANY of multiple Connection header lines is honored
1262        // (get_all, not just the first line).
1263        assert!(
1264            !remains_reusable_after_get(&["keep-alive", "close"]),
1265            "a `close` in any Connection header line must disable keep-alive"
1266        );
1267    }
1268
1269    use super::*;
1270    use crate::common::io::Compat;
1271    #[cfg(feature = "client")]
1272    use crate::proto::h1::ClientTransaction;
1273    #[cfg(feature = "server")]
1274    use crate::proto::h1::ServerTransaction;
1275    #[cfg(feature = "server")]
1276    use crate::proto::RequestLine;
1277    use bytes::Bytes;
1278
1279    fn poll_head<I, T>(
1280        conn: &mut Conn<Compat<I>, Bytes, T>,
1281    ) -> Poll<Option<crate::Result<(MessageHead<T::Incoming>, DecodedLength, Wants)>>>
1282    where
1283        I: tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin,
1284        T: Http1Transaction + Unpin,
1285    {
1286        tokio_test::task::spawn(()).enter(|cx, _| conn.poll_read_head(cx))
1287    }
1288
1289    fn ready<T>(poll: Poll<T>) -> T {
1290        match poll {
1291            Poll::Ready(value) => value,
1292            Poll::Pending => panic!("expected ready"),
1293        }
1294    }
1295
1296    #[cfg(feature = "server")]
1297    #[test]
1298    fn conn_reads_request_head() {
1299        let io = tokio_test::io::Builder::new()
1300            .read(b"GET / HTTP/1.1\r\n\r\n")
1301            .build();
1302        let mut conn = Conn::<_, Bytes, ServerTransaction>::new(Compat::new(io));
1303
1304        let (head, body, _) = ready(poll_head(&mut conn))
1305            .expect("message")
1306            .expect("valid request");
1307        assert_eq!(head.subject, RequestLine(Method::GET, "/".parse().unwrap()));
1308        assert_eq!(body, DecodedLength::ZERO);
1309    }
1310
1311    #[cfg(feature = "server")]
1312    #[test]
1313    fn conn_reads_partial_request_head() {
1314        tokio_test::task::spawn(()).enter(|cx, _| {
1315            let (io, mut handle) = tokio_test::io::Builder::new().build_with_handle();
1316            let mut conn = Conn::<_, Bytes, ServerTransaction>::new(Compat::new(io));
1317            handle.read(b"GET / HTTP");
1318            assert!(conn.poll_read_head(cx).is_pending());
1319            handle.read(b"/1.1\r\nHost: foo.bar\r\n\r\n");
1320            assert!(conn.poll_read_head(cx).is_ready());
1321        });
1322    }
1323
1324    #[cfg(feature = "server")]
1325    #[test]
1326    fn conn_accepts_eof_when_idle() {
1327        let io = tokio_test::io::Builder::new().build();
1328        let mut conn = Conn::<_, Bytes, ServerTransaction>::new(Compat::new(io));
1329        conn.state.idle::<ServerTransaction>();
1330        assert!(matches!(poll_head(&mut conn), Poll::Ready(None)));
1331    }
1332
1333    #[cfg(feature = "server")]
1334    #[test]
1335    fn conn_rejects_eof_during_partial_head() {
1336        let io = tokio_test::io::Builder::new()
1337            .read(b"GET / HTTP/1.1")
1338            .build();
1339        let mut conn = Conn::<_, Bytes, ServerTransaction>::new(Compat::new(io));
1340        conn.state.idle::<ServerTransaction>();
1341        let err = ready(poll_head(&mut conn))
1342            .expect("error result")
1343            .expect_err("partial head must fail");
1344        assert!(err.is_incomplete_message(), "unexpected error: {err:?}");
1345    }
1346
1347    #[cfg(feature = "client")]
1348    #[test]
1349    fn client_rejects_eof_while_busy() {
1350        let io = tokio_test::io::Builder::new().build();
1351        let mut client = Conn::<_, Bytes, ClientTransaction>::new(Compat::new(io));
1352        client.state.busy();
1353        client.state.writing = Writing::KeepAlive;
1354        let err = ready(poll_head(&mut client))
1355            .expect("error result")
1356            .expect_err("client EOF must fail");
1357        assert!(err.is_incomplete_message(), "unexpected error: {err:?}");
1358    }
1359
1360    #[cfg(feature = "server")]
1361    #[test]
1362    fn server_accepts_eof_while_busy() {
1363        let io = tokio_test::io::Builder::new().build();
1364        let mut server = Conn::<_, Bytes, ServerTransaction>::new(Compat::new(io));
1365        server.state.busy();
1366        assert!(matches!(poll_head(&mut server), Poll::Ready(None)));
1367    }
1368
1369    #[cfg(feature = "client")]
1370    #[test]
1371    fn conn_reads_empty_response_before_eof() {
1372        let io = tokio_test::io::Builder::new()
1373            .read(b"HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n")
1374            .build();
1375        let mut conn = Conn::<_, Bytes, ClientTransaction>::new(Compat::new(io));
1376        conn.state.busy();
1377        conn.state.writing = Writing::KeepAlive;
1378        let (_, body, _) = ready(poll_head(&mut conn))
1379            .expect("response")
1380            .expect("valid response");
1381        assert_eq!(body, DecodedLength::ZERO);
1382    }
1383
1384    #[cfg(feature = "server")]
1385    #[test]
1386    fn conn_reads_body_and_reports_end() {
1387        let io = tokio_test::io::Builder::new()
1388            .read(b"POST / HTTP/1.1\r\nContent-Length: 5\r\n\r\n12345")
1389            .wait(std::time::Duration::from_secs(1))
1390            .build();
1391        let mut conn = Conn::<_, Bytes, ServerTransaction>::new(Compat::new(io));
1392        let (_, body, _) = ready(poll_head(&mut conn))
1393            .expect("request")
1394            .expect("valid request");
1395        assert_eq!(body, DecodedLength::new(5));
1396
1397        tokio_test::task::spawn(()).enter(|cx, _| {
1398            let frame = conn.poll_read_body(cx);
1399            let data = ready(frame)
1400                .expect("body frame")
1401                .expect("valid body")
1402                .into_data()
1403                .expect("data frame");
1404            assert_eq!(data, "12345");
1405            assert!(
1406                !conn.can_read_body(),
1407                "the complete body must return to head-reading state"
1408            );
1409        });
1410    }
1411
1412    #[cfg(feature = "server")]
1413    #[test]
1414    fn closed_conn_cannot_read_or_write() {
1415        let io = tokio_test::io::Builder::new().build();
1416        let mut conn = Conn::<_, Bytes, ServerTransaction>::new(Compat::new(io));
1417        conn.state.close();
1418        assert!(conn.is_read_closed());
1419        assert!(conn.is_write_closed());
1420        assert!(!conn.can_read_head());
1421        assert!(!conn.can_write_head());
1422    }
1423
1424    #[cfg(feature = "server")]
1425    #[test]
1426    fn conn_writes_chunked_body() {
1427        let io = tokio_test::io::Builder::new()
1428            .write(b"7\r\nheaders\r\n0\r\n\r\n")
1429            .build();
1430        let mut conn = Conn::<_, Bytes, ServerTransaction>::new(Compat::new(io));
1431        conn.state.writing = Writing::Body(Encoder::chunked());
1432        conn.write_body(Bytes::from_static(b"headers"));
1433        conn.end_body().unwrap();
1434        tokio_test::task::spawn(()).enter(|cx, _| {
1435            assert!(conn.poll_flush(cx).is_ready());
1436        });
1437    }
1438}