mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-24 15:21:33 +00:00
Pass the host name with websockets (#177)
This commit is contained in:
@ -35,7 +35,11 @@ use tokio_io::{AsyncRead, AsyncWrite};
|
||||
/// Represents the configuration for a websocket transport capability for libp2p.
|
||||
///
|
||||
/// This implementation of `Transport` accepts any address that looks like
|
||||
/// `/ip4/.../tcp/.../ws` or `/ip6/.../tcp/.../ws`, and connect to the corresponding IP and port.
|
||||
/// `/ip4/.../tcp/.../ws`, `/ip6/.../tcp/.../ws`, `/dns4/.../ws` or `/dns6/.../ws`, and connect to
|
||||
/// the corresponding IP and port.
|
||||
///
|
||||
/// If the underlying multiaddress uses `/dns4` or `/dns6`, then the domain name will be passed in
|
||||
/// the headers of the request. This is important is the listener is behind an HTTP proxy.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct BrowserWsConfig;
|
||||
|
||||
@ -339,6 +343,18 @@ fn multiaddr_to_target(addr: &Multiaddr) -> Result<String, ()> {
|
||||
(&AddrComponent::IP6(ref ip), &AddrComponent::TCP(port), &AddrComponent::WSS) => {
|
||||
Ok(format!("wss://[{}]:{}/", ip, port))
|
||||
}
|
||||
(&AddrComponent::DNS4(ref ns), &AddrComponent::TCP(port), &AddrComponent::WS) => {
|
||||
Ok(format!("ws://{}:{}/", ns, port))
|
||||
}
|
||||
(&AddrComponent::DNS6(ref ns), &AddrComponent::TCP(port), &AddrComponent::WS) => {
|
||||
Ok(format!("ws://{}:{}/", ns, port))
|
||||
}
|
||||
(&AddrComponent::DNS4(ref ns), &AddrComponent::TCP(port), &AddrComponent::WSS) => {
|
||||
Ok(format!("wss://{}:{}/", ns, port))
|
||||
}
|
||||
(&AddrComponent::DNS6(ref ns), &AddrComponent::TCP(port), &AddrComponent::WSS) => {
|
||||
Ok(format!("wss://{}:{}/", ns, port))
|
||||
}
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,10 @@ use websocket::stream::async::Stream as AsyncStream;
|
||||
/// This implementation of `Transport` accepts any address that ends with `/ws` or `/wss`, and will
|
||||
/// try to pass the underlying multiaddress to the underlying `Transport`.
|
||||
///
|
||||
/// Note that the underlying multiaddr is `/dns4/...` or `/dns6/...`, then this library will
|
||||
/// pass the domain name in the headers of the request. This is important is the listener is behind
|
||||
/// an HTTP proxy.
|
||||
///
|
||||
/// > **Note**: `/wss` is only supported for dialing and not listening.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct WsConfig<T> {
|
||||
@ -159,6 +163,8 @@ where
|
||||
|
||||
debug!(target: "libp2p-websocket", "Dialing {} through inner transport", inner_addr);
|
||||
|
||||
let ws_addr = client_addr_to_ws(&inner_addr, is_wss);
|
||||
|
||||
let inner_dial = match self.transport.dial(inner_addr) {
|
||||
Ok(d) => d,
|
||||
Err((transport, old_addr)) => {
|
||||
@ -177,13 +183,8 @@ where
|
||||
let dial = inner_dial
|
||||
.into_future()
|
||||
.and_then(move |(connec, client_addr)| {
|
||||
// We pass a dummy address to `ClientBuilder` because it is never used anywhere
|
||||
// in the negotiation anyway, and we use `async_connect_on` to pass a stream.
|
||||
ClientBuilder::new(if is_wss {
|
||||
"wss://127.0.0.1"
|
||||
} else {
|
||||
"ws://127.0.0.1"
|
||||
}).expect("hard-coded ws address is always valid")
|
||||
ClientBuilder::new(&ws_addr)
|
||||
.expect("generated ws address is always valid")
|
||||
.async_connect_on(connec)
|
||||
.map_err(|err| IoError::new(IoErrorKind::Other, err))
|
||||
.map(|(client, _)| {
|
||||
@ -245,6 +246,38 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn client_addr_to_ws(client_addr: &Multiaddr, is_wss: bool) -> String {
|
||||
let inner = {
|
||||
let protocols: Vec<_> = client_addr.iter().collect();
|
||||
|
||||
if protocols.len() != 2 {
|
||||
"127.0.0.1".to_owned()
|
||||
} else {
|
||||
match (&protocols[0], &protocols[1]) {
|
||||
(&AddrComponent::IP4(ref ip), &AddrComponent::TCP(port)) => {
|
||||
format!("{}:{}", ip, port)
|
||||
}
|
||||
(&AddrComponent::IP6(ref ip), &AddrComponent::TCP(port)) => {
|
||||
format!("[{}]:{}", ip, port)
|
||||
}
|
||||
(&AddrComponent::DNS4(ref ns), &AddrComponent::TCP(port)) => {
|
||||
format!("{}:{}", ns, port)
|
||||
}
|
||||
(&AddrComponent::DNS6(ref ns), &AddrComponent::TCP(port)) => {
|
||||
format!("{}:{}", ns, port)
|
||||
}
|
||||
_ => "127.0.0.1".to_owned(),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if is_wss {
|
||||
format!("wss://{}", inner)
|
||||
} else {
|
||||
format!("ws://{}", inner)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
extern crate libp2p_tcp_transport as tcp;
|
||||
|
Reference in New Issue
Block a user