Skip to content
Snippets Groups Projects
Commit 48e23f20 authored by Maksim Kaitmazian's avatar Maksim Kaitmazian
Browse files

refactor: allow default ports to be listened on by other protocols

Previously, using a default port for another protocol would result in an
error like the following
```
error: Invalid value "localhost:8080" for '--pg-listen <[HOST][:PORT]>': PGPROTO cannot listen on port 8080 because it is default port for HTTP
```

This commit allows default ports to be used by other protocols,
as long as the port is not already occupied.

Close #1254
parent 08a9d0a8
No related branches found
No related tags found
No related merge requests found
Pipeline #59365 passed
......@@ -57,21 +57,9 @@ impl IprotoAddress {
};
let (host, port) = match host_port.rsplit_once(':') {
Some((host, port)) => {
if host.contains(':') {
if host.contains(':') || port.is_empty() {
return format_err();
}
if port.is_empty() {
return format_err();
}
if port == DEFAULT_HTTP_PORT {
return Err(format!(
"IPROTO cannot listen on port {DEFAULT_HTTP_PORT} because it is default port for HTTP"
));
} else if port == DEFAULT_PGPROTO_PORT {
return Err(format!(
"IPROTO cannot listen on port {DEFAULT_PGPROTO_PORT} because it is default port for PGPROTO"
));
}
let host = if host.is_empty() { None } else { Some(host) };
(host, Some(port))
}
......@@ -161,21 +149,9 @@ impl HttpAddress {
let format_err = || Err("valid format: [host][:port]".to_string());
let (host, port) = match addr.rsplit_once(':') {
Some((host, port)) => {
if host.contains(':') {
if host.contains(':') || port.is_empty() {
return format_err();
}
if port.is_empty() {
return format_err();
}
if port == DEFAULT_IPROTO_PORT {
return Err(format!(
"HTTP cannot listen on port {DEFAULT_IPROTO_PORT} because it is default port for IPROTO"
));
} else if port == DEFAULT_PGPROTO_PORT {
return Err(format!(
"HTTP cannot listen on port {DEFAULT_PGPROTO_PORT} because it is default port for PGPROTO"
));
}
let host = if host.is_empty() { None } else { Some(host) };
(host, Some(port))
}
......@@ -260,21 +236,9 @@ impl PgprotoAddress {
let format_err = || Err("valid format: [host][:port]".to_string());
let (host, port) = match addr.rsplit_once(':') {
Some((host, port)) => {
if host.contains(':') {
if host.contains(':') || port.is_empty() {
return format_err();
}
if port.is_empty() {
return format_err();
}
if port == DEFAULT_IPROTO_PORT {
return Err(format!(
"PGPROTO cannot listen on port {DEFAULT_IPROTO_PORT} because it is default port for IPROTO"
));
} else if port == DEFAULT_HTTP_PORT {
return Err(format!(
"PGPROTO cannot listen on port {DEFAULT_HTTP_PORT} because it is default port for HTTP"
));
}
let host = if host.is_empty() { None } else { Some(host) };
(host, Some(port))
}
......@@ -430,37 +394,19 @@ mod tests {
//
let iproto_conflict_with_http = format!("host:{DEFAULT_HTTP_PORT}");
assert_eq!(
iproto_conflict_with_http.parse::<IprotoAddress>().unwrap_err(),
format!("IPROTO cannot listen on port {DEFAULT_HTTP_PORT} because it is default port for HTTP")
);
assert!(iproto_conflict_with_http.parse::<IprotoAddress>().is_ok(),);
let iproto_conflict_with_pg = format!("host:{DEFAULT_PGPROTO_PORT}");
assert_eq!(
iproto_conflict_with_pg.parse::<IprotoAddress>().unwrap_err(),
format!("IPROTO cannot listen on port {DEFAULT_PGPROTO_PORT} because it is default port for PGPROTO")
);
assert!(iproto_conflict_with_pg.parse::<IprotoAddress>().is_ok());
let http_conflict_with_iproto = format!("host:{DEFAULT_IPROTO_PORT}");
assert_eq!(
http_conflict_with_iproto.parse::<HttpAddress>().unwrap_err(),
format!("HTTP cannot listen on port {DEFAULT_IPROTO_PORT} because it is default port for IPROTO")
);
assert!(http_conflict_with_iproto.parse::<HttpAddress>().is_ok(),);
let http_conflict_with_pg = format!("host:{DEFAULT_PGPROTO_PORT}");
assert_eq!(
http_conflict_with_pg.parse::<HttpAddress>().unwrap_err(),
format!("HTTP cannot listen on port {DEFAULT_PGPROTO_PORT} because it is default port for PGPROTO")
);
assert!(http_conflict_with_pg.parse::<HttpAddress>().is_ok(),);
let pg_conflict_with_iproto = format!("host:{DEFAULT_IPROTO_PORT}");
assert_eq!(
pg_conflict_with_iproto.parse::<PgprotoAddress>().unwrap_err(),
format!("PGPROTO cannot listen on port {DEFAULT_IPROTO_PORT} because it is default port for IPROTO")
);
assert!(pg_conflict_with_iproto.parse::<PgprotoAddress>().is_ok(),);
let pg_conflict_with_http = format!("host:{DEFAULT_HTTP_PORT}");
assert_eq!(
pg_conflict_with_http.parse::<PgprotoAddress>().unwrap_err(),
format!("PGPROTO cannot listen on port {DEFAULT_HTTP_PORT} because it is default port for HTTP")
);
assert!(pg_conflict_with_http.parse::<PgprotoAddress>().is_ok(),);
//
// check correctness of default values to avoid human factor
......
......@@ -171,14 +171,10 @@ class PortDistributor:
def __init__(self, start: int, end: int) -> None:
self.gen = iter(range(start, end))
def get(self, pg: bool = False) -> int:
def get(self) -> int:
for port in self.gen:
if can_bind(port):
if not pg:
return port
if pg and port != HTTP_DEFAULT_PORT and port != IPROTO_DEFAULT_PORT:
return port
return port
raise Exception(
"No more free ports left in configured range, consider enlarging it"
......@@ -1824,9 +1820,9 @@ class Cluster:
# of a pgproto port at the config stage, we have to
# pass them manually and check it's correctness
if pg_port is None:
pg_port = self.port_distributor.get(pg=True)
pg_port = self.port_distributor.get()
if bootstrap_port == pg_port or port == pg_port:
pg_port = self.port_distributor.get(pg=True)
pg_port = self.port_distributor.get()
instance = Instance(
binary_path=self.binary_path,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment