Skip to content

Fix/artifact download contract - #309

Open
Mehrn0ush wants to merge 3 commits into
CycloneDX:mainfrom
Mehrn0ush:fix/artifact-download-contract
Open

Mehrn0ush wants to merge 3 commits into
CycloneDX:mainfrom
Mehrn0ush:fix/artifact-download-contract

Conversation

@Mehrn0ush

@Mehrn0ush Mehrn0ush commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Normative mediaType matching (case-insensitive type/subtype; case-insensitive parameter names; exact parameter values), Vary: Accept only when Accept drove content selection, and download response bodies modeled as */*.
  • Reproducible absolute Content-Location (API base + version + ?mediaType=) on content and signature downloads, including versioned responses.
  • If-None-Match + bodyless 304 on all four download operations; shall revalidate on latest; should emit ETag / shall honor when present on versioned; HEAD and redirect notes.

Closes #289.

Test plan

  • Spot-check all four download operations for If-None-Match, shared 304-not-modified, and Content-Location/Vary
  • Confirm content/signature response keys are */*
  • Confirm Go client generate + build with */*

…nd 304.

Closes CycloneDX#289.

Signed-off-by: Mehrn0ush <mehrnoush.vaseghi@gmail.com>
…tching.

Signed-off-by: Mehrn0ush <mehrnoush.vaseghi@gmail.com>

@taleodor taleodor left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this lands everything from #289 and the spec validates. Three things before merge.

1. Body media type does not match the summary. The summary says content download bodies are */*, but all four download responses still key on application/octet-stream, and the new description text says so. Please switch the four content keys to "*/*" with the existing binary schema. That is the truthful declaration, since the wire Content-Type is the format's mediaType, it also covers signatures where the server knows a more specific type, and it validates. If the Go generator cannot handle */*, keep octet-stream, state in the description that the key is a placeholder for the format's mediaType, and update the summary to match. Either way the summary and the spec should agree.

2. Fewer new components. Six are added; three are enough.

  • artifact-etag-required and signature-etag-required duplicate the existing ETag headers with required: true flipped, and they are the only response headers in the spec carrying that flag. Two definitions of the same header will drift. The "shall" already lives in the prose on the latest responses and operations, so please reference artifact-etag / signature-etag and drop the duplicates.
  • The two 304 responses differ only in which header refs they list. A single 304-not-modified with generic ETag, Cache-Control, Content-Location and Vary string headers, plus the existing "repeat from the would-be 200" prose, covers all four operations. The Vary line already says "when used on the corresponding 200".
  • if-none-match and artifact-vary-accept are referenced three or four times each and are fine as components.

3. The 304 responses reference the optional ETag header even for the latest operations where the 200 requires it. If the -required duplicates go per point 2. this resolves itself.

…ETags.

Signed-off-by: Mehrn0ush <mehrnoush.vaseghi@gmail.com>
@Mehrn0ush

Copy link
Copy Markdown
Contributor Author

Thanks @taleodor
done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Complete artifact download contract: negotiation, Content-Location, and 304

2 participants