Skip to content

Commit 29b1217

Browse files
committed
config: Simplify CIDR parsing code
1 parent 46b8d40 commit 29b1217

File tree

1 file changed

+40
-40
lines changed

1 file changed

+40
-40
lines changed

src/config.rs

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ impl Default for Server {
9494
match env_optional::<String>("WEB_PAGE_OFFSET_CIDR_BLOCKLIST") {
9595
None => vec![],
9696
Some(s) if s.is_empty() => vec![],
97-
Some(s) => s.split(',').map(String::from).collect(),
97+
Some(s) => s.split(',').map(parse_cidr_block).collect(),
9898
};
9999

100100
let base = Base::from_environment();
@@ -116,7 +116,7 @@ impl Default for Server {
116116
blocked_traffic: blocked_traffic(),
117117
max_allowed_page_offset: env_optional("WEB_MAX_ALLOWED_PAGE_OFFSET").unwrap_or(200),
118118
page_offset_ua_blocklist,
119-
page_offset_cidr_blocklist: parse_cidr_blocks(&page_offset_cidr_blocklist),
119+
page_offset_cidr_blocklist,
120120
excluded_crate_names,
121121
domain_name: domain_name(),
122122
allowed_origins,
@@ -158,7 +158,7 @@ pub(crate) fn domain_name() -> String {
158158
dotenv::var("DOMAIN_NAME").unwrap_or_else(|_| "crates.io".into())
159159
}
160160

161-
/// Parses list of CIDR block strings to valid `IpNetwork` structs.
161+
/// Parses a CIDR block string to a valid `IpNetwork` struct.
162162
///
163163
/// The purpose is to be able to block IP ranges that overload the API that uses pagination.
164164
///
@@ -167,30 +167,25 @@ pub(crate) fn domain_name() -> String {
167167
/// * at least 16 for IPv4 based CIDRs.
168168
/// * at least 64 for IPv6 based CIDRs
169169
///
170-
fn parse_cidr_blocks(blocks: &[String]) -> Vec<IpNetwork> {
171-
blocks
172-
.iter()
173-
.map(|block| {
174-
let network = block.parse::<IpNetwork>();
175-
match network {
176-
Ok(cidr) => {
177-
let host_prefix = match cidr {
178-
IpNetwork::V4(_) => 16,
179-
IpNetwork::V6(_) => 64,
180-
};
181-
if cidr.prefix() < host_prefix {
182-
panic!(
183-
"WEB_PAGE_OFFSET_CIDR_BLOCKLIST only allows CIDR blocks with a host prefix \
170+
fn parse_cidr_block(block: &str) -> IpNetwork {
171+
let network = block.parse();
172+
match network {
173+
Ok(cidr) => {
174+
let host_prefix = match cidr {
175+
IpNetwork::V4(_) => 16,
176+
IpNetwork::V6(_) => 64,
177+
};
178+
if cidr.prefix() < host_prefix {
179+
panic!(
180+
"WEB_PAGE_OFFSET_CIDR_BLOCKLIST only allows CIDR blocks with a host prefix \
184181
of at least 16 bits (IPv4) or 64 bits (IPv6)."
185-
);
186-
} else {
187-
cidr
188-
}
189-
},
190-
Err(_) => panic!("WEB_PAGE_OFFSET_CIDR_BLOCKLIST must contain IPv4 or IPv6 CIDR blocks."),
182+
);
183+
} else {
184+
cidr
191185
}
192-
})
193-
.collect::<Vec<_>>()
186+
}
187+
Err(_) => panic!("WEB_PAGE_OFFSET_CIDR_BLOCKLIST must contain IPv4 or IPv6 CIDR blocks."),
188+
}
194189
}
195190

196191
fn blocked_traffic() -> Vec<(String, Vec<String>)> {
@@ -235,35 +230,40 @@ fn parse_traffic_patterns_splits_on_comma_and_looks_for_equal_sign() {
235230

236231
#[test]
237232
fn parse_cidr_block_list_successfully() {
238-
let cidr_blocks = vec!["127.0.0.1/24".to_string(), "192.168.0.1/31".to_string()];
239-
240-
let blocks = parse_cidr_blocks(&cidr_blocks);
241233
assert_eq!(
242-
vec![
243-
"127.0.0.1/24".parse::<IpNetwork>().unwrap(),
244-
"192.168.0.1/31".parse::<IpNetwork>().unwrap(),
245-
],
246-
blocks,
234+
parse_cidr_block("127.0.0.1/24"),
235+
"127.0.0.1/24".parse::<IpNetwork>().unwrap()
236+
);
237+
assert_eq!(
238+
parse_cidr_block("192.168.0.1/31"),
239+
"192.168.0.1/31".parse::<IpNetwork>().unwrap()
247240
);
248241
}
249242

250243
#[test]
251244
#[should_panic]
252245
fn parse_cidr_blocks_panics_when_host_ipv4_prefix_is_too_low() {
253-
parse_cidr_blocks(&["127.0.0.1/8".to_string()]);
246+
parse_cidr_block("127.0.0.1/8");
254247
}
255248

256249
#[test]
257250
#[should_panic]
258251
fn parse_cidr_blocks_panics_when_host_ipv6_prefix_is_too_low() {
259-
parse_cidr_blocks(&["2001:0db8:0123:4567:89ab:cdef:1234:5678/56".to_string()]);
252+
parse_cidr_block("2001:0db8:0123:4567:89ab:cdef:1234:5678/56");
260253
}
261254

262255
#[test]
263256
fn parse_ipv6_based_cidr_blocks() {
264-
let input = vec![
265-
"2002::1234:abcd:ffff:c0a8:101/64".to_string(),
266-
"2001:0db8:0123:4567:89ab:cdef:1234:5678/92".to_string(),
267-
];
268-
assert_eq!(2, parse_cidr_blocks(&input).len());
257+
assert_eq!(
258+
parse_cidr_block("2002::1234:abcd:ffff:c0a8:101/64"),
259+
"2002::1234:abcd:ffff:c0a8:101/64"
260+
.parse::<IpNetwork>()
261+
.unwrap()
262+
);
263+
assert_eq!(
264+
parse_cidr_block("2001:0db8:0123:4567:89ab:cdef:1234:5678/92"),
265+
"2001:0db8:0123:4567:89ab:cdef:1234:5678/92"
266+
.parse::<IpNetwork>()
267+
.unwrap()
268+
);
269269
}

0 commit comments

Comments
 (0)