mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-17 22:18:14 -07:00
global: fixes
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
use aide::OperationInput;
|
||||
use axum::{extract::FromRequestParts, http::request::Parts};
|
||||
|
||||
use crate::Error;
|
||||
|
||||
/// Extractor that rejects requests carrying any query string.
|
||||
/// Used on path-only endpoints to prevent cache-busting via injected
|
||||
/// query params (the cache key includes the URI).
|
||||
pub struct Empty;
|
||||
|
||||
impl<S> FromRequestParts<S> for Empty
|
||||
where
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Rejection = Error;
|
||||
|
||||
async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {
|
||||
match parts.uri.query() {
|
||||
Some(q) if !q.is_empty() => Err(Error::bad_request(format!(
|
||||
"this endpoint does not accept query parameters (got `?{q}`)"
|
||||
))),
|
||||
_ => Ok(Empty),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl OperationInput for Empty {}
|
||||
@@ -4,6 +4,7 @@ mod block_count_param;
|
||||
mod blockhash_param;
|
||||
mod blockhash_start_index;
|
||||
mod blockhash_tx_index;
|
||||
mod empty;
|
||||
mod height_param;
|
||||
mod pool_slug_param;
|
||||
mod series_param;
|
||||
@@ -22,6 +23,7 @@ pub use block_count_param::*;
|
||||
pub use blockhash_param::*;
|
||||
pub use blockhash_start_index::*;
|
||||
pub use blockhash_tx_index::*;
|
||||
pub use empty::*;
|
||||
pub use height_param::*;
|
||||
pub use pool_slug_param::*;
|
||||
pub use series_param::*;
|
||||
|
||||
@@ -13,19 +13,25 @@ pub struct TxidsParam {
|
||||
|
||||
impl TxidsParam {
|
||||
/// Parsed manually from URI since serde_urlencoded doesn't support repeated keys.
|
||||
pub fn from_query(query: &str) -> Self {
|
||||
Self {
|
||||
txids: query
|
||||
.split('&')
|
||||
.filter_map(|pair| {
|
||||
let (key, val) = pair.split_once('=')?;
|
||||
if key == "txId[]" || key == "txId%5B%5D" {
|
||||
Txid::from_str(val).ok()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
/// Rejects unknown keys to prevent cache-busting via injected query params.
|
||||
pub fn from_query(query: &str) -> Result<Self, String> {
|
||||
if query.is_empty() {
|
||||
return Ok(Self { txids: Vec::new() });
|
||||
}
|
||||
let mut txids = Vec::new();
|
||||
for pair in query.split('&') {
|
||||
let (key, val) = pair.split_once('=').ok_or_else(|| {
|
||||
format!("malformed query parameter `{pair}`, expected `txId[]=<txid>`")
|
||||
})?;
|
||||
if key == "txId[]" || key == "txId%5B%5D" {
|
||||
let txid = Txid::from_str(val).map_err(|e| format!("invalid txid `{val}`: {e}"))?;
|
||||
txids.push(txid);
|
||||
} else {
|
||||
return Err(format!(
|
||||
"unknown query parameter `{key}`, expected `txId[]`"
|
||||
));
|
||||
}
|
||||
}
|
||||
Ok(Self { txids })
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user