Serve a stored post's attachments as Documents, with their mime - #2172
Merged
Conversation
karlitschek
force-pushed
the
fix/attachment-media-type
branch
2 times, most recently
from
September 13, 2026 23:38
5aaefa2 to
95dcdf8
Compare
Every Social photo arrived on Pixelfed with no photo. Two halves to it: The stored row (`MediaAttachment::asLocal()`, what `StreamRequest::save()` writes) carried Mastodon's client entity, which has no mime, so a post read back from the database had `mediaType` '' on every attachment — and Pixelfed validates an attachment with `in_array($media['mediaType'], $allowed)`. Mastodon sniffs the URL and hid it. The row now carries `media_type`, `import()` reads it back, and a row from before it existed gets a guess from the extension (or the commonest type of its kind) rather than nothing. And `Stream::jsonSerialize()` handed the hydrated attachment objects straight through under `attachment`, in whatever export format they were in — the local one, after hydration — so a re-served post carried Mastodon's client shape under an ActivityPub key. It maps every attachment through `asDocument()` now, so a post fetched by a peer goes out the same as the original `Create` did. Closes roadmap items 13 and 39 in docs/Mastodon-Compatibility.md. Signed-off-by: Frank Karlitschek <frank@nextcloud.com> Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Frank Karlitschek <frank@nextcloud.com> Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
karlitschek
force-pushed
the
fix/attachment-media-type
branch
from
September 13, 2026 23:38
95dcdf8 to
ca94876
Compare
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Item 6 of the fresh look: every Social photo arrived on Pixelfed with no photo. Pixelfed validates an attachment with
in_array($media['mediaType'], $allowed); Mastodon sniffs the URL and hid the bug for weeks.Two halves, both in the re-read path (the original
Createwas already right — roadmap #39 said so):StreamRequest::save()writesMediaAttachment::asLocal(), Mastodon's client entity, which has no mime;import()hydrated it back withmediaType = ''. The row now carriesmedia_type(this app's own key — a Mastodon client ignores it),import()reads it back, and a row from before the key existed gets a guess from the file extension, or the commonest type of its kind (image/jpeg,video/mp4,audio/mpeg), rather than an empty string Pixelfed refuses.Stream::jsonSerialize()handed the hydratedMediaAttachmentobjects straight through asattachment, in whatever export format they were in — the local one, after hydration. It now maps every attachment throughasDocument(), so a post fetched by a peer (single status, outbox,featured,replies) goes out as{"type": "Document", "mediaType": "image/png", "name": …}exactly like the originalCreate.Roadmap items 13 and 39 in
docs/Mastodon-Compatibility.mdare marked done;docs/API.mddocuments the extramedia_typekey.Verification
StreamTest::testAHydratedPostServesItsAttachmentsAsDocuments(local-format attachments →DocumentwithmediaTypewhen the post is exported as ActivityPub, and noattachmentkey in the client format).WireCompatibilityTestcovers the inbound side only.Version 0.19.36.
🤖 Generated with Claude Code