Skip to content

Commit

Permalink
Merge branch 'master' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
sunli829 committed Jan 6, 2024
2 parents 3950b8a + 18c267d commit 61baa2c
Show file tree
Hide file tree
Showing 65 changed files with 761 additions and 463 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:
# Switch to stable Rust
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.67.0
toolchain: 1.74.0
components: rustfmt, clippy
override: true
- name: Cache Rust
Expand Down Expand Up @@ -91,7 +91,7 @@ jobs:
# Switch to stable Rust
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.67.0
toolchain: 1.74.0
components: rustfmt, clippy
- name: Cache Rust
uses: Swatinem/rust-cache@v2
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/code-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- name: Install Stable Toolchain
uses: dtolnay/rust-toolchain@stable
with:
toolchain: 1.67.0
toolchain: 1.74.0
components: rustfmt
- name: Cache Rust
uses: Swatinem/rust-cache@v2
Expand Down
14 changes: 7 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ repository = "https://github.com/poem-web/poem"
rust-version = "1.64"

[workspace.dependencies]
poem = { path = "poem", version = "1.3.59", default-features = false }
poem-derive = { path = "poem-derive", version = "1.3.59" }
poem-openapi-derive = { path = "poem-openapi-derive", version = "3.0.6" }
poem-grpc-build = { path = "poem-grpc-build", version = "0.2.23" }
poem = { path = "poem", version = "2.0.0", default-features = false }
poem-derive = { path = "poem-derive", version = "2.0.0" }
poem-openapi-derive = { path = "poem-openapi-derive", version = "4.0.0" }
poem-grpc-build = { path = "poem-grpc-build", version = "0.3.0" }

proc-macro-crate = "2.0.0"
proc-macro2 = "1.0.29"
Expand All @@ -45,8 +45,8 @@ quick-xml = { version = "0.30.0", features = ["serialize"] }
base64 = "0.21.0"
serde_urlencoded = "0.7.1"
indexmap = "2.0.0"
reqwest = { version = "0.11.23", default-features = false }

# rustls, update together
hyper-rustls = { version = "0.24.0", default-features = false }
rustls = "0.21.0"
tokio-rustls = "0.24.0"
rustls = "0.22.0"
tokio-rustls = "0.25.0"
21 changes: 11 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,17 @@ This repo contains the following main components:

The following are cases of community use:

