diff --git a/httparty.gemspec b/httparty.gemspec index 8c579f4..4cfdcac 100644 --- a/httparty.gemspec +++ b/httparty.gemspec @@ -16,6 +16,7 @@ Gem::Specification.new do |s| s.required_ruby_version = '>= 2.0.0' s.add_dependency 'multi_xml', ">= 0.5.2" + s.add_dependency('mime-types', "~> 3.0") # If this line is removed, all hard partying will cease. s.post_install_message = "When you HTTParty, you must party hard!" diff --git a/lib/httparty.rb b/lib/httparty.rb index 167d93f..f2ffcb5 100644 --- a/lib/httparty.rb +++ b/lib/httparty.rb @@ -4,6 +4,7 @@ require 'net/https' require 'uri' require 'zlib' require 'multi_xml' +require 'mime/types' require 'json' require 'csv' diff --git a/lib/httparty/request/body.rb b/lib/httparty/request/body.rb index 64892c9..c8637a7 100644 --- a/lib/httparty/request/body.rb +++ b/lib/httparty/request/body.rb @@ -35,9 +35,9 @@ module HTTParty memo += %(Content-Disposition: form-data; name="#{key}") # value.path is used to support ActionDispatch::Http::UploadedFile # https://github.com/jnunemaker/httparty/pull/585 - memo += %(; filename="#{determine_file_name(value)}") if file?(value) + memo += %(; filename="#{file_name(value)}") if file?(value) memo += "\r\n" - memo += "Content-Type: application/octet-stream\r\n" if file?(value) + memo += "Content-Type: #{content_type(value)}\r\n" if file?(value) memo += "\r\n" memo += file?(value) ? value.read : value.to_s memo += "\r\n" @@ -74,7 +74,13 @@ module HTTParty end end - def determine_file_name(object) + def content_type(object) + return object.content_type if object.respond_to?(:content_type) + mime = MIME::Types.type_for(file_name(object)) + mime.empty? ? 'application/octet-stream' : mime[0].content_type + end + + def file_name(object) object.respond_to?(:original_filename) ? object.original_filename : File.basename(object.path) end diff --git a/spec/httparty/request/body_spec.rb b/spec/httparty/request/body_spec.rb index f2e8faf..2a6470b 100644 --- a/spec/httparty/request/body_spec.rb +++ b/spec/httparty/request/body_spec.rb @@ -38,7 +38,7 @@ RSpec.describe HTTParty::Request::Body do end let(:expected_file_name) { 'tiny.gif' } let(:expected_file_contents) { "GIF89a\u0001\u0000\u0001\u0000\u0000\xFF\u0000,\u0000\u0000\u0000\u0000\u0001\u0000\u0001\u0000\u0000\u0002\u0000;" } - let(:expected_content_type) { 'application/octet-stream' } + let(:expected_content_type) { 'image/gif' } let(:multipart_params) do "--------------------------c772861a5109d5ef\r\n" \ "Content-Disposition: form-data; name=\"user[avatar]\"; filename=\"#{expected_file_name}\"\r\n" \