Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature http transport #296

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open

Conversation

ii64
Copy link
Member

@ii64 ii64 commented Dec 23, 2023

Motivation

Follow up for #125

Solution

RFC, API stabilization. Initial POC is using reqwest, however volo have their own http library wrapper, perhaps looking to that later?

@ii64 ii64 requested review from a team as code owners December 23, 2023 19:09
@yukiiiteru
Copy link
Member

The CI failed on building openssl-sys, maybe you should add a feature vendored to its related crates.

volo-thrift/src/client/mod.rs Outdated Show resolved Hide resolved
volo-thrift/src/client/mod.rs Outdated Show resolved Hide resolved
@@ -32,6 +33,7 @@ pub enum ConnStream {
Rustls(#[pin] tokio_rustls::TlsStream<TcpStream>),
#[cfg(feature = "native-tls")]
NativeTls(#[pin] tokio_native_tls::TlsStream<TcpStream>),
Http(#[pin] Http),
Copy link
Member

Choose a reason for hiding this comment

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

Is it possible to move the Conn/IO part of volo-http here? @wfly1998

Copy link
Member

Choose a reason for hiding this comment

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

Yes, grpc is also possible.

Copy link
Member Author

Choose a reason for hiding this comment

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

It'd be nice if you can touch up the implementation to use volo-http, I have no idea about how we can use that with existing volo-http implementation.

Also I wonder of we can reuse the service handler on top of another HTTP server implementation, e.g. Axum, Actix, Rocket, etc etc. So that we can provide multiple service running on the same server for the usecase like /api/authn/v1 will be handled by the AuthenticationServiceV1, /api/feed/v1 will be handled by the FeedServiceV1 etc etc.

Cargo.toml Outdated Show resolved Hide resolved
@@ -33,7 +33,9 @@ jobs:
# - uses: Swatinem/rust-cache@v1
- name: Run tests
run: |
apt install -y pkg-config libssl-dev
Copy link
Member

Choose a reason for hiding this comment

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

Try using vendored for openssl-sys?

Copy link
Member Author

@ii64 ii64 Dec 27, 2023

Choose a reason for hiding this comment

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

I am not really sure how we can set a transitive dependency features, it's a dependency of tokio-native-tls

Copy link
Member

Choose a reason for hiding this comment

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

  1. tokio-native-tls has a feature vendored for enabling native-tls/vendored
  2. native-tls has a feature vendored for enabling openssl/vendored
  3. openssl has a feature vendored for enabling ffi/vendored, and note that the ffi is openssl-sys in the same repository
  4. openssl-sys has a feature vendored through which openssl can use its own openssl implementation instead of libssl-dev

It's complicated and I don't like them 🥲 but it works.

Copy link
Member Author

@ii64 ii64 Dec 27, 2023

Choose a reason for hiding this comment

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

But actually with that, we can let the user decide if they want to use vendored (and statically link the library) or just go by the system package by adding our:

[features]
vendored = ["tokio-native-tls/vendored"]

What do you think?

Copy link
Member

Choose a reason for hiding this comment

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

I think adding a feature vendored to enable tokio-native-tls/vendored is the best way, users can decide by themselves, and we can use vendored in CI.

Copy link
Member Author

Choose a reason for hiding this comment

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

Sounds good, ref for that change @ ac00381

Copy link
Member Author

Choose a reason for hiding this comment

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

Nevermind, I'll open a new PR for that

pub use incoming::{DefaultIncoming, MakeIncoming};

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum Address {
Ip(std::net::SocketAddr),
#[cfg(target_family = "unix")]
Unix(Cow<'static, Path>),
Http(hyper::Uri)
Copy link
Member

Choose a reason for hiding this comment

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

Consider that Uri can be a full uri or a relative uri, e.g., https://www.rust-lang.org/install.html or /hello/world, which is not an address.

Additionally, an http or https host can resolve to SocketAddr, or an openapi server can serve on a unix socket, both of which are supported.

I think using Uri as address is not a good idea.

Copy link
Member Author

Choose a reason for hiding this comment

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

What I have been thinking about that is, we can play with Uri scheme as like what the gRPC one currently does, e.g. unix:///var/run/some.socket.

So wrap it up for client role, Unix("/var/run/some.socket") will talk to the UNIX domain socket as like TCP one, while Http("unix:///var/run/some.socket") will talk to the UNIX domain socket in HTTP with write-buffered RPC payload as the request body. (Or say that if we want to support bi-directional Thrift, we can use Transfer-Encoding: chunked first as initial connection upgrade and go as like what we did on TCP).

For the relative uri, I am not really sure if we can restrict it, if not in the runtime, because that basically has no scheme so we can just throw a panic when we check it.

And for HTTP or HTTPS hosts that can resolve to SocketAddr, I think we can still use Http("https://127.0.0.1:9999/") whereas 120.0.0.1:9999 is a valid SocketAddr with / added for specified endpoint resource.

Or do you have any idea about it?

Copy link
Member

Choose a reason for hiding this comment

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

This type is Address, which is the address used for the transport layer of the network model, while HTTP is a protocol of application layer. They should not be confused.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants