+3
Cargo.lock
+3
Cargo.lock
···
603
603
"axum-core",
604
604
"bytes",
605
605
"cookie",
606
+
"form_urlencoded",
606
607
"futures-util",
607
608
"headers",
608
609
"http",
···
612
613
"pin-project-lite",
613
614
"rustversion",
614
615
"serde",
616
+
"serde_html_form",
617
+
"serde_path_to_error",
615
618
"tower",
616
619
"tower-layer",
617
620
"tower-service",
+1
-1
constellation/Cargo.toml
+1
-1
constellation/Cargo.toml
···
8
8
anyhow = "1.0.95"
9
9
askama = { version = "0.12.1", features = ["serde-json"] }
10
10
axum = "0.8.1"
11
-
axum-extra = { version = "0.10.0", features = ["typed-header"] }
11
+
axum-extra = { version = "0.10.0", features = ["query", "typed-header"] }
12
12
axum-metrics = "0.2"
13
13
bincode = "1.3.3"
14
14
clap = { version = "4.5.26", features = ["derive"] }
+24
-7
constellation/src/server/mod.rs
+24
-7
constellation/src/server/mod.rs
···
238
238
collection: String,
239
239
path: String,
240
240
cursor: Option<OpaqueApiCursor>,
241
+
/// Filter links only from these DIDs
242
+
///
243
+
/// include multiple times to filter by multiple source DIDs
244
+
#[serde(default)]
245
+
did: Vec<String>,
246
+
/// [deprecated] Filter links only from these DIDs
247
+
///
248
+
/// format: comma-separated sequence of DIDs
249
+
///
250
+
/// errors: if `did` parameter is also present
251
+
///
252
+
/// deprecated: use `did`, which can be repeated multiple times
241
253
from_dids: Option<String>, // comma separated: gross
242
254
limit: Option<u64>,
243
255
// TODO: allow reverse (er, forward) order as well
···
256
268
}
257
269
fn get_links(
258
270
accept: ExtractAccept,
259
-
query: Query<GetLinkItemsQuery>,
271
+
query: axum_extra::extract::Query<GetLinkItemsQuery>, // supports multiple param occurrences
260
272
store: impl LinkReader,
261
273
) -> Result<impl IntoResponse, http::StatusCode> {
262
274
let until = query
···
271
283
return Err(http::StatusCode::BAD_REQUEST);
272
284
}
273
285
274
-
let filter_dids = &query
275
-
.from_dids
276
-
.clone()
277
-
.map(|comma_joined| HashSet::from_iter(comma_joined.split(',').map(|d| Did(d.to_string()))))
278
-
.unwrap_or_default();
286
+
let mut filter_dids: HashSet<Did> = HashSet::from_iter(query.did.iter().map(|d| Did(d.to_string())));
287
+
288
+
if let Some(comma_joined) = &query.from_dids {
289
+
if !filter_dids.is_empty() {
290
+
return Err(http::StatusCode::BAD_REQUEST);
291
+
}
292
+
for did in comma_joined.split(',') {
293
+
filter_dids.insert(Did(did.to_string()));
294
+
}
295
+
}
279
296
280
297
let paged = store
281
298
.get_links(
···
284
301
&query.path,
285
302
limit,
286
303
until,
287
-
filter_dids,
304
+
&filter_dids,
288
305
)
289
306
.map_err(|_| http::StatusCode::INTERNAL_SERVER_ERROR)?;
290
307