Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## v4.3.0

- Added `get_repository_versions_data`, `get_package_data`,

## v4.2.0 - 2025-08-27

- `Version`'s serde deserializer can now work with `String` as well as `str`.
Expand Down
42 changes: 38 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,14 @@ pub fn unretire_release_response(response: http::Response<Vec<u8>>) -> Result<()

/// Create a request that get the names and versions of all of the packages on
/// the package registry.
///
/// Uses the registry v2 API.
/// Responses use gz encoding and are wrapped in a signing message.
/// For direct usage of response see below:
///
/// https://github.com/hexpm/specifications/blob/main/registry-v2.md
/// Recommended sections: (#registry-files, #signing, #decoding-registry-files)
///
/// TODO: Where are the API docs for this?
pub fn get_repository_versions_request(
api_key: Option<&str>,
Expand All @@ -256,9 +264,8 @@ pub fn get_repository_versions_request(
.expect("get_repository_versions_request request")
}

/// Parse a request that get the names and versions of all of the packages on
/// Parse a request that gets the names and versions of all of the packages on
/// the package registry.
///
pub fn get_repository_versions_response(
response: http::Response<Vec<u8>>,
public_key: &[u8],
Expand All @@ -274,7 +281,15 @@ pub fn get_repository_versions_response(
let mut body = Vec::new();
decoder.read_to_end(&mut body)?;

let signed = Signed::decode(body.as_slice())?;
parse_repository_v2_versions(&body, public_key)
}

/// Parse a signed binary message containing all of the packages on the package registry.
pub fn parse_repository_v2_versions(
protobuf_bytes: &Vec<u8>,
public_key: &[u8],
) -> Result<HashMap<String, Vec<Version>>, ApiError> {
let signed = Signed::decode(protobuf_bytes.as_slice())?;

let payload =
verify_payload(signed, public_key).map_err(|_| ApiError::IncorrectPayloadSignature)?;
Expand All @@ -301,6 +316,13 @@ pub fn get_repository_versions_response(

/// Create a request to get the information for a package in the repository.
///
/// Uses the registry v2 API.
/// Responses use gz encoding and are wrapped in a signing message.
/// For direct usage of response see below:
///
/// https://github.com/hexpm/specifications/blob/main/registry-v2.md
/// Recommended sections: (#registry-files, #signing, #decoding-registry-files)
///
/// API Docs:
///
/// https://github.com/hexpm/hex/blob/main/lib/mix/tasks/hex.package.ex#L348
Expand Down Expand Up @@ -339,7 +361,15 @@ pub fn get_package_response(
let mut body = Vec::new();
decoder.read_to_end(&mut body)?;

let signed = Signed::decode(body.as_slice())?;
parse_repository_v2_package(&body, public_key)
}

/// Parse a signed binary message containing the information for a package in the repository.
pub fn parse_repository_v2_package(
protobuf_bytes: &Vec<u8>,
public_key: &[u8],
) -> Result<Package, ApiError> {
let signed = Signed::decode(protobuf_bytes.as_slice())?;

let payload =
verify_payload(signed, public_key).map_err(|_| ApiError::IncorrectPayloadSignature)?;
Expand Down Expand Up @@ -739,6 +769,10 @@ impl ApiError {
pub fn is_not_found(&self) -> bool {
matches!(self, Self::NotFound)
}

pub fn is_invalid_protobuf(&self) -> bool {
matches!(self, Self::InvalidProtobuf(_))
}
}

/// Read a body and ensure it has the given sha256 digest.
Expand Down
Loading
Loading