Skip to content

SavonRB uses dirty http request, leading to incorrect Content-Length header #237

Closed
@timcharper

Description

@timcharper

Given I execute some code as follows:

    require "savon"

    # create a client for your SOAP service
    client = Savon::Client.new("http://service.example.com?wsdl")

    client.wsdl.soap_actions
    # => [:create_user, :get_user, :get_all_users]

    # execute a SOAP request to call the "getUser" action
    response = client.request(:get_user) do
      soap.body = { :id => 1 }
    end

    # ... do stuff with response...

    # update the user
    response = client.request(:update_user) do
      soap.body = { :id => user.id, :email => "cornholio@email.com", :name => "Alter Ego" }
    end

The second call to client.request ends up using a recycled http object.

It's allocated here:

https://github.com/rubiii/savon/blob/6b6fe262/lib/savon/client.rb#L45

Then used here:

https://github.com/rubiii/savon/blob/6b6fe262/lib/savon/client.rb#L79

Then it's ultimately configured here:

https://github.com/rubiii/savon/blob/6b6fe262/lib/savon/soap/request.rb#L40-43

The problem is with this:

    http.headers["Content-Length"] ||= soap.to_xml.length.to_s

Since the header was sent from the first request (the call to get_user), the call to update_user inherits the content length. Ultimately, this causes the server to receive truncated XML, because the call to update_user in fact has a longer content length, so the server usually returns a 400 (malformed) response.

I'm not sure what the best way to fix this is. As it stands, I see two options:

  1. Change the '||=' default assignment operators to '=' assignment operators here:

https://github.com/rubiii/savon/blob/6b6fe262/lib/savon/soap/request.rb#L40-43

  1. Instantiate a new HTTP object in client.rb with each request. This would mean storing the cookie in another object and setting the cookie each time.

What way do you think is better? I tend to think #2 is better, but #1 is obviously the easiest fix.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions