Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multipart breaks requests without ParamPart/FilePart #1170

Open
mkroman opened this issue Jul 23, 2020 · 1 comment
Open

Multipart breaks requests without ParamPart/FilePart #1170

mkroman opened this issue Jul 23, 2020 · 1 comment
Labels
info Generic question on how to use Faraday

Comments

@mkroman
Copy link

mkroman commented Jul 23, 2020

Basic Info

  • Faraday Version: HEAD (1.0.1 @ 5acab36)
  • Ruby Version: 2.7.1p83

Issue description

When creating a Faraday instance with the multipart middleware, requests that don't contain a Faraday::ParamPart or Faraday::FilePart fails

I'd expect it to simply send a regular POST request.

This is the backtrace:

Traceback (most recent call last):
	18: from test.rb:15:in `<main>'
	17: from /home/…/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/bundler/gems/faraday-5acab3623994/lib/faraday/connection.rb:279:in `post'
	16: from /home/…/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/bundler/gems/faraday-5acab3623994/lib/faraday/connection.rb:492:in `run_request'
	15: from /home/…/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/bundler/gems/faraday-5acab3623994/lib/faraday/rack_builder.rb:154:in `build_response'
	14: from /home/…/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/bundler/gems/faraday-5acab3623994/lib/faraday/request/multipart.rb:30:in `call'
	13: from /home/…/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/bundler/gems/faraday-5acab3623994/lib/faraday/adapter/net_http.rb:68:in `call'
	12: from /home/…/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/bundler/gems/faraday-5acab3623994/lib/faraday/adapter.rb:61:in `connection'
	11: from /home/…/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/bundler/gems/faraday-5acab3623994/lib/faraday/adapter/net_http.rb:70:in `block in call'
	10: from /home/…/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/bundler/gems/faraday-5acab3623994/lib/faraday/adapter/net_http.rb:128:in `perform_request'
	 9: from /home/…/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/bundler/gems/faraday-5acab3623994/lib/faraday/adapter/net_http.rb:137:in `request_with_wrapped_block'
	 8: from /home/…/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/bundler/gems/faraday-5acab3623994/lib/faraday/adapter/net_http.rb:152:in `request_via_request_method'
	 7: from /home/…/.rbenv/versions/2.7.1/lib/ruby/2.7.0/net/http.rb:933:in `start'
	 6: from /home/…/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/bundler/gems/faraday-5acab3623994/lib/faraday/adapter/net_http.rb:158:in `block in request_via_request_method'
	 5: from /home/…/.rbenv/versions/2.7.1/lib/ruby/2.7.0/net/http.rb:1492:in `request'
	 4: from /home/…/.rbenv/versions/2.7.1/lib/ruby/2.7.0/net/http.rb:1519:in `transport_request'
	 3: from /home/…/.rbenv/versions/2.7.1/lib/ruby/2.7.0/net/http.rb:1519:in `catch'
	 2: from /home/…/.rbenv/versions/2.7.1/lib/ruby/2.7.0/net/http.rb:1521:in `block in transport_request'
	 1: from /home/…/.rbenv/versions/2.7.1/lib/ruby/2.7.0/net/http/generic_request.rb:123:in `exec'
/home/…/.rbenv/versions/2.7.1/lib/ruby/2.7.0/net/http/generic_request.rb:184:in `send_request_with_body': undefined method `bytesize' for {:username=>"admin", :password=>"password"}:Hash (NoMethodError)

Steps to reproduce

#!/usr/bin/env ruby
# frozen_string_literal: true

require 'faraday'

http = Faraday.new('http://localhost:8080') do |conn|
  conn.request :multipart
end

body = {
  username: 'admin',
  password: 'password'
}

http.post '/auth/login', body

If you add body[:something] = Faraday::ParamPart.new('abc', 'text/plain'), the issue is gone.

@iMacTia
Copy link
Member

iMacTia commented Jul 28, 2020

Hi @mkroman, you can't send a Hash as a request body, you need to either manually make it a string or have a middleware do that for you.

If the server you're trying to contact expects a x-www-form-urlencoded body, then add the url_encoded middleware, if it expects json, you can add the json middleware instead. These middleware can be added together with the multipart one and they will play nicely as per your expectation:

http = Faraday.new('http://localhost:8080') do |conn|
  conn.request :multipart
  conn.request :url_encoded # or :json
  conn.adapter :net_http # don't forget to put the adapter when you customise the connection
end

This should work as expected, please give it a try and let us know

@iMacTia iMacTia added the info Generic question on how to use Faraday label Jul 28, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
info Generic question on how to use Faraday
Projects
None yet
Development

No branches or pull requests

2 participants