Skip to content

Conversation

@AaronDDM
Copy link
Contributor

@AaronDDM AaronDDM commented Jun 24, 2025

Description

Reported in issue #528 - see a similar issue reported here jnunemaker/httparty#671

Fixes: Encoding::CompatibilityError when sending multipart requests with UTF-8 content
Closes: #528

https://nylas.atlassian.net/browse/TW-3983

License

I confirm that this contribution is made under the terms of the MIT license and that I have the authority necessary to make this contribution on behalf of its copyright owner.

@AaronDDM AaronDDM requested review from ajay-k and kraju3 June 24, 2025 18:49
@AaronDDM AaronDDM self-assigned this Jun 24, 2025
@AaronDDM AaronDDM changed the title fix(fileutils): resolve UTF-8 encoding incompatibility in multipart form data fix(http_client): resolve UTF-8 encoding incompatibility in multipart form data Jun 24, 2025
@AaronDDM AaronDDM changed the title fix(http_client): resolve UTF-8 encoding incompatibility in multipart form data fix(http-client): replace Tempfile with StringIO for multipart uploads Jul 3, 2025
@playerzero-ai
Copy link

playerzero-ai bot commented Jul 3, 2025

Pull Request Summary

The pull request introduces several enhancements and fixes to improve file handling, error management, and multipart upload functionality in the Nylas Ruby SDK. Key changes include:

  • File Handling Improvements:

    • Replaced Tempfile with StringIO for handling multipart uploads to improve reliability and compatibility.
    • Updated file closing logic to ensure only file objects that support the close method are closed.
  • Error Handling and Logging Enhancements:

    • Enhanced error logging with detailed information, including HTTP response details and stack traces.
    • Improved error handling for loading environment variables and file operations.
  • Multipart Upload Enhancements:

    • Introduced methods to handle multipart payloads, ensuring proper encoding and conversion of binary content to StringIO.
    • Improved detection and handling of binary content attachments in multipart requests.
  • Testing and Demonstration Scripts:

    • Added scripts to demonstrate file upload functionality, including handling of small and large attachments.
    • Included tests for UTF-8 encoding compatibility and multipart request handling.
  • HTTP Client Enhancements:

    • Added methods to normalize JSON encodings and prepare multipart payloads for HTTParty compatibility.
    • Enhanced the file_upload? method to accurately detect different types of file uploads.

These changes aim to enhance the SDK's reliability, compatibility, and user experience when dealing with file uploads and multipart requests, particularly focusing on error management and internationalization support.

Functional Tests

  • Verify that files can be uploaded using StringIO for multipart requests and that the upload process completes successfully.
  • Test that only file objects supporting the 'close' method are closed after sending a message, ensuring no errors occur during file handling.
  • Check that binary content attachments are correctly detected and handled in multipart requests, ensuring compatibility with HTTParty.
  • Ensure that JSON payloads with special characters or emojis are UTF-8 encoded and transmitted correctly in messages.
  • Test the new example scripts for sending messages with small and large attachments, verifying that they execute without errors and log detailed information.
  • Verify that error logging provides detailed information, including HTTP response details and stack traces, during file uploads.
  • Ensure that environment variables are correctly loaded and errors are logged when they are missing or incorrect.
  • Test the multipart payload preparation method to ensure it normalizes string encodings and converts binary content to StringIO objects for HTTParty compatibility.
  • Check that temporary files created during multipart uploads are properly cleaned up after the request is processed.

Files Changed

File Name Summary
lib/nylas/resources/messages.rb Improved file closing by checking if file objects respond to close before closing during message sending.
examples/messages/file_upload_example.rb Added detailed error logging and handling for environment loading and file creation.
Implemented methods for creating/finding test files of various types and sizes with logging.
Added methods to send messages with different attachment types and detailed logging.
Included a test for a UTF-8 encoding bug with multipart/form-data.
Enhanced main flow with environment checks, client initialization, and cleanup.
examples/messages/send_attachments.rb New script demonstrating sending messages with small and large attachments.
Includes usage instructions, environment variable checks, and detailed error logging.
Showcases multipart form data handling for large files and overall file upload capabilities in Nylas SDK.
spec/nylas/handler/http_client_spec.rb Added stringio require.
Tests for detecting binary content attachments and multipart requests.
Implemented multipart payload preparation logic:
- Normalize message payload to ASCII-8BIT.
- Convert binary attachments to StringIO.
- Preserve non-message fields.
- Support multiple binary attachments.
Enhances HTTP client handling of binary file uploads and multipart requests.
spec/nylas/utils/file_utils_spec.rb Added test ensuring build_form_request produces UTF-8 JSON with original special characters.
Verifies compatibility with HTTParty and correct handling of international characters and emojis in messages.
lib/nylas/handler/http_client.rb Added normalize_json_encodings! to base64 encode binary attachment content in JSON payloads.
Introduced prepare_multipart_payload to normalize encodings and convert binary attachments to StringIO for HTTParty multipart compatibility.
Modified file_upload? to detect both traditional and multipart uploads.
Updated httparty_execute to use multipart payload preparation for file uploads, improving multipart request reliability.

View more in PlayerZero
updated: Jul 14 @ 02:54 PM UTC

- Replace Tempfile with StringIO in prepare_multipart_payload to eliminate filesystem dependencies
- Add enhanced StringIO compatibility methods for HTTParty multipart handling
- Update test expectations from Tempfile to StringIO
- Add defensive file closing in messages.rb
- Resolves issues with read-only containers and AWS Lambda environments

Fixes #528
…multipart requests

Fixes #528

- Resolves 'incompatible character encodings: ASCII-8BIT and UTF-8' error when sending multipart requests
- Normalizes all multipart payload strings to consistent ASCII-8BIT encoding for HTTParty compatibility
- Maintains backward compatibility while preventing encoding conflicts during multipart body generation
- Updates test expectations to reflect new encoding behavior
…lization

- Add normalize_json_encodings! method to handle binary attachment content
- Automatically base64 encode binary strings before JSON serialization
- Fixes 'source sequence is illegal/malformed utf-8' error when sending
  attachments with raw binary content via JSON (non-multipart) requests
- Preserves backward compatibility with both symbol and string keys
- Resolves issue #528
@AaronDDM AaronDDM changed the title fix(http-client): replace Tempfile with StringIO for multipart uploads Added support for string-content attachments & fixed HTTParty encoding issues. Jul 14, 2025
Copy link

@ajay-k ajay-k left a comment

Choose a reason for hiding this comment

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

LGTM 👍

@AaronDDM AaronDDM merged commit 4040ad7 into main Jul 18, 2025
6 checks passed
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.

Encoding issues encountered while trying to send multi-part emails

3 participants