Skip to content

fix(client): accept xlsx workbooks mislabeled as JSON via ZIP magic sniff - #414

Merged
benbenbang merged 3 commits into
mainfrom
fix/411-xlsx-content-type
Oct 4, 2026
Merged

benbenbang merged 3 commits into
mainfrom
fix/411-xlsx-content-type

Conversation

@benbenbang

Copy link
Copy Markdown
Member

FMP serves real XLSX workbooks under an application/json content type (#411), which the strict content-type contract rejected, causing valid responses to fail. Binary endpoints now accept a body based on its actual signature rather than its declared media type, while keeping error diagnostics free of raw payload bytes.

  • Sniff the ZIP magic bytes (PK\x03\x04) on binary endpoints and accept a matching body under any content type, keeping the content type as received.
  • Preserve provider-message handling: a JSON error object on a binary endpoint is surfaced as a provider message rather than decoded as a workbook, and JSON endpoints are never sniffed for workbook signatures.
  • Summarise rejected or undecodable binary bodies as a byte count and content type instead of echoing raw bytes, preventing private payloads from leaking into error output.
  • Apply the same behaviour across the Rust client and the Go SDK, with tests covering the sniffing, provider-message, and error-summary paths.
  • Record the relaxed content-type policy in a new ADR, cross-reference it from the shared wire-types ADR, and update the example comment to match.

Closes #411

FMP has labeled real workbooks as JSON (#411), causing getBinary to
reject valid responses whose content type did not match the expected
media types. Accept a body when it opens with the signature of one of
the expected types, sniffing the ZIP magic bytes for xlsx and zip
media types. JSON endpoints are never sniffed, so workbook signatures
on JSON responses still fail as before.

A JSON-labeled provider message keeps its provider-message error; every
other rejected binary body is now summarized as a byte count and
content type rather than echoed, preventing private payload bytes from
leaking into error diagnostics.
FMP serves real XLSX workbooks under `application/json` (#411), which the
strict content-type contract rejected. Binary endpoints now sniff the ZIP
magic `PK\x03\x04` and accept a matching body under any content type,
keeping the content type as received.

The provider-message check still runs first, so a JSON error object such
as `{"Error Message":...}` served on a binary endpoint is surfaced as a
provider message rather than decoded as a workbook.

Decode errors on binary endpoints now summarize the body as
`<binary body omitted: N bytes, content-type ...>` so raw payload bytes
never reach a diagnostic. JSON endpoints never sniff workbook signatures.
…ries

Document the #411 change where FMP serves the real XLSX workbook under a
JSON content type. The SDK now accepts a successful body that starts with
the magic bytes of an expected format (XLSX and the ZIP family
`PK\x03\x04`) regardless of its declared media type, keeping the content
type exactly as received. `Content-Disposition` is not used for the
decision and `application/octet-stream` is never sniffed.

Record that every other error on a binary endpoint summarises the body
(`<binary body omitted: N bytes, ...>`) instead of echoing raw bytes, and
update the example comment to match. ADR 0002 cross-references ADR 0008 for
the relaxed content-type policy.

close #411
@benbenbang
benbenbang enabled auto-merge (rebase) October 4, 2026 03:06
@github-actions github-actions Bot added documentation Improvements or additions to documentation enhancement New feature or request labels Oct 4, 2026
@benbenbang
benbenbang merged commit 2f48e9d into main Oct 4, 2026
10 checks passed
@benbenbang
benbenbang deleted the fix/411-xlsx-content-type branch October 4, 2026 03:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: financial-reports-xlsx fails because FMP sends the workbook as application/json

1 participant