Skip to content

Commit

Permalink
Merge pull request #115 from p2p-industries/master
Browse files Browse the repository at this point in the history
Implement http-path protocol
  • Loading branch information
jxs authored Oct 17, 2024
2 parents fe847fa + 4281ba3 commit a4a4fbd
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 1 deletion.
28 changes: 28 additions & 0 deletions src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ const GARLIC32: u32 = 447;
const SNI: u32 = 449;
const P2P_STARDUST: u32 = 277; // Deprecated
const WEBRTC: u32 = 281;
const HTTP_PATH: u32 = 481;

/// Type-alias for how multi-addresses use `Multihash`.
///
Expand Down Expand Up @@ -128,6 +129,7 @@ pub enum Protocol<'a> {
Sni(Cow<'a, str>),
P2pStardust,
WebRTC,
HttpPath(Cow<'a, str>),
}

impl<'a> Protocol<'a> {
Expand Down Expand Up @@ -276,6 +278,11 @@ impl<'a> Protocol<'a> {
}
"p2p-stardust" => Ok(Protocol::P2pStardust),
"webrtc" => Ok(Protocol::WebRTC),
"http-path" => {
let s = iter.next().ok_or(Error::InvalidProtocolString)?;
let decoded = percent_encoding::percent_decode(s.as_bytes()).decode_utf8()?;
Ok(Protocol::HttpPath(decoded))
}
unknown => Err(Error::UnknownProtocolString(unknown.to_string())),
}
}
Expand Down Expand Up @@ -457,6 +464,14 @@ impl<'a> Protocol<'a> {
}
P2P_STARDUST => Ok((Protocol::P2pStardust, input)),
WEBRTC => Ok((Protocol::WebRTC, input)),
HTTP_PATH => {
let (n, input) = decode::usize(input)?;
let (data, rest) = split_at(n, input)?;
Ok((
Protocol::HttpPath(Cow::Borrowed(str::from_utf8(data)?)),
rest,
))
}
_ => Err(Error::UnknownProtocolId(id)),
}
}
Expand Down Expand Up @@ -604,6 +619,12 @@ impl<'a> Protocol<'a> {
}
Protocol::P2pStardust => w.write_all(encode::u32(P2P_STARDUST, &mut buf))?,
Protocol::WebRTC => w.write_all(encode::u32(WEBRTC, &mut buf))?,
Protocol::HttpPath(s) => {
w.write_all(encode::u32(HTTP_PATH, &mut buf))?;
let bytes = s.as_bytes();
w.write_all(encode::usize(bytes.len(), &mut encode::usize_buffer()))?;
w.write_all(bytes)?
}
}
Ok(())
}
Expand Down Expand Up @@ -651,6 +672,7 @@ impl<'a> Protocol<'a> {
Sni(cow) => Sni(Cow::Owned(cow.into_owned())),
P2pStardust => P2pStardust,
WebRTC => WebRTC,
HttpPath(cow) => HttpPath(Cow::Owned(cow.into_owned())),
}
}

Expand Down Expand Up @@ -698,6 +720,7 @@ impl<'a> Protocol<'a> {
Sni(_) => "sni",
P2pStardust => "p2p-stardust",
WebRTC => "webrtc",
HttpPath(_) => "http-path",
}
}
}
Expand Down Expand Up @@ -755,6 +778,11 @@ impl<'a> fmt::Display for Protocol<'a> {
),
Garlic32(addr) => write!(f, "/{}", multibase::Base::Base32Lower.encode(addr)),
Sni(s) => write!(f, "/{s}"),
HttpPath(s) => {
let encoded =
percent_encoding::percent_encode(s.as_bytes(), PATH_SEGMENT_ENCODE_SET);
write!(f, "/{encoded}")
}
_ => Ok(()),
}
}
Expand Down
22 changes: 21 additions & 1 deletion tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ impl Arbitrary for Ma {
struct Proto(Protocol<'static>);

impl Proto {
const IMPL_VARIANT_COUNT: u8 = 39;
const IMPL_VARIANT_COUNT: u8 = 40;
}

impl Arbitrary for Proto {
Expand Down Expand Up @@ -160,6 +160,7 @@ impl Arbitrary for Proto {
36 => Proto(Sni(Cow::Owned(SubString::arbitrary(g).0))),
37 => Proto(P2pStardust),
38 => Proto(WebRTC),
39 => Proto(HttpPath(Cow::Owned(SubString::arbitrary(g).0))),
_ => panic!("outside range"),
}
}
Expand Down Expand Up @@ -290,6 +291,21 @@ fn construct_success() {
"0604D2C003E003",
vec![Tcp(1234), Tls, Http],
);
ma_valid(
"/tcp/1234/http/http-path/user",
"0604D2E003E1030475736572",
vec![Tcp(1234), Http, HttpPath(Cow::Borrowed("user"))],
);
ma_valid(
"/tcp/1234/http/http-path/api%2Fv0%2Flogin",
"0604D2E003E1030C6170692F76302F6C6F67696E",
vec![Tcp(1234), Http, HttpPath(Cow::Borrowed("api/v0/login"))],
);
ma_valid(
"/tcp/1234/http/http-path/a%2520space",
"0604D2E003E10309612532307370616365",
vec![Tcp(1234), Http, HttpPath(Cow::Borrowed("a%20space"))],
);
ma_valid("/tcp/1234/https", "0604D2BB03", vec![Tcp(1234), Https]);
ma_valid(
"/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/tcp/1234",
Expand Down Expand Up @@ -518,6 +534,7 @@ fn construct_fail() {
"/p2p-circuit/50",
"/ip4/127.0.0.1/udp/1234/webrtc-direct/certhash",
"/ip4/127.0.0.1/udp/1234/webrtc-direct/certhash/b2uaraocy6yrdblb4sfptaddgimjmmp", // 1 character missing from certhash
"/tcp/1234/http/http-path/a/b",
];

for address in &addresses {
Expand Down Expand Up @@ -672,6 +689,9 @@ fn protocol_stack() {
"/udp/1234/utp",
"/tcp/1234/http",
"/tcp/1234/tls/http",
"/tcp/1234/http/http-path/user",
"/tcp/1234/http/http-path/api%2Fv1%2Flogin",
"/tcp/1234/http/http-path/a%20space",
"/tcp/1234/https",
"/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/tcp/1234",
"/ip4/127.0.0.1/udp/1234",
Expand Down

0 comments on commit a4a4fbd

Please sign in to comment.