Skip to content

Feat/binary Add opt-in byte-preserving binary APPEND to legacy socket - #58

Merged
ralflang merged 3 commits into
horde:FRAMEWORK_6_0from
neuhaus:feat/binary-append
Nov 2, 2026
Merged

ralflang merged 3 commits into
horde:FRAMEWORK_6_0from
neuhaus:feat/binary-append

Conversation

@neuhaus

@neuhaus neuhaus commented Oct 24, 2026

Copy link
Copy Markdown
Contributor

The legacy socket APPEND implementation normalizes line endings throughout the message, which can alter binary MIME payloads.

This adds a per-message binary option:

$client->append('Objects', [
    ['data' => $messageStream, 'binary' => true],
]);

When enabled, the client preserves bytes, requires the server’s BINARY capability, and sends a literal8 (~{n}). Server rejection does not trigger a fallback to ordinary APPEND. CATENATE inputs are assembled locally because RFC 4469 TEXT parts do not permit literal8.

Callers must supply a valid MIME message with CRLF headers and appropriate content-transfer-encoding. Existing behavior remains unchanged when the option is omitted or false. The modern namespaced API is unchanged.

Validation

  • 13 regression tests cover strings, streams, byte preservation, wire output, capability checks, batching, and rejection handling.
  • Full unit suite: 1,634 tests, no failures or errors; 55 skipped, two incomplete, and one unrelated PHP 8.5 deprecation.
  • Live APPEND/BINARY FETCH round trips against Dovecot verified exact length and SHA-256 for 1 MiB and 512 MiB payloads.
  • The 512 MiB round trip completed under a 64 MiB PHP memory limit, with 10 MiB peak PHP memory.

Protocol references

@what-the-diff

what-the-diff Bot commented Oct 24, 2026

Copy link
Copy Markdown

PR Summary

  • Adds opt-in support for byte-preserving binary APPEND uploads. Messages marked for binary upload retain their original bytes, including line endings, instead of being altered during upload.
  • Protects uploads from unsupported or unsafe fallbacks. The client checks that the server supports the required capability before sending a batch and won’t retry a failed binary upload as a standard APPEND, which could change message contents.
  • Documents how to use binary APPEND. The documentation explains message requirements, server support, stream handling, and how failures and retries are handled.
  • Adds test coverage for binary uploads. Tests verify byte preservation, server capability checks, batch behavior, and that existing standard APPEND behavior remains unchanged.

@ralflang ralflang left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I need to ensure after merging there is a feature parity for the src/ branch.

@ralflang
ralflang merged commit d5ac1f0 into horde:FRAMEWORK_6_0 Nov 2, 2026
1 check passed
@neuhaus
neuhaus deleted the feat/binary-append branch November 2, 2026 07:01
ralflang added a commit that referenced this pull request Nov 3, 2026
…o spec

- Validates the BINARY capability (batch-wide, before any send)
- Rejects a url part combined with binary (CapabilityNotSupportedException (RFC 4469).
- Concatenates the TEXT parts locally into one php://temp stream and sends it as a single literal8 via ImapWireStream(forceBinary: true)
- Updated the docblock

This is informed by lib/ PR #58
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.

2 participants