mirror of
https://github.com/sigp/lighthouse.git
synced 2026-07-02 20:34:27 +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()
|
path.path_segments_mut()
|
||||||
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
|
.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("eth")
|
||||||
.push(&version.to_string());
|
.push(&version.to_string());
|
||||||
|
|
||||||
@@ -3232,6 +3235,7 @@ impl BeaconNodeHttpClient {
|
|||||||
|
|
||||||
path.path_segments_mut()
|
path.path_segments_mut()
|
||||||
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
|
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
|
||||||
|
.pop_if_empty()
|
||||||
.push("lighthouse")
|
.push("lighthouse")
|
||||||
.push("liveness");
|
.push("liveness");
|
||||||
|
|
||||||
@@ -3508,3 +3512,37 @@ impl BeaconNodeHttpClient {
|
|||||||
.await
|
.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