fix content type error on android

This commit is contained in:
Oleksii Bulenok
2026-08-04 19:09:50 +02:00
parent 1b2ec14ffd
commit 0e9c186d4f
2 changed files with 120 additions and 1 deletions
+30
View File
@@ -24,3 +24,33 @@ import.
Can be removed if Expo stops referencing `./react-native-web` from the types
loaded by the native winter runtime, or guards the augmentation to web.
## src/winter/fetch/RequestUtils.ts + fetch.ts - Blob body must not clobber an explicit Content-Type
Expo 57 installs `expo/fetch` as the global `fetch` on native
(`src/winter/runtime.native.ts`), replacing React Native's whatwg-fetch. When
the request body is a Blob, `normalizeBodyInitAsync` returned
`overriddenHeaders: [['Content-Type', blob.type]]`, which `fetch.ts` applied
*over* the caller's headers (introduced in expo/expo#33405). This is backwards
per the fetch spec: a blob's type is only a default, used when no Content-Type
was provided, and an empty type must contribute no header at all.
In this app it broke publishing posts with any image blob on Android. The
composer uploads via `agent.uploadBlob(blob, {encoding})`; `@atproto/xrpc`
sets `content-type: <mime>` explicitly, but the blob comes from an XHR
`file://` read of a `.bin`-renamed jpeg (the RN#27099 workaround in
`src/lib/api/upload-blob.ts`), for which Android's BlobModule returns an empty
mime. expo/fetch replaced the good header with the empty blob type and the PDS
rejected the upload with "Request encoding (Content-Type) required but not
provided". Also silently rewrote the intended mime on every other blob upload
(avatars, banners, caption files) even when the blob type was non-empty.
The patch splits body-derived headers into two channels: FormData keeps
`overriddenHeaders` (its boundary header must win), while the Blob branch
returns new `fallbackHeaders` (skipped entirely when `blob.type` is empty)
that `fetch.ts` applies via `fillMissingHeaders` only for header keys the
caller did not set. This matches browser behavior.
Upstream: expo/expo#33405 introduced the override; the SDK 58 Request rewrite
(expo/expo#46630) is expected to make this spec-compliant, so re-evaluate on
the next SDK bump. Worth filing an issue against expo/expo referencing this.