mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-27 16:51:34 +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.
|
/// Represents the configuration for a websocket transport capability for libp2p.
|
||||||
///
|
///
|
||||||
/// This implementation of `Transport` accepts any address that looks like
|
/// 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)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct BrowserWsConfig;
|
pub struct BrowserWsConfig;
|
||||||
|
|
||||||
@ -339,6 +343,18 @@ fn multiaddr_to_target(addr: &Multiaddr) -> Result<String, ()> {
|
|||||||
(&AddrComponent::IP6(ref ip), &AddrComponent::TCP(port), &AddrComponent::WSS) => {
|
(&AddrComponent::IP6(ref ip), &AddrComponent::TCP(port), &AddrComponent::WSS) => {
|
||||||
Ok(format!("wss://[{}]:{}/", ip, port))
|
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(()),
|
_ => 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
|
/// 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`.
|
/// 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.
|
/// > **Note**: `/wss` is only supported for dialing and not listening.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct WsConfig<T> {
|
pub struct WsConfig<T> {
|
||||||
@ -159,6 +163,8 @@ where
|
|||||||
|
|
||||||
debug!(target: "libp2p-websocket", "Dialing {} through inner transport", inner_addr);
|
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) {
|
let inner_dial = match self.transport.dial(inner_addr) {
|
||||||
Ok(d) => d,
|
Ok(d) => d,
|
||||||
Err((transport, old_addr)) => {
|
Err((transport, old_addr)) => {
|
||||||
@ -177,13 +183,8 @@ where
|
|||||||
let dial = inner_dial
|
let dial = inner_dial
|
||||||
.into_future()
|
.into_future()
|
||||||
.and_then(move |(connec, client_addr)| {
|
.and_then(move |(connec, client_addr)| {
|
||||||
// We pass a dummy address to `ClientBuilder` because it is never used anywhere
|
ClientBuilder::new(&ws_addr)
|
||||||
// in the negotiation anyway, and we use `async_connect_on` to pass a stream.
|
.expect("generated ws address is always valid")
|
||||||
ClientBuilder::new(if is_wss {
|
|
||||||
"wss://127.0.0.1"
|
|
||||||
} else {
|
|
||||||
"ws://127.0.0.1"
|
|
||||||
}).expect("hard-coded ws address is always valid")
|
|
||||||
.async_connect_on(connec)
|
.async_connect_on(connec)
|
||||||
.map_err(|err| IoError::new(IoErrorKind::Other, err))
|
.map_err(|err| IoError::new(IoErrorKind::Other, err))
|
||||||
.map(|(client, _)| {
|
.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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
extern crate libp2p_tcp_transport as tcp;
|
extern crate libp2p_tcp_transport as tcp;
|
||||||
|
Reference in New Issue
Block a user