Skip to content

Commit 18ce9d7

Browse files
author
wangxiaoxiong
committed
feat:tls
1 parent d0e21c1 commit 18ce9d7

File tree

6 files changed

+127
-7
lines changed

6 files changed

+127
-7
lines changed

dubbo/Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ http-body = "0.4.4"
1717
tower = { version = "0.4.12", features = ["timeout"]}
1818
futures-util = "0.3.23"
1919
futures-core ="0.3.23"
20-
tokio = { version = "1.0", features = [ "rt-multi-thread", "time", "fs", "macros", "net", "signal"] }
20+
argh = "0.1"
21+
rustls-pemfile = "1.0.0"
22+
tokio-rustls="0.23.4"
23+
tokio = { version = "1.0", features = [ "rt-multi-thread", "time", "fs", "macros", "net", "signal", "full" ] }
2124
prost = "0.10.4"
2225
lazy_static = "1.3.0"
2326
async-trait = "0.1.56"

dubbo/src/triple/server/builder.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
use std::{
1919
net::{SocketAddr, ToSocketAddrs},
20+
path::Path,
2021
str::FromStr,
2122
};
2223

@@ -25,13 +26,17 @@ use http::{Request, Response};
2526
use hyper::body::Body;
2627
use tower_service::Service;
2728

28-
use crate::BoxBody;
29+
use tokio_rustls::rustls::{Certificate, PrivateKey};
30+
2931
use crate::{common::url::Url, triple::transport::DubboServer};
32+
use crate::{utils, BoxBody};
3033

3134
#[derive(Clone, Default, Debug)]
3235
pub struct ServerBuilder {
3336
pub listener: String,
3437
pub addr: Option<SocketAddr>,
38+
pub certs: Vec<Certificate>,
39+
pub keys: Vec<PrivateKey>,
3540
pub service_names: Vec<String>,
3641
server: DubboServer,
3742
}
@@ -45,6 +50,26 @@ impl ServerBuilder {
4550
Self { listener, ..self }
4651
}
4752

53+
pub fn with_tls(self, certs: &str, keys: &str) -> ServerBuilder {
54+
Self {
55+
certs: match utils::tls::load_certs(Path::new(certs)) {
56+
Ok(v) => v,
57+
Err(err) => {
58+
tracing::error!("error loading tls certs {:?}", err);
59+
Vec::new()
60+
}
61+
},
62+
keys: match utils::tls::load_keys(Path::new(keys)) {
63+
Ok(v) => v,
64+
Err(err) => {
65+
tracing::error!("error loading tls keys {:?}", err);
66+
Vec::new()
67+
}
68+
},
69+
..self
70+
}
71+
}
72+
4873
pub fn with_addr(self, addr: &'static str) -> ServerBuilder {
4974
Self {
5075
addr: addr.to_socket_addrs().unwrap().next(),
@@ -61,6 +86,13 @@ impl ServerBuilder {
6186

6287
pub fn build(self) -> Self {
6388
let mut server = self.server.with_listener(self.listener.clone());
89+
90+
{
91+
if self.certs.len() != 0 && self.keys.len() != 0 {
92+
server = server.with_tls(self.certs.clone(), self.keys.clone());
93+
}
94+
}
95+
6496
{
6597
let lock = crate::protocol::triple::TRIPLE_SERVICES.read().unwrap();
6698
for name in self.service_names.iter() {
@@ -73,6 +105,8 @@ impl ServerBuilder {
73105
server = server.add_service(name.clone(), svc.clone());
74106
}
75107
}
108+
109+
{}
76110
Self { server, ..self }
77111
}
78112

@@ -114,6 +148,8 @@ impl From<Url> for ServerBuilder {
114148
addr: authority.to_string().to_socket_addrs().unwrap().next(),
115149
service_names: u.service_key,
116150
server: DubboServer::default(),
151+
certs: Vec::new(),
152+
keys: Vec::new(),
117153
}
118154
}
119155
}

dubbo/src/triple/transport/service.rs

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,22 @@
1515
* limitations under the License.
1616
*/
1717

18+
use std::io;
1819
use std::net::SocketAddr;
20+
use std::sync::Arc;
1921

2022
use futures_core::Future;
2123
use http::{Request, Response};
2224
use hyper::body::Body;
2325
use tokio::time::Duration;
2426
use tower_service::Service;
2527

28+
use tokio_rustls::rustls::{Certificate, PrivateKey};
29+
use tokio_rustls::{rustls, TlsAcceptor};
30+
2631
use super::listener::get_listener;
2732
use super::router::DubboRouter;
33+
use crate::triple::transport::io::BoxIO;
2834
use crate::BoxBody;
2935

3036
#[derive(Default, Clone, Debug)]
@@ -38,6 +44,8 @@ pub struct DubboServer {
3844
http2_keepalive_timeout: Option<Duration>,
3945
router: DubboRouter,
4046
listener: Option<String>,
47+
certs: Vec<Certificate>,
48+
keys: Vec<PrivateKey>,
4149
}
4250

4351
impl DubboServer {
@@ -93,6 +101,14 @@ impl DubboServer {
93101
..self
94102
}
95103
}
104+
105+
pub fn with_tls(self, certs: Vec<Certificate>, keys: Vec<PrivateKey>) -> Self {
106+
Self {
107+
certs: certs,
108+
keys: keys,
109+
..self
110+
}
111+
}
96112
}
97113

98114
impl DubboServer {
@@ -107,6 +123,8 @@ impl DubboServer {
107123
max_frame_size: None,
108124
router: DubboRouter::new(),
109125
listener: None,
126+
certs: Vec::new(),
127+
keys: Vec::new(),
110128
}
111129
}
112130
}
@@ -147,10 +165,25 @@ impl DubboServer {
147165
None => {
148166
return Err(Box::new(crate::status::DubboError::new(
149167
"listener name is empty".to_string(),
150-
)))
168+
)));
151169
}
152170
};
153171

