Skip to content

Commit

Permalink
feat: make it possible to try several sockaddrs when starting server (#…
Browse files Browse the repository at this point in the history
…567)

* fix: enable several sockaddress when starting servers

* nits

* more verbose asserts in rustdoc tests

* fix tests

* fix tests again
  • Loading branch information
niklasad1 authored Nov 17, 2021
1 parent aacf7c0 commit e2d4722
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 19 deletions.
2 changes: 1 addition & 1 deletion benches/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ pub async fn http_server(handle: tokio::runtime::Handle) -> (String, jsonrpsee::
let server = HttpServerBuilder::default()
.max_request_body_size(u32::MAX)
.custom_tokio_runtime(handle)
.build("127.0.0.1:0".parse().unwrap())
.build("127.0.0.1:0")
.unwrap();
let mut module = RpcModule::new(());
module.register_method(SYNC_METHOD_NAME, |_, _| Ok("lo")).unwrap();
Expand Down
2 changes: 1 addition & 1 deletion examples/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ async fn main() -> anyhow::Result<()> {
}

async fn run_server() -> anyhow::Result<(SocketAddr, HttpServerHandle)> {
let server = HttpServerBuilder::default().build("127.0.0.1:0".parse()?)?;
let server = HttpServerBuilder::default().build("127.0.0.1:0".parse::<SocketAddr>()?)?;
let mut module = RpcModule::new(());
module.register_method("say_hello", |_, _| Ok("lo"))?;

Expand Down
58 changes: 46 additions & 12 deletions http-server/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ use socket2::{Domain, Socket, Type};
use std::{
cmp,
future::Future,
net::{SocketAddr, TcpListener},
net::{SocketAddr, TcpListener, ToSocketAddrs},
pin::Pin,
task::{Context, Poll},
};
Expand Down Expand Up @@ -106,7 +106,50 @@ impl Builder {
}

/// Finalizes the configuration of the server.
pub fn build(self, addr: SocketAddr) -> Result<Server, Error> {
///
/// ```rust
/// #[tokio::main]
/// async fn main() {
/// let listener = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
/// let occupied_addr = listener.local_addr().unwrap();
/// let addrs: &[std::net::SocketAddr] = &[
/// occupied_addr,
/// "127.0.0.1:0".parse().unwrap(),
/// ];
/// assert!(jsonrpsee_http_server::HttpServerBuilder::default().build(occupied_addr).is_err());
/// assert!(jsonrpsee_http_server::HttpServerBuilder::default().build(addrs).is_ok());
/// }
/// ```
pub fn build(self, addrs: impl ToSocketAddrs) -> Result<Server, Error> {
let mut err: Option<Error> = None;

for addr in addrs.to_socket_addrs()? {
let (listener, local_addr) = match self.inner_builder(addr) {
Ok(res) => res,
Err(e) => {
err = Some(e);
continue;
}
};

return Ok(Server {
listener,
local_addr,
access_control: self.access_control,
max_request_body_size: self.max_request_body_size,
resources: self.resources,
tokio_runtime: self.tokio_runtime,
});
}

let err = err.unwrap_or_else(|| std::io::Error::new(std::io::ErrorKind::NotFound, "No address found").into());
Err(err)
}

fn inner_builder(
&self,
addr: SocketAddr,
) -> Result<(hyper::server::Builder<hyper::server::conn::AddrIncoming>, Option<SocketAddr>), Error> {
let domain = Domain::for_address(addr);
let socket = Socket::new(domain, Type::STREAM, None)?;
socket.set_nodelay(true)?;
Expand All @@ -119,17 +162,8 @@ impl Builder {
socket.listen(128)?;
let listener: TcpListener = socket.into();
let local_addr = listener.local_addr().ok();

let listener = hyper::Server::from_tcp(listener)?;

Ok(Server {
listener,
local_addr,
access_control: self.access_control,
max_request_body_size: self.max_request_body_size,
resources: self.resources,
tokio_runtime: self.tokio_runtime,
})
Ok((listener, local_addr))
}
}

Expand Down
2 changes: 1 addition & 1 deletion http-server/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ use jsonrpsee_test_utils::TimeoutFutureExt;
use serde_json::Value as JsonValue;

async fn server() -> (SocketAddr, ServerHandle) {
let server = HttpServerBuilder::default().build("127.0.0.1:0".parse().unwrap()).unwrap();
let server = HttpServerBuilder::default().build("127.0.0.1:0").unwrap();
let ctx = TestContext;
let mut module = RpcModule::new(ctx);
let addr = server.local_addr().unwrap();
Expand Down
2 changes: 1 addition & 1 deletion tests/tests/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ pub async fn websocket_server() -> SocketAddr {
}

pub async fn http_server() -> (SocketAddr, HttpServerHandle) {
let server = HttpServerBuilder::default().build("127.0.0.1:0".parse().unwrap()).unwrap();
let server = HttpServerBuilder::default().build("127.0.0.1:0").unwrap();
let mut module = RpcModule::new(());
let addr = server.local_addr().unwrap();
module.register_method("say_hello", |_, _| Ok("hello")).unwrap();
Expand Down
2 changes: 1 addition & 1 deletion tests/tests/resource_limiting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ async fn http_server(module: RpcModule<()>) -> Result<(SocketAddr, HttpServerHan
let server = HttpServerBuilder::default()
.register_resource("CPU", 6, 2)?
.register_resource("MEM", 10, 1)?
.build("127.0.0.1:0".parse().unwrap())?;
.build("127.0.0.1:0")?;

let addr = server.local_addr()?;
let handle = server.start(module)?;
Expand Down
19 changes: 17 additions & 2 deletions ws-server/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -563,8 +563,23 @@ impl Builder {
}

/// Finalize the configuration of the server. Consumes the [`Builder`].
pub async fn build(self, addr: impl ToSocketAddrs) -> Result<Server, Error> {
let listener = TcpListener::bind(addr).await?;
///
/// ```rust
/// #[tokio::main]
/// async fn main() {
/// let listener = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
/// let occupied_addr = listener.local_addr().unwrap();
/// let addrs: &[std::net::SocketAddr] = &[
/// occupied_addr,
/// "127.0.0.1:0".parse().unwrap(),
/// ];
/// assert!(jsonrpsee_ws_server::WsServerBuilder::default().build(occupied_addr).await.is_err());
/// assert!(jsonrpsee_ws_server::WsServerBuilder::default().build(addrs).await.is_ok());
/// }
/// ```
///
pub async fn build(self, addrs: impl ToSocketAddrs) -> Result<Server, Error> {
let listener = TcpListener::bind(addrs).await?;
let stop_monitor = StopMonitor::new();
let resources = self.resources;
Ok(Server { listener, cfg: self.settings, stop_monitor, resources })
Expand Down

0 comments on commit e2d4722

Please sign in to comment.