Skip to content

Conversation

@ndbroadbent
Copy link

Summary

This PR fixes a long-standing issue where PUT requests could not properly handle multipart form data with files. PUT requests now correctly set Content-Type: multipart/form-data headers and encode form data identically to POST requests.

Problem

PUT requests with multipart form data (containing files) were not being form-encoded correctly:

  • No Content-Type: multipart/form-data header was set
  • File uploads in PUT requests failed or were malformed
  • PUT always used upload/read_callback approach regardless of form type
  • POST requests worked correctly, but PUT did not

Solution

Updated the Putable module to mirror Postable behavior:

  1. Check for multipart forms: Added form.multipart? detection
  2. Use correct libcurl API: Use httppost for multipart forms instead of always using upload/read_callback
  3. Preserve HTTP method: Set customrequest = 'PUT' to override libcurl's default POST behavior when using httppost
  4. Maintain backward compatibility: Non-multipart PUT requests continue to work as before

Changes

  • lib/ethon/easy/http/putable.rb: Updated set_form method to handle multipart forms
  • spec/ethon/easy/http/put_spec.rb: Added comprehensive tests for multipart PUT requests
  • Gemfile + spec/support/localhost_server.rb: Fixed test suite compatibility with modern Rack versions

Testing

All existing tests pass, plus new tests verify:

  • Multipart PUT requests use httppost instead of upload
  • Multipart forms are properly materialized
  • PUT method is preserved (not changed to POST)
  • multipart/form-data content type is sent correctly

Related Issues

Closes:

Related to:

This resolves a 10+ year old issue that affected Ruby HTTP clients generated by OpenAPI Generator and direct Typhoeus/Ethon usage.

ndbroadbent and others added 2 commits August 11, 2025 03:10
- Add rackup gem dependency for Ruby 3.0+
- Update localhost_server.rb to use Rackup::Handler instead of Rack::Handler
- Fixes test suite that was broken due to rack/webrick handler being moved to separate rackup gem

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
PUT requests now properly handle multipart form data with files, matching POST behavior:

- Check form.multipart? to detect multipart forms in Putable module
- Use httppost for multipart forms instead of always using upload/read_callback
- Set customrequest='PUT' to override libcurl's default POST method when using httppost
- Add comprehensive tests for multipart PUT requests

Fixes long-standing issue where PUT requests would not form-encode multipart data,
causing Content-Type header to be missing and files to be sent incorrectly.

Resolves typhoeus/typhoeus#389 and OpenAPITools/openapi-generator#3138

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

if Gem.ruby_version >= Gem::Version.new("3.0.0")
gem "webrick"
gem "rackup"
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think there is any reason to include rackup based on Ruby version. Rackup is needed when Rack 3+ is used.

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