172+
let acceptor: Option<TlsAcceptor>;
173+
if self.certs.len() != 0 && !self.keys.len() != 0 {
174+
let mut keys = self.keys;
175+
176+
let config = rustls::ServerConfig::builder()
177+
.with_safe_defaults()
178+
.with_no_client_auth()
179+
.with_single_cert(self.certs, keys.remove(0))
180+
.map_err(|err| io::Error::new(io::ErrorKind::InvalidInput, err))?;
181+
182+
acceptor = Some(TlsAcceptor::from(Arc::new(config)));
183+
} else {
184+
acceptor = None;
185+
}
186+
154187
let listener = match get_listener(name, addr).await {
155188
Ok(v) => v,
156189
Err(err) => return Err(err),
@@ -166,6 +199,14 @@ impl DubboServer {
166199
match res {
167200
Ok(conn) => {
168201
let (io, local_addr) = conn;
202+
let b :BoxIO;
203+
204+
if !acceptor.is_none() {
205+
b = BoxIO::new(acceptor.as_ref().unwrap().clone().accept(io).await?);
206+
} else {
207+
b = io;
208+
}
209+
169210
tracing::debug!("hyper serve, local address: {:?}", local_addr);
170211
let c = hyper::server::conn::Http::new()
171212
.http2_only(self.accept_http2)
@@ -175,10 +216,9 @@ impl DubboServer {
175216
.http2_keep_alive_interval(self.http2_keepalive_interval)
176217
.http2_keep_alive_timeout(http2_keepalive_timeout)
177218
.http2_max_frame_size(self.max_frame_size)
178-
.serve_connection(io, svc.clone()).with_upgrades();
219+
.serve_connection(b,svc.clone()).with_upgrades();
179220

180221
tokio::spawn(c);
181-
182222
},
183223
Err(err) => tracing::error!("hyper serve, err: {:?}", err),
184224
}

dubbo/src/utils/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@
1717

1818
pub mod boxed;
1919
pub mod boxed_clone;
20+
pub mod tls;

dubbo/src/utils/tls.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
use rustls_pemfile::{certs, rsa_private_keys};
19+
use std::{
20+
fs::File,
21+
io::{self, BufReader},
22+
path::Path,
23+
};
24+
use tokio_rustls::rustls::{Certificate, PrivateKey};
25+
26+
pub fn load_certs(path: &Path) -> io::Result<Vec<Certificate>> {
27+
certs(&mut BufReader::new(File::open(path)?))
28+
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "invalid cert"))
29+
.map(|mut certs| certs.drain(..).map(Certificate).collect())
30+
}
31+
32+
pub fn load_keys(path: &Path) -> io::Result<Vec<PrivateKey>> {
33+
rsa_private_keys(&mut BufReader::new(File::open(path)?))
34+
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "invalid key"))
35+
.map(|mut keys| keys.drain(..).map(PrivateKey).collect())
36+
}

examples/echo/src/echo/server.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,14 @@ async fn main() {
8080

8181
// 3. 通过serverbuilder来初始化Server
8282
let builder = ServerBuilder::new()
83-
.with_listener("unix".to_string())
83+
.with_listener("tcp".to_string())
8484
.with_service_names(vec!["grpc.examples.echo.Echo".to_string()])
85+
.with_tls(
86+
"/Users/baerwang/project/rusts/apache/tls/tokio-rustls/tests/end.cert",
87+
"/Users/baerwang/project/rusts/apache/tls/tokio-rustls/tests/end.rsa",
88+
)
8589
.with_addr("127.0.0.1:8888");
86-
builder.build().serve().await.unwrap();
90+
println!("{:?}", builder.build().serve().await);
8791
}
8892

8993
#[allow(dead_code)]

0 commit comments

Comments
 (0)