Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

src/lib: Add Multiaddr::protocol_stack #60

Merged
merged 10 commits into from
Oct 24, 2022
15 changes: 15 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,10 @@ impl Multiaddr {
}
self.bytes[(n - m)..] == other.bytes[..]
}

pub fn protocol_stack(&self) -> ProtoStackIter {
ProtoStackIter{ parts: self.iter() }
}
}

impl fmt::Debug for Multiaddr {
Expand Down Expand Up @@ -293,6 +297,17 @@ impl<'a> Iterator for Iter<'a> {
}
}

pub struct ProtoStackIter<'a>{
parts: Iter<'a>
}

impl<'a> Iterator for ProtoStackIter<'a> {
type Item = &'static str;
fn next(&mut self) -> Option<Self::Item> {
self.parts.next().map(|p|p.tag())
}
}

impl<'a> From<Protocol<'a>> for Multiaddr {
fn from(p: Protocol<'a>) -> Multiaddr {
let mut w = Vec::new();
Expand Down
38 changes: 38 additions & 0 deletions src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,44 @@ impl<'a> Protocol<'a> {
Wss(cow) => Wss(Cow::Owned(cow.into_owned())),
}
}

pub fn tag(&self) -> &'static str {
John-LittleBearLabs marked this conversation as resolved.
Show resolved Hide resolved
John-LittleBearLabs marked this conversation as resolved.
Show resolved Hide resolved
use self::Protocol::*;
match self {
Dccp(_) => "dccp",
Dns(_) => "dns",
Dns4(_) => "dns4",
Dns6(_) => "dns6",
Dnsaddr(_) => "dnsaddr",
Http => "http",
Https => "https",
Ip4(_) => "ip4",
Ip6(_) => "ip6",
P2pWebRtcDirect => "p2p-webrtc-direct",
P2pWebRtcStar => "p2p-webrtc-star",
WebRTC => "webrtc",
Certhash(_) => "certhash",
P2pWebSocketStar => "p2p-websocket-star",
Memory(_) => "memory",
Onion(_, _) => "onion",
Onion3(_) => "onion3",
P2p(_) =>"p2p",
P2pCircuit => "p2p-circuit",
Quic => "quic",
Sctp(_) => "sctp",
Tcp(_) => "tcp",
Tls => "tls",
Noise => "noise",
Udp(_) => "udp",
Udt => "udt",
Unix(_) => "unix",
Utp => "utp",
Ws(ref s) if s == "/" => "ws",
Ws(_) => "x-parity-ws",
Wss(ref s) if s == "/" => "wss",
Wss(_) => "x-parity-wss",
}
}
}

impl<'a> fmt::Display for Protocol<'a> {
Expand Down
78 changes: 78 additions & 0 deletions tests/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
extern crate core;

use data_encoding::HEXUPPER;
use multiaddr::*;
use multihash::Multihash;
Expand Down Expand Up @@ -527,3 +529,79 @@ fn unknown_protocol_string() {
},
}
}

#[test]
fn protocol_stack() {
let addresses = [
"/ip4/0.0.0.0",
"/ip6/::1",
"/ip6/2601:9:4f81:9700:803e:ca65:66e8:c21",
"/udp/0",
"/tcp/0",
"/sctp/0",
"/udp/1234",
"/tcp/1234",
"/sctp/1234",
"/udp/65535",
"/tcp/65535",
"/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC",
"/udp/1234/sctp/1234",
"/udp/1234/udt",
"/udp/1234/utp",
"/tcp/1234/http",
"/tcp/1234/tls/http",
"/tcp/1234/https",
"/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/tcp/1234",
"/ip4/127.0.0.1/udp/1234",
"/ip4/127.0.0.1/udp/0",
"/ip4/127.0.0.1/tcp/1234",
"/ip4/127.0.0.1/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC",
"/ip4/127.0.0.1/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/tcp/1234",
"/ip6/2001:8a0:7ac5:4201:3ac9:86ff:fe31:7095/tcp/8000/ws/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC",
"/p2p-webrtc-star/ip4/127.0.0.1/tcp/9090/ws/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC",
"/ip6/2001:8a0:7ac5:4201:3ac9:86ff:fe31:7095/tcp/8000/wss/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC",
"/ip4/127.0.0.1/tcp/9090/p2p-circuit/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC",
"/onion/aaimaq4ygg2iegci:80",
"/dnsaddr/sjc-1.bootstrap.libp2p.io",
"/dnsaddr/sjc-1.bootstrap.libp2p.io/tcp/1234/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
"/ip4/127.0.0.1/tcp/127/ws",
"/ip4/127.0.0.1/tcp/127/tls",
"/ip4/127.0.0.1/tcp/127/tls/ws",
"/ip4/127.0.0.1/tcp/127/noise",
"/ip4/127.0.0.1/udp/1234/webrtc",
];
let argless = std::collections::HashSet::from([
"http",
"https",
"noise",
"p2p-circuit",
"p2p-webrtc-direct",
"p2p-webrtc-star",
"p2p-websocket-star",
"quic",
"tls",
"udt",
"utp",
"webrtc",
"ws",
"wss",
]);
for addr_str in addresses {
let ma = Multiaddr::from_str(addr_str).expect("These are supposed to be valid multiaddrs");
let ps: Vec<&str> = ma.protocol_stack().collect();
let mut toks: Vec<&str> = addr_str.split("/").collect();
assert_eq!("", toks[0]);
toks.remove(0);
let mut i = 0;
while i < toks.len() {
let proto_tag = toks[i];
i += 1;
if argless.contains(proto_tag) {
//skip
} else {
toks.remove(i);
}
}
assert_eq!(ps, toks);
}
}