Skip to content

Instantly share code, notes, and snippets.

@did
Created March 25, 2013 00:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save did/5234265 to your computer and use it in GitHub Desktop.
Save did/5234265 to your computer and use it in GitHub Desktop.
Make Webmock and Httmultparty a happy family (https://github.com/bblimke/webmock/issues/262). It's a dirty monkey patch I'm not ashamed of, mainly because it's only used for tests. Just add the file in your spec/support folder of your app.
require 'webmock'
require 'httmultiparty'
class FakeUploadIO
attr_accessor :original_filename, :content_type, :body
def initialize(io)
io.rewind # make sure....
self.original_filename = io.original_filename || File.basename(io.local_path)
self.content_type = io.content_type
self.body = io.read
io.rewind # ...we don't mess up with the io
end
end
module WebMock
module NetHTTPUtility
def self.request_signature_from_request(net_http, request, body = nil)
protocol = net_http.use_ssl? ? "https" : "http"
path = request.path
path = WebMock::Util::URI.heuristic_parse(request.path).request_uri if request.path =~ /^http/
if request["authorization"] =~ /^Basic /
userinfo = WebMock::Util::Headers.decode_userinfo_from_header(request["authorization"])
userinfo = WebMock::Util::URI.encode_unsafe_chars_in_userinfo(userinfo) + "@"
else
userinfo = ""
end
uri = "#{protocol}://#{userinfo}#{net_http.address}:#{net_http.port}#{path}"
method = request.method.downcase.to_sym
headers = Hash[*request.to_hash.map {|k,v| [k, v]}.inject([]) {|r,x| r + x}]
headers.reject! {|k,v| k =~ /[Aa]uthorization/ && v.first =~ /^Basic / } #we added it to url userinfo
# changes happen here
if body != nil && body.respond_to?(:read)
request.set_body_internal body.read
else
request.set_body_internal body
end
_body = request.respond_to?(:body_footprint) ? request.body_footprint : request.body
WebMock::RequestSignature.new(method, uri, :body => _body, :headers => headers)
end
end
end
module HTTMultiParty::Multipartable::Webmock
def body_footprint
return self.body if @_body.blank?
Marshal.dump(@_body.map do |key, _value|
_value = FakeUploadIO.new(_value) if _value.is_a?(UploadIO)
[key, _value]
end)
end
def body=(value)
if value.is_a?(Array)
@_body = value.dup # save it for later
super(value)
else
# does this case exist for real ? Never observed so far
puts "[httmultiparty] not an array !!! #{value.class}."
raise 'STOP'
end
end
end
class HTTMultiParty::MultipartPost < Net::HTTP::Post
include HTTMultiParty::Multipartable::Webmock
end
@jonmagic
Copy link

Thank you 👍 Just ran across this after beating my head against wall for a few hours. ❤️

@killpack
Copy link

❤️ ❤️ ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment