Skip to content

Commit

Permalink
Merge pull request #27 from k9withabone/ipv6-brackets
Browse files Browse the repository at this point in the history
fix(service): support host IP in brackets for `ports` short syntax
  • Loading branch information
k9withabone authored Sep 29, 2024
2 parents 2c50d2c + 2bd181f commit 0159297
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 8 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ sort_commits = "oldest"

[package]
name = "compose_spec"
version = "0.2.1-alpha.3"
version = "0.2.1-alpha.4"
authors.workspace = true
edition.workspace = true
license.workspace = true
Expand Down
17 changes: 12 additions & 5 deletions src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1078,18 +1078,25 @@ where
de::Error::custom("extra host value must be a string representing an IP address")
})?;

// Remove brackets possibly surrounding IP address, e.g. `[::1]`
let value = value.strip_prefix('[').unwrap_or(value);
let value = value.strip_suffix(']').unwrap_or(value);

Ok((
Hostname::new(key).map_err(de::Error::custom)?,
value.parse().map_err(de::Error::custom)?,
strip_brackets(value).parse().map_err(de::Error::custom)?,
))
})
.collect()
}

/// Remove surrounding square brackets from a string slice.
///
/// If the brackets are not in a pair, then the string is returned unchanged.
///
/// For example, an IPv6 address may be in brackets, `[::1]` to `::1`.
fn strip_brackets(s: &str) -> &str {
s.strip_prefix('[')
.and_then(|s| s.strip_suffix(']'))
.unwrap_or(s)
}

/// IPC isolation mode for a [`Service`] container.
///
/// Available values are platform specific.
Expand Down
22 changes: 21 additions & 1 deletion src/service/ports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ use thiserror::Error;

use crate::{impl_from_str, serde::FromStrOrU16Visitor, Extensions, ShortOrLong};

use super::strip_brackets;

/// [`Service`](super::Service) container ports to publish to the host.
///
/// [compose-spec](https://github.com/compose-spec/compose-spec/blob/master/05-services.md#ports)
Expand Down Expand Up @@ -308,7 +310,7 @@ impl FromStr for ShortPort {
})
.map(|(host_ip, rest)| {
s = rest;
host_ip
strip_brackets(host_ip)
.parse()
.map_err(|source| ParseShortPortError::IpAddr {
source,
Expand Down Expand Up @@ -973,6 +975,8 @@ pub(super) mod tests {
use super::*;

mod short_port {
use std::net::Ipv6Addr;

use super::*;

proptest! {
Expand All @@ -986,6 +990,22 @@ pub(super) mod tests {
prop_assert_eq!(&port, &port.to_string().parse()?);
}
}

#[test]
fn host_ip_brackets() -> Result<(), ParseShortPortError> {
let port = ShortPort {
host_ip: Some(IpAddr::V6(Ipv6Addr::LOCALHOST)),
ranges: ShortRanges {
host: Some(80.into()),
container: 80.into(),
},
protocol: None,
};
assert_eq!("[::1]:80:80".parse::<ShortPort>()?, port);
assert_eq!("::1:80:80".parse::<ShortPort>()?, port);

Ok(())
}
}

mod range {
Expand Down

0 comments on commit 0159297

Please sign in to comment.