List all provenance graph hashes the remote holds. This mirrors the `.change` sync model: the server advertises a flat inventory of content-addressed objects, the client computes the delta by presence (`has_provenance_graph`), and pulls missing objects by hash via [`download_provenance`](Self::download_provenance). Deliberately NOT a per-change relationship query ("which provenance explains chan
(&self)
| 511 | /// |
| 512 | /// Base32-encoded provenance graph hashes, one per line, in server order. |
| 513 | pub async fn get_provenance_list(&self) -> RemoteResult<Vec<String>> { |
| 514 | let url = format!("{}?provenance-list", self.base_url); |
| 515 | debug!("GET provenance-list: {}", url); |
| 516 | |
| 517 | let response = self |
| 518 | .client |
| 519 | .get(&url) |
| 520 | .send() |
| 521 | .await |
| 522 | .map_err(|e| RemoteError::connection_failed(&url, e))?; |
| 523 | |
| 524 | crate::check_min_version_header(response.headers()); |
| 525 | let status = response.status(); |
| 526 | |
| 527 | match status { |
| 528 | StatusCode::OK => { |
| 529 | let text = response |
| 530 | .text() |
| 531 | .await |
| 532 | .map_err(|e| RemoteError::connection_failed(&url, e))?; |
| 533 | Ok(text |
| 534 | .lines() |
| 535 | .map(str::trim) |
| 536 | .filter(|line| !line.is_empty()) |
| 537 | .map(|line| line.to_string()) |
| 538 | .collect()) |
| 539 | } |
| 540 | StatusCode::NOT_FOUND => Ok(Vec::new()), |
| 541 | StatusCode::UNAUTHORIZED | StatusCode::FORBIDDEN => { |
| 542 | let msg = response.text().await.unwrap_or_default(); |
| 543 | Err(RemoteError::auth_failed(&url, msg)) |
| 544 | } |
| 545 | _ => { |
| 546 | let msg = response.text().await.unwrap_or_default(); |
| 547 | Err(RemoteError::http(status.as_u16(), msg)) |
| 548 | } |
| 549 | } |
| 550 | } |
| 551 | |
| 552 | /// Download a provenance graph from the remote server. |
| 553 | /// |