mirror of
https://github.com/sigp/lighthouse.git
synced 2026-06-30 11:24:31 +00:00
Fix checkpoint sync 401 with trailing-slash path-embedded API keys (#9548)
Closes #9545 `BeaconNodeHttpClient::eth_path` clones the configured server URL and pushes path segments onto it. When the base URL ends with a slash (such as a QuickNode-style endpoint that embeds the API key in the path, `https://<host>/<api-key>/`), the URL already carries an empty trailing segment, so pushing `eth` yields a double slash: ``` https://<host>/<api-key>//eth/v2/debug/beacon/states/finalized ``` The provider responds to the `//` form with a `307` redirect to a normalized path that drops the key segment, so the redirected request arrives unauthenticated and checkpoint sync fails with `Error loading checkpoint state from remote: StatusCode(401)`. This PR calls `pop_if_empty()` before pushing segments, the standard `url`-crate idiom for trailing-slash-tolerant joining, so a trailing slash no longer changes the resulting path. The fix is applied in `eth_path` (the shared prefix builder that every `/eth/vX` endpoint derives from) and in `post_lighthouse_liveness`, the only other builder that extends the base URL directly. Co-Authored-By: rahulbarman <itsrahulbarman1@gmail.com>
This commit is contained in:
@@ -208,6 +208,9 @@ impl BeaconNodeHttpClient {
|
||||
|
||||
path.path_segments_mut()
|
||||
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
|
||||
// Drop a trailing empty segment so a base URL with a trailing slash
|
||||
// (e.g. `https://host/<api-key>/`) does not produce a double slash.
|
||||
.pop_if_empty()
|
||||
.push("eth")
|
||||
.push(&version.to_string());
|
||||
|
||||
@@ -3232,6 +3235,7 @@ impl BeaconNodeHttpClient {
|
||||
|
||||
path.path_segments_mut()
|
||||
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
|
||||
.pop_if_empty()
|
||||
.push("lighthouse")
|
||||
.push("liveness");
|
||||
|
||||
@@ -3508,3 +3512,37 @@ impl BeaconNodeHttpClient {
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::time::Duration;
|
||||
|
||||
fn eth_v2_prefix(base: &str) -> String {
|
||||
let server = SensitiveUrl::parse(base).expect("valid base url");
|
||||
let client = BeaconNodeHttpClient::new(server, Timeouts::set_all(Duration::from_secs(1)));
|
||||
client.eth_path(V2).unwrap().to_string()
|
||||
}
|
||||
|
||||
// A trailing slash on the base URL must not change the resulting endpoint
|
||||
// path. With a path-embedded API key this previously produced a `//eth`
|
||||
// double slash that providers redirect to a key-less, unauthenticated path.
|
||||
// See https://github.com/sigp/lighthouse/issues/9545.
|
||||
#[test]
|
||||
fn eth_path_is_trailing_slash_tolerant() {
|
||||
// The reported case: a path-embedded API key with a trailing slash.
|
||||
assert_eq!(
|
||||
eth_v2_prefix("https://example.com/secret-key/"),
|
||||
"https://example.com/secret-key/eth/v2"
|
||||
);
|
||||
assert_eq!(
|
||||
eth_v2_prefix("https://example.com/secret-key/"),
|
||||
eth_v2_prefix("https://example.com/secret-key")
|
||||
);
|
||||
// Regression guard: a bare host with a trailing slash.
|
||||
assert_eq!(
|
||||
eth_v2_prefix("http://localhost:5052/"),
|
||||
eth_v2_prefix("http://localhost:5052")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user