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

Fix multipart to set its header even when other headers are provided #576

Merged
merged 1 commit into from
Mar 12, 2018
Merged

Fix multipart to set its header even when other headers are provided #576

merged 1 commit into from
Mar 12, 2018

Conversation

jirutka
Copy link
Contributor

@jirutka jirutka commented Feb 25, 2018

@raw_request.initialize_http_header resets the headers, so when options contained :headers, it always erased the Content-Type header set for multipart.

Now the Content-Type header is always set to "multipart/form-data" when body is detected as multipart. This is IMHO not correct, but that's how the original implementation was designed…

Related to: #569
Notify: @TheSmartnik

@request.options[:headers] = {'Content-Type' => 'application/x-www-form-urlencoded'}
@request.send(:setup_raw_request)
headers = @request.instance_variable_get(:@raw_request).each_header.to_h
expect(headers['content-type']).to match(%r{^multipart/form-data; boundary=---})
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is nasty copypaste code, but unfortunately that’s how the rest of the tests in this file is written, so to be consistent…

@TheSmartnik
Copy link
Collaborator

This is IMHO not correct, but that's how the original implementation was designed

Why do you think this isn't correct? What would be a correct behaviour in your opinion?

`@raw_request.initialize_http_header` resets the headers, so when
options contained :headers, it always erased the Content-Type header set
for multipart.

Now the Content-Type header is always set to "multipart/form-data" when
body is detected as multipart. This is IMHO not correct, but that's how
the original implementation was designed...
@jordanbyron
Copy link

@TheSmartnik you can re-produce the bug by running this slightly modified version of the specs for checking the headers. Only change I made here was to include headers: {} when calling @klass.post:

context 'when posting file' do
  let(:boundary) { '------------------------c772861a5109d5ef' }
  let(:headers) do
    { 'Content-Type'=>"multipart/form-data; boundary=#{boundary}" }
  end

  before do
    expect(HTTParty::Request::MultipartBoundary).to receive(:generate).and_return(boundary)
  end

  it 'changes content-type headers to multipart/form-data' do
    stub_request(:post, "http://example.com/").with(headers: headers)

    @klass.post('http://example.com', body: { file: File.open('spec/fixtures/tiny.gif')}, headers: {})
  end
end

Adding any headers to the post call wipes out the Content-Type header set here:

# lib/httparty/request.rb
#
# Assuming *options* has a multipart body AND headers
#
def setup_raw_request
  # snip ...

  if options[:body] # <= This gets called
    if body.multipart?
      content_type = "multipart/form-data; boundary=#{body.boundary}"
      @raw_request.initialize_http_header('Content-Type' => content_type)  # <= This gets called
    end
    @raw_request.body = body.call
  end

  if options[:headers].respond_to?(:to_hash)  # <= This gets called
    headers_hash = options[:headers].to_hash

    # This gets called, clearing the Content-Type header set above
    @raw_request.initialize_http_header(headers_hash) 
    # $=> @raw_request.to_hash 
    # #=> {}
    #  Missing Content-Type, breaking multipart support :(
    # snip ...
    end
  end

  # snip ....
end

@jnunemaker
Copy link
Owner

I think this makes sense. It seems like we'd want the multi part header regardless of any other headers passed in.

@TheSmartnik any feels to the contrary?

@jordanbyron
Copy link

@jnunemaker @TheSmartnik hey gents! Anything I can do to help move this along? We've got our httparty locked at the pre-0.16 version until this gets resolved. Thanks so much!

@TheSmartnik
Copy link
Collaborator

TheSmartnik commented Mar 12, 2018

Hi, everyone. Sorry for a long reply.

I think this makes sense. It seems like we'd want the multi part header regardless of any other headers passed in.

@jnunemaker I agree. That's why I asked, why @jirutka said

This is IMHO not correct

@TheSmartnik
Copy link
Collaborator

Tested the fix. Working good. Thanks @jirutka

@jnunemaker jnunemaker merged commit 37336f4 into jnunemaker:master Mar 12, 2018
@jnunemaker
Copy link
Owner

0.16.1 is out.

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.

4 participants