| Repo | Description | Documentation |
|----------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------|
| [delicate](https://github.com/BinChengZhao/delicate) | A distributed task scheduling platform written in rust. | [(README)](https://delicate-rs.github.io/Roadmap.html) |
| [databend](https://github.com/datafuselabs/databend) | A cloud-native data warehouse written in rust. | [(ROADMAP)](https://github.com/datafuselabs/databend/issues/746) |
| [muse](https://leihuo.163.com/) | A NetEase Leihuo's internal art resource sharing platform, backend in rust. | |
| [hik-proconnect](https://www.hikvision.com/en/products/software/hik-proconnect/) | A front-end automated deployment platform based on continuous integration of aws. Hik-ProConnect project for Hikvision | |
| [warpgate](https://github.com/eugeny/warpgate) | A smart SSH bastion host that works with any SSH clients. | [(README)](https://github.com/warp-tech/warpgate/blob/main/README.md) |
| [lust](https://github.com/ChillFish8/lust) | A fast, auto-optimizing image server designed for high throughput and caching. | [(README)](https://github.com/ChillFish8/lust/blob/master/README.md) |
| [aptos](https://github.com/aptos-labs/aptos-core) | Building the safest and most scalable Layer 1 blockchain. | [(WEBSITE)](https://aptoslabs.com/) |
| [poem-casbin](https://github.com/casbin-rs/poem-casbin) | Casbin access control middleware for poem framework. | [(WEBSITE)](https://casbin.org/) |
| Repo | Description | Documentation |
|----------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------|
| [delicate](https://github.com/BinChengZhao/delicate) | A distributed task scheduling platform written in rust. | [(README)](https://delicate-rs.github.io/Roadmap.html) |
| [databend](https://github.com/datafuselabs/databend) | A cloud-native data warehouse written in rust. | [(ROADMAP)](https://github.com/datafuselabs/databend/issues/746) |
| [muse](https://leihuo.163.com/) | A NetEase Leihuo's internal art resource sharing platform, backend in rust. | |
| [hik-proconnect](https://www.hikvision.com/en/products/software/hik-proconnect/) | A front-end automated deployment platform based on continuous integration of aws. Hik-ProConnect project for Hikvision | |
| [warpgate](https://github.com/eugeny/warpgate) | A smart SSH bastion host that works with any SSH clients. | [(README)](https://github.com/warp-tech/warpgate/blob/main/README.md) |
| [lust](https://github.com/ChillFish8/lust) | A fast, auto-optimizing image server designed for high throughput and caching. | [(README)](https://github.com/ChillFish8/lust/blob/master/README.md) |
| [aptos](https://github.com/aptos-labs/aptos-core) | Building the safest and most scalable Layer 1 blockchain. | [(WEBSITE)](https://aptoslabs.com/) |
| [poem-casbin](https://github.com/casbin-rs/poem-casbin) | Casbin access control middleware for poem framework. | [(WEBSITE)](https://casbin.org/) |
| [poem-grants](https://github.com/DDtKey/protect-endpoints/tree/main/poem-grants) | Authorization extension to protect endpoints. | [(README)](https://github.com/DDtKey/protect-endpoints/blob/main/poem-grants/README.md) |


### Startups
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion examples/grpc/helloworld/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>
.unwrap(),
);
let request = Request::new(HelloRequest {
name: "Tonic".into(),
name: "Poem".into(),
});
let response = client.say_hello(request).await?;
println!("RESPONSE={response:?}");
Expand Down
2 changes: 1 addition & 1 deletion examples/grpc/middleware/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>
.unwrap(),
);
let request = Request::new(HelloRequest {
name: "Tonic".into(),
name: "Poem".into(),
});
let response = client.say_hello(request).await?;
println!("RESPONSE={response:?}");
Expand Down
84 changes: 84 additions & 0 deletions examples/openapi/combined-apis/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
## Merging API Specifications

To merge API specifications for multiple services and expose them on a single page, follow these steps:

1. Generate OpenAPI specifications for each service.
2. Create a function to merge the specifications. ...
3. Integrate the merged specification when creating the OpenApiService.
4. Test the merged API specification to ensure it works as expected.

Example code snippet:

```rust
// Merge OpenAPI specifications
let merged_spec = merge_openapi_specs(auth_spec, test_spec);

// Create an OpenApiService for the merged specification
let api_service = OpenApiService::new_with_spec(merged_spec, "Merged API", version).server(api_doc_url_info);

___________________________________________________________________________


## Merging API Specifications [Explained]:

If you have two API services and wish to merge their OpenAPI specifications to be accessed on a single page, follow these steps:

1.Generate OpenAPI Specifications:

Ensure that you have the OpenAPI specifications for each service. You can use tools like Swagger or OpenAPI Generator to automatically generate these specifications from your API code.

2.Merge Specifications:

Create a function to merge the OpenAPI specifications. Below is an example code snippet. Customize the function based on the structure of your OpenAPI specifications. Ensure that you handle conflicts appropriately.:


lang:'Rust'

use openapiv3::OpenAPI;

fn merge_openapi_specs(auth_spec: OpenAPI, test_spec: OpenAPI) -> OpenAPI {
let mut merged_spec = auth_spec.clone(); // Start with one of the specs

// Merge paths
if let Some(test_paths) = test_spec.paths {
if let Some(merged_paths) = &mut merged_spec.paths {
merged_paths.extend(test_paths);
} else {
merged_spec.paths = Some(test_paths);
}
}

// Merge components, etc.

merged_spec
}


3. Integrate Merged Specification:

Use the merged specification when creating the OpenApiService. Update your application code as following example:

lang:'Rust'

use poem_openapi::{OpenApiService, SwaggerUIConfig};

// Assuming you have your OpenAPI specs for AuthApi and TestApi in variables auth_spec and test_spec.

// Merge OpenAPI specifications
let merged_spec = merge_openapi_specs(auth_spec, test_spec);

// Create an OpenApiService for the merged specification
let api_service = OpenApiService::new_with_spec(merged_spec, "Merged API", version).server(api_doc_url_info);

// Configure Swagger UI for the merged API
let ui = api_service.swagger_ui(SwaggerUIConfig::default().url("/panel/openapi.json"));

let app = Route::new()
.at("/status", get(server_status))
.nest("/api/auth", get_auth_api())
.nest("/api/test", get_test_api())
.nest("/panel", ui);

4. Testing:

Make sure to thoroughly test the merged API specification to ensure that it works as expected. Verify that the paths, components, and other relevant information are correctly combined.
3 changes: 1 addition & 2 deletions examples/poem/acme-expanded-http-01/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ async fn main() -> Result<(), std::io::Error> {
}
tracing_subscriber::fmt::init();

let mut acme_client =
AcmeClient::try_new(&LETS_ENCRYPT_PRODUCTION.parse().unwrap(), vec![]).await?;
let mut acme_client = AcmeClient::try_new(LETS_ENCRYPT_PRODUCTION, vec![]).await?;
let cert_resolver = Arc::new(ResolveServerCert::default());
let challenge = ChallengeType::Http01;
let keys_for_http_challenge = Http01TokensMap::new();
Expand Down
3 changes: 1 addition & 2 deletions examples/poem/opentelemetry-jaeger/src/server1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use opentelemetry_http::HeaderInjector;
use opentelemetry_sdk::{propagation::TraceContextPropagator, trace::Tracer};
use poem::{
get, handler,
http::Method,
listener::TcpListener,
middleware::{OpenTelemetryMetrics, OpenTelemetryTracing},
web::Data,
Expand Down Expand Up @@ -38,7 +37,7 @@ async fn index(tracer: Data<&Tracer>, body: String) -> String {

let req = {
let mut req = reqwest::Request::new(
Method::GET,
reqwest::Method::GET,
Url::from_str("http://localhost:3002/api2").unwrap(),
);
global::get_text_map_propagator(|propagator| {
Expand Down
2 changes: 1 addition & 1 deletion poem-derive/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "poem-derive"
version = "1.3.59"
version = "2.0.0"
authors.workspace = true
edition.workspace = true
license.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion poem-grpc-build/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "poem-grpc-build"
version = "0.2.23"
version = "0.3.0"
authors.workspace = true
edition.workspace = true
license.workspace = true
Expand Down
19 changes: 10 additions & 9 deletions poem-grpc/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "poem-grpc"
version = "0.2.25"
version = "0.3.0"
authors.workspace = true
edition.workspace = true
license.workspace = true
Expand All @@ -21,9 +21,8 @@ json-codec = ["serde", "serde_json"]
poem = { workspace = true, default-features = true }

futures-util.workspace = true
hyper = { version = "0.14.20", features = ["client"] }
async-stream = "0.3.3"
tokio = { workspace = true, features = ["io-util", "rt", "sync"] }
tokio = { workspace = true, features = ["io-util", "rt", "sync", "net"] }
flate2 = "1.0.24"
itoa = "1.0.2"
percent-encoding = "2.1.0"
Expand All @@ -32,16 +31,18 @@ prost = "0.12.0"
base64 = "0.21.0"
prost-types = "0.12.0"
tokio-stream = { workspace = true, features = ["sync"] }
hyper-rustls = { workspace = true, features = [
"webpki-roots",
"http2",
"native-tokio",
] }
serde = { workspace = true, optional = true }
serde_json = { workspace = true, optional = true }
rustls.workspace = true
rustls = { workspace = true }
thiserror.workspace = true
fastrand = "2.0.0"
http = "1.0.0"
hyper = { version = "1.0.0", features = ["http1", "http2"] }
hyper-util = { version = "0.1.1", features = ["client-legacy", "tokio"] }
http-body-util = "0.1.0"
tokio-rustls.workspace = true
tower-service = "0.3.2"
webpki-roots = "0.26"

[build-dependencies]
poem-grpc-build.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion poem-grpc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ This crate uses `#![forbid(unsafe_code)]` to ensure everything is implemented in

## MSRV

The minimum supported Rust version for this crate is `1.67.0`.
The minimum supported Rust version for this crate is `1.74.0`.

## Contributing

Expand Down
38 changes: 18 additions & 20 deletions poem-grpc/src/client.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use std::sync::Arc;
use std::{io::Error as IoError, sync::Arc};

use bytes::Bytes;
use futures_util::TryStreamExt;
use hyper_rustls::HttpsConnectorBuilder;
use http_body_util::BodyExt;
use hyper_util::{client::legacy::Client, rt::TokioExecutor};
use poem::{
http::{
header, header::InvalidHeaderValue, uri::InvalidUri, Extensions, HeaderValue, Method,
Expand All @@ -14,10 +16,13 @@ use rustls::ClientConfig as TlsClientConfig;

use crate::{
codec::Codec,
connector::HttpsConnector,
encoding::{create_decode_response_body, create_encode_request_body},
Code, Metadata, Request, Response, Status, Streaming,
};

pub(crate) type BoxBody = http_body_util::combinators::BoxBody<Bytes, IoError>;

/// A configuration for GRPC client
#[derive(Default)]
pub struct ClientConfig {
Expand Down Expand Up @@ -392,29 +397,17 @@ fn create_client_endpoint(
config: ClientConfig,
) -> Arc<dyn Endpoint<Output = HttpResponse> + 'static> {
let mut config = config;
let cli = match config.tls_config.take() {
Some(tls_config) => hyper::Client::builder().http2_only(true).build(
HttpsConnectorBuilder::new()
.with_tls_config(tls_config)
.https_or_http()
.enable_http2()
.build(),
),
None => hyper::Client::builder().http2_only(true).build(
HttpsConnectorBuilder::new()
.with_webpki_roots()
.https_or_http()
.enable_http2()
.build(),
),
};
let cli = Client::builder(TokioExecutor::new())
.http2_only(true)
.build(HttpsConnector::new(config.tls_config.take()));

let config = Arc::new(config);

Arc::new(poem::endpoint::make(move |request| {
let config = config.clone();
let cli = cli.clone();
async move {
let mut request: hyper::Request<hyper::Body> = request.into();
let mut request: hyper::Request<BoxBody> = request.into();

if config.uris.is_empty() {
return Err(poem::Error::from_string(
Expand Down Expand Up @@ -443,7 +436,12 @@ fn create_client_endpoint(
}

let resp = cli.request(request).await.map_err(to_boxed_error)?;
Ok::<_, poem::Error>(HttpResponse::from(resp))
let (parts, body) = resp.into_parts();

Ok::<_, poem::Error>(HttpResponse::from(hyper::Response::from_parts(
parts,
body.map_err(IoError::other),
)))
}
}))
}
Loading

0 comments on commit 61baa2c

Please sign in to comment.