Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ members = ["monoio-http", "monoio-http-client"]
resolver = "2"

[workspace.dependencies]
monoio = "0.2.3"
monoio = "0.2.4"
monoio-compat = "0.2.0"
service-async = "0.2.0"
monoio-rustls = "0.3.0"
Expand Down
50 changes: 21 additions & 29 deletions monoio-http-client/examples/h2_client.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
use std::time::Duration;

use http::{request::Builder, Method, Version};
use monoio::time::sleep;
use monoio_http::common::body::{Body, FixedBody, HttpBody};
use tracing_subscriber::FmtSubscriber;

Expand All @@ -14,35 +11,30 @@ async fn main() {
tracing::subscriber::set_global_default(subscriber)
.expect("Failed to set up the tracing subscriber");

let h2_client = monoio_http_client::Builder::new().http2_client().build();
let mut first = true;
let h2_client = monoio_http_client::Builder::new()
.http2_client()
.build();

for _ in 0..6 {
if first {
sleep(Duration::from_millis(1000)).await;
first = false;
}
let body = HttpBody::fixed_body(None);
let body = HttpBody::fixed_body(None);

let request = Builder::new()
.method(Method::GET)
// HTTP Upgrade not supported, requires
// a HTTP2 server
.uri("http://127.0.0.1:8080/")
.version(Version::HTTP_2)
.body(body)
.unwrap();
let request = Builder::new()
.method(Method::GET)
.uri("https://httpbin.org/get")
.version(Version::HTTP_2)
.header(http::header::USER_AGENT, "monoio-http")
.header(http::header::ACCEPT, "*/*")
.body(body)
.unwrap();

tracing::debug!("starting request");
tracing::debug!("starting request");

let resp = h2_client
.send_request(request)
.await
.expect("Sending request");
let (parts, mut body) = resp.into_parts();
println!("{:?}", parts);
while let Some(Ok(data)) = body.next_data().await {
println!("{:?}", data);
}
let resp = h2_client
.send_request(request)
.await
.expect("Sending request");
let (parts, mut body) = resp.into_parts();
println!("{:?}", parts);
while let Some(Ok(data)) = body.next_data().await {
println!("{:?}", data);
}
}
49 changes: 37 additions & 12 deletions monoio-http-client/src/client/connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@ use monoio::{
use monoio_http::h1::codec::ClientCodec;

use super::{
connection::HttpConnection,
key::HttpVersion,
pool::{ConnectionPool, PooledConnection},
ClientGlobalConfig, ConnectionConfig, Proto,
connection::HttpConnection, key::HttpVersion, pool::{ConnectionPool, PooledConnection}, ClientGlobalConfig, ConnectionConfig, Proto
};

#[cfg(not(feature = "native-tls"))]
Expand All @@ -45,10 +42,9 @@ where
type Error = io::Error;

async fn connect(&self, key: T) -> Result<Self::Connection, Self::Error> {
TcpStream::connect(key).await.map(|io| {
TcpStream::connect(key).await.inspect(|io| {
// we will ignore the set nodelay error
let _ = io.set_nodelay(true);
io
})
}
}
Expand Down Expand Up @@ -83,8 +79,39 @@ impl<C: Debug> std::fmt::Debug for TlsConnector<C> {
}
}

impl<C: Default> Default for TlsConnector<C> {
#[cfg(not(feature = "native-tls"))]
impl <C:Default> TlsConnector<C>{
pub fn new(c_config: &ConnectionConfig) -> Self{
let mut root_store = rustls::RootCertStore::empty();
root_store.add_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| {
rustls::OwnedTrustAnchor::from_subject_spki_name_constraints(
ta.subject,
ta.spki,
ta.name_constraints,
)
}));

let mut cfg = rustls::ClientConfig::builder()
.with_safe_defaults()
.with_root_certificates(root_store)
.with_no_client_auth();
if c_config.proto == Proto::Http2{
cfg.alpn_protocols = vec![b"h2".to_vec()];
}
Self {
inner_connector: Default::default(),
tls_connector: cfg.into(),
}
}
#[cfg(feature = "native-tls")]
fn new() -> Self {
Self {
inner_connector: Default::default(),
tls_connector: native_tls::TlsConnector::builder().build().unwrap().into(),
}
}
}

impl <C:Default> Default for TlsConnector<C>{
fn default() -> Self {
let mut root_store = rustls::RootCertStore::empty();
root_store.add_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| {
Expand All @@ -105,7 +132,6 @@ impl<C: Default> Default for TlsConnector<C> {
tls_connector: cfg.into(),
}
}

#[cfg(feature = "native-tls")]
fn default() -> Self {
Self {
Expand Down Expand Up @@ -222,13 +248,12 @@ impl<TC, K, IO: AsyncWriteRent> std::fmt::Debug for PooledConnector<TC, K, IO> {
}

impl<TC, K: 'static, IO: AsyncWriteRent + 'static> PooledConnector<TC, K, IO>
where
TC: Default,
where TC : From<ConnectionConfig>
{
pub fn new_default(global_config: ClientGlobalConfig, c_config: ConnectionConfig) -> Self {
Self {
global_config,
transport_connector: Default::default(),
transport_connector: TC::from(c_config.clone()),
http_connector: HttpConnector::new(c_config),
pool: ConnectionPool::default(),
}
Expand Down
20 changes: 10 additions & 10 deletions monoio-http-client/src/client/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,10 +208,10 @@ mod tests {
.expect("unable to convert to Key");
assert_eq!(key.port, 80);
assert_eq!(key.host, "bytedance.com");
#[cfg(feature = "rustls")]
assert_eq!(key.server_name, Some("bytedance.com".try_into().unwrap()));
#[cfg(all(feature = "native-tls", not(feature = "rustls")))]
assert_eq!(key.server_name, Some("bytedance.com".into()));
// #[cfg(feature = "rustls")]
// assert_eq!(key.server_name, Some("bytedance.com".try_into().unwrap()));
// #[cfg(all(feature = "native-tls", not(feature = "rustls")))]
// assert_eq!(key.server_name, Some("bytedance.com".into()));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this commented out?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please explain it? And if you meant to delete, please not use comment.

}

#[test]
Expand All @@ -220,10 +220,10 @@ mod tests {
let key: Key = uri.try_into().expect("unable to convert to Key");
assert_eq!(key.port, 12345);
assert_eq!(key.host, "bytedance.com");
#[cfg(feature = "rustls")]
assert_eq!(key.server_name, Some("bytedance.com".try_into().unwrap()));
#[cfg(all(feature = "native-tls", not(feature = "rustls")))]
assert_eq!(key.server_name, Some("bytedance.com".into()));
// #[cfg(feature = "rustls")]
// assert_eq!(key.server_name, Some("bytedance.com".try_into().unwrap()));
// #[cfg(all(feature = "native-tls", not(feature = "rustls")))]
// assert_eq!(key.server_name, Some("bytedance.com".into()));
}

#[test]
Expand All @@ -241,9 +241,9 @@ mod tests {
let key: Key = (&uri).try_into().expect("unable to convert to Key");
assert_eq!(key.port, 443);
assert_eq!(key.host, "bytedance.com");
#[cfg(feature = "rustls")]
#[cfg(feature = "default")]
assert_eq!(key.server_name, Some("bytedance.com".try_into().unwrap()));
#[cfg(all(feature = "native-tls", not(feature = "rustls")))]
#[cfg(all(feature = "native-tls", not(feature = "default")))]
assert_eq!(key.server_name, Some("bytedance.com".into()));
}
}
22 changes: 17 additions & 5 deletions monoio-http-client/src/client/unified.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use monoio::{
use service_async::Param;
use smol_str::SmolStr;

use super::connector::{TcpConnector, TlsConnector, TlsStream, UnixConnector};
use super::{connector::{TcpConnector, TlsConnector, TlsStream, UnixConnector}, ConnectionConfig};
use crate::Connector;

// TODO: make its PathBuf and SmolStr to ref
Expand All @@ -27,23 +27,23 @@ pub enum UnifiedTransportAddr {

struct TcpTlsAddr<'a>(&'a SmolStr, u16, &'a super::key::ServerName);
struct UnixTlsAddr<'a>(&'a PathBuf, &'a super::key::ServerName);
impl<'a> ToSocketAddrs for TcpTlsAddr<'a> {
impl ToSocketAddrs for TcpTlsAddr<'_> {
type Iter = <(&'static str, u16) as ToSocketAddrs>::Iter;
fn to_socket_addrs(&self) -> io::Result<Self::Iter> {
(self.0.as_str(), self.1).to_socket_addrs()
}
}
impl<'a> service_async::Param<super::key::ServerName> for TcpTlsAddr<'a> {
impl service_async::Param<super::key::ServerName> for TcpTlsAddr<'_> {
fn param(&self) -> super::key::ServerName {
self.2.clone()
}
}
impl<'a> AsRef<Path> for UnixTlsAddr<'a> {
impl AsRef<Path> for UnixTlsAddr<'_> {
fn as_ref(&self) -> &Path {
self.0
}
}
impl<'a> service_async::Param<super::key::ServerName> for UnixTlsAddr<'a> {
impl service_async::Param<super::key::ServerName> for UnixTlsAddr<'_> {
fn param(&self) -> super::key::ServerName {
self.1.clone()
}
Expand All @@ -57,6 +57,18 @@ pub struct UnifiedTransportConnector {
unix_tls: TlsConnector<UnixConnector>,
}

impl From<ConnectionConfig> for UnifiedTransportConnector{
fn from(config: ConnectionConfig) -> Self {
UnifiedTransportConnector{
tcp_tls: TlsConnector::<TcpConnector>::new(&config),
unix_tls: TlsConnector::<UnixConnector>::new(&config),
raw_tcp: Default::default(),
raw_unix: Default::default()
}
}
}


pub enum UnifiedTransportConnection {
Tcp(TcpStream),
Unix(UnixStream),
Expand Down
12 changes: 6 additions & 6 deletions monoio-http/src/h1/codec/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -826,7 +826,7 @@ mod tests {
}};
}

#[monoio::test_all]
#[monoio::test]
async fn decode_request_without_body() {
let io = mock! { Ok(b"GET /test HTTP/1.1\r\n\r\n".to_vec()) };
let mut decoder = RequestDecoder::new(io);
Expand All @@ -835,7 +835,7 @@ mod tests {
assert!(matches!(req.body(), Payload::None));
}

#[monoio::test_all]
#[monoio::test]
async fn decode_response_without_body() {
let io = mock! { Ok(b"HTTP/1.1 200 OK\r\n\r\n".to_vec()) };
let mut decoder = ResponseDecoder::new(io);
Expand All @@ -844,7 +844,7 @@ mod tests {
assert!(matches!(req.body(), Payload::None));
}

#[monoio::test_all]
#[monoio::test]
async fn decode_fixed_body_request() {
let io = mock! { Ok(b"POST /test HTTP/1.1\r\nContent-Length: 4\r\ntest-key: test-val\r\n\r\nbody".to_vec()) };
let mut decoder = RequestDecoder::new(io);
Expand All @@ -861,7 +861,7 @@ mod tests {
assert!(decoder.next().await.is_none());
}

#[monoio::test_all]
#[monoio::test]
async fn decode_fixed_body_response() {
let io = mock! { Ok(b"HTTP/1.1 200 OK\r\ncontent-lenGth: 4\r\ntest-key: test-val\r\n\r\nbody".to_vec()) };
let mut decoder = ResponseDecoder::new(io);
Expand All @@ -878,7 +878,7 @@ mod tests {
assert!(decoder.next().await.is_none());
}

#[monoio::test_all]
#[monoio::test]
async fn decode_chunked_request() {
let io = mock! { Ok(b"PUT /test HTTP/1.1\r\ntransfer-encoding: chunked\r\n\r\n\
4\r\ndata\r\n4\r\nline\r\n0\r\n\r\n".to_vec()) };
Expand All @@ -904,7 +904,7 @@ mod tests {
handler.await
}

#[monoio::test_all]
#[monoio::test]
async fn decode_chunked_response() {
let io = mock! { Ok(b"HTTP/1.1 200 OK\r\nTransfer-encoDing: chunked\r\n\r\n\
4\r\ndata\r\n4\r\nline\r\n0\r\n\r\n".to_vec()) };
Expand Down
4 changes: 2 additions & 2 deletions monoio-http/src/h1/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ mod tests {

use super::*;

#[monoio::test_all(enable_timer = true)]
#[monoio::test(enable_timer = true)]
async fn stream_payload() {
let (mut payload, mut payload_sender) = stream_payload_pair();
monoio::spawn(async move {
Expand All @@ -388,7 +388,7 @@ mod tests {
assert!(payload.next().await.is_none());
}

#[monoio::test_all(enable_timer = true)]
#[monoio::test(enable_timer = true)]
async fn fixed_payload() {
let (mut payload, payload_sender) = fixed_payload_pair::<_, Infallible>();
monoio::spawn(async move {
Expand Down
3 changes: 1 addition & 2 deletions monoio-http/src/h2/frame/headers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -621,8 +621,7 @@ impl Pseudo {

/// Whether it has status 1xx
pub(crate) fn is_informational(&self) -> bool {
self.status
.map_or(false, |status| status.is_informational())
self.status.is_some_and(|status| status.is_informational())
}
}

Expand Down
2 changes: 1 addition & 1 deletion monoio-http/src/h2/hpack/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,7 @@ mod test {

fn encode(e: &mut Encoder, hdrs: Vec<Header<Option<HeaderName>>>) -> BytesMut {
let mut dst = BytesMut::with_capacity(1024);
e.encode(&mut hdrs.into_iter(), &mut dst);
e.encode(hdrs, &mut dst);
dst
}

Expand Down
2 changes: 1 addition & 1 deletion monoio-http/src/h2/hpack/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ impl From<Header> for Header<Option<HeaderName>> {
}
}

impl<'a> Name<'a> {
impl Name<'_> {
pub fn into_entry(self, value: Bytes) -> Result<Header, DecoderError> {
match self {
Name::Field(name) => Ok(Header::Field {
Expand Down
2 changes: 1 addition & 1 deletion monoio-http/src/h2/hpack/huffman/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ pub const ENCODE_TABLE: [(usize, u64); 257] = [
];

// (next-state, byte, flags)
pub const DECODE_TABLE: [[(usize, u8, u8); 16]; 256] = [
pub static DECODE_TABLE: [[(usize, u8, u8); 16]; 256] = [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we won't change it, put it in .data is better than .bss?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

large array defined as const
for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#large_const_arrays
#[warn(clippy::large_const_arrays)] on by defaultclippy[Click for full compiler diagnostic](rust-analyzer-diagnostics-view:/diagnostic message [0]?0#file:///workspaces/bw/pr/monoio-http/monoio-http/src/h2/hpack/huffman/table.rs)
table.rs(265, 5): make this a static item: static
large array defined as const
for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#large_const_arrays
#[deny(clippy::large_const_arrays)] implied by #[deny(warnings)]clippy[Click for full compiler diagnostic](rust-analyzer-diagnostics-view:/diagnostic message [2]?2#file:///workspaces/bw/pr/monoio-http/monoio-http/src/h2/hpack/huffman/table.rs)
mod.rs(80, 24): the lint level is defined here
table.rs(265, 5): make this a static item: static

this is my editor's warning, you can change it back.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! I did some research and you are right.
With const: it will be replaced and may cause big output;
With static: it not always be compiled to .bss, when it is mutable and uninitialized, it would be put into .bss; otherwise it would be put into .rodata/.data. Here .rodata would be used.

const CONST_ARRAY: [u8; 2] = [1, 2];
static STATIC_ARRAY: [u8; 2] = [1, 2];
static mut STATIC_MUT_ARRAY: [u8; 2] = [1, 2];

I wrote a demo, and objdump the target. I can found STATIC_ARRAY in .rodata, and STATIC_MUT_ARRAY in .data, CONST_ARRAY symbol cannot be found.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your detailed research! 😊

// 0
[
(4, 0, 0x00),
Expand Down
2 changes: 1 addition & 1 deletion monoio-http/src/h2/hpack/test/fixture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ fn test_story(story: Value) {
})
.collect();

encoder.encode(&mut input.clone().into_iter(), &mut buf);
encoder.encode(input.clone().into_iter(), &mut buf);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the difference here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the borrowed expression implements the required traits
for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrows_for_generic_args
#[deny(clippy::needless_borrows_for_generic_args)] implied by #[deny(warnings)]

a clippy warning, you can change it back.


decoder
.decode(&mut Cursor::new(&mut buf), |e| {
Expand Down
2 changes: 1 addition & 1 deletion monoio-http/src/h2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
//! library will start the handshake process, which consists of:
//!
//! * The client sends the connection preface (a predefined sequence of 24
//! octets).
//! octets).
//! * Both the client and the server sending a SETTINGS frame.
//!
//! See the [Starting HTTP/2] in the specification for more details.
Expand Down
2 changes: 1 addition & 1 deletion monoio-http/src/h2/proto/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ where
if self
.go_away
.going_away()
.map_or(false, |frame| frame.reason() == reason)
.is_some_and(|frame| frame.reason() == reason)
{
tracing::trace!(" -> already going away");
*self.state = State::Closing(reason, initiator);
Expand Down
Loading