Quellcode-Bibliothek incoming.rs
Interaktion und PortierbarkeitRust
use std::fmt; #[cfg(all(feature = "http1", any(feature = "client", feature = "server")))] use std::future::Future; use std::pin::Pin; use std::task::{Context, Poll};
use bytes::Bytes; #[cfg(all(feature = "http1", any(feature = "client", feature = "server")))] use futures_channel::{mpsc, oneshot}; #[cfg(all(
any(feature = "http1", feature = "http2"),
any(feature = "client", feature = "server")
))] use futures_core::ready; #[cfg(all(feature = "http1", any(feature = "client", feature = "server")))] use futures_core::{stream::FusedStream, Stream}; // for mpsc::Receiver #[cfg(all(feature = "http1", any(feature = "client", feature = "server")))] use http::HeaderMap; use http_body::{Body, Frame, SizeHint};
/// A stream of `Bytes`, used when receiving bodies from the network. /// /// Note that Users should not instantiate this struct directly. When working with the hyper client, /// `Incoming` is returned to you in responses. Similarly, when operating with the hyper server, /// it is provided within requests. /// /// # Examples /// /// ```rust,ignore /// async fn echo( /// req: Request<hyper::body::Incoming>, /// ) -> Result<Response<BoxBody<Bytes, hyper::Error>>, hyper::Error> { /// //Here, you can process `Incoming` /// } /// ``` #[must_use = "streams do nothing unless polled"] pubstruct Incoming {
kind: Kind,
}
/// A sender half created through [`Body::channel()`]. /// /// Useful when wanting to stream chunks from another thread. /// /// ## Body Closing /// /// Note that the request body will always be closed normally when the sender is dropped (meaning /// that the empty terminating chunk will be sent to the remote). If you desire to close the /// connection with an incomplete response (e.g. in the case of an error during asynchronous /// processing), call the [`Sender::abort()`] method to abort the body in an abnormal fashion. /// /// [`Body::channel()`]: struct.Body.html#method.channel /// [`Sender::abort()`]: struct.Sender.html#method.abort #[must_use = "Sender does nothing unless sent on"] #[cfg(all(feature = "http1", any(feature = "client", feature = "server")))] pub(crate) struct Sender {
want_rx: watch::Receiver,
data_tx: BodySender,
trailers_tx: Option<TrailersSender>,
}
// If wanter is true, `Sender::poll_ready()` won't becoming ready // until the `Body` has been polled for data once. let want = if wanter { WANT_PENDING } else { WANT_READY };
let (want_tx, want_rx) = watch::channel(want);
let tx = Sender {
want_rx,
data_tx,
trailers_tx: Some(trailers_tx),
}; let rx = Incoming::new(Kind::Chan {
content_length,
want_tx,
data_rx,
trailers_rx,
});
if !data_rx.is_terminated() { iflet Some(chunk) = ready!(Pin::new(data_rx).poll_next(cx)?) {
len.sub_if(chunk.len() as u64); return Poll::Ready(Some(Ok(Frame::data(chunk))));
}
}
// check trailers after data is terminated match ready!(Pin::new(trailers_rx).poll(cx)) {
Ok(t) => Poll::Ready(Some(Ok(Frame::trailers(t)))),
Err(_) => Poll::Ready(None),
}
} #[cfg(all(feature = "http2", any(feature = "client", feature = "server")))]
Kind::H2 { refmut data_done, ref ping,
recv: refmut h2,
content_length: refmut len,
} => { if !*data_done { match ready!(h2.poll_data(cx)) {
Some(Ok(bytes)) => { let _ = h2.flow_control().release_capacity(bytes.len());
len.sub_if(bytes.len() as u64);
ping.record_data(bytes.len()); return Poll::Ready(Some(Ok(Frame::data(bytes))));
}
Some(Err(e)) => { returnmatch e.reason() { // These reasons should cause the body reading to stop, but not fail it. // The same logic as for `Read for H2Upgraded` is applied here.
Some(h2::Reason::NO_ERROR) | Some(h2::Reason::CANCEL) => {
Poll::Ready(None)
}
_ => Poll::Ready(Some(Err(crate::Error::new_body(e)))),
};
}
None => {
*data_done = true; // fall through to trailers
}
}
}
// after data, check trailers match ready!(h2.poll_trailers(cx)) {
Ok(t) => {
ping.record_non_data();
Poll::Ready(Ok(t.map(Frame::trailers)).transpose())
}
Err(e) => Poll::Ready(Some(Err(crate::Error::new_h2(e)))),
}
}
#[cfg(all(feature = "http1", any(feature = "client", feature = "server")))] impl Sender { /// Check to see if this `Sender` can send more data. pub(crate) fn poll_ready(&mutself, cx: &mut Context<'_>) -> Poll<crate::Result<()>> { // Check if the receiver end has tried polling for the body yet
ready!(self.poll_want(cx)?); self.data_tx
.poll_ready(cx)
.map_err(|_| crate::Error::new_closed())
}
/// Send data on data channel when it is ready. #[cfg(test)] #[allow(unused)] pub(crate) async fn send_data(&mutself, chunk: Bytes) -> crate::Result<()> { self.ready().await?; self.data_tx
.try_send(Ok(chunk))
.map_err(|_| crate::Error::new_closed())
}
/// Try to send data on this channel. /// /// # Errors /// /// Returns `Err(Bytes)` if the channel could not (currently) accept /// another `Bytes`. /// /// # Note /// /// This is mostly useful for when trying to send from some other thread /// that doesn't have an async context. If in an async context, prefer /// `send_data()` instead. #[cfg(feature = "http1")] pub(crate) fn try_send_data(&mutself, chunk: Bytes) -> Result<(), Bytes> { self.data_tx
.try_send(Ok(chunk))
.map_err(|err| err.into_inner().expect("just sent Ok"))
}
pub(crate) fn send_error(&mutself, err: crate::Error) { let _ = self
.data_tx // clone so the send works even if buffer is full
.clone()
.try_send(Err(err));
}
}
#[cfg(all(feature = "http1", any(feature = "client", feature = "server")))] #[test]
fn test_size_of() { // These are mostly to help catch *accidentally* increasing // the size by too much.
match tx_ready.poll() {
Poll::Ready(Err(ref e)) if e.is_closed() => (),
unexpected => panic!("tx poll ready unexpected: {:?}", unexpected),
}
}
}
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.24Bemerkung:
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-10-12)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.