savon 0.7.6 → 0.7.7

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,5 +1,20 @@
1
+ == 0.7.7 (2010-05-09)
2
+ * SOAP requests now start with a proper XML declaration.
3
+ * Added support for gzipped requests and responses (http://github.com/lucascs). While gzipped SOAP
4
+ responses are decoded automatically, you have to manually instruct Savon to gzip SOAP requests:
5
+
6
+ client = Savon::Client.new "http://example.com/UserService?wsdl", :gzip => true
7
+
8
+ * Fix for issue #51. Added the :soap_endpoint option to Savon::Client.new which let's you specify a SOAP
9
+ endpoint per client instance:
10
+
11
+ client = Savon::Client.new "http://example.com/UserService?wsdl",
12
+ :soap_endpoint => "http://localhost/UserService"
13
+
14
+ * Fix for issue #50. Savon still escapes special characters in SOAP request Hash values, but you can now
15
+ append an exclamation mark to Hash keys specifying that it's value should not be escaped.
16
+
1
17
  == 0.7.6 (2010-03-21)
2
- * Renamed
3
18
  * Moved documentation from the Github Wiki to the actual class files and established a much nicer
4
19
  documentation combining examples and implementation (using Hanna) at: http://savon.rubiii.com
5
20
  * Added Savon::Client#call as a workaround for dispatching calls to SOAP actions named after
@@ -153,4 +168,3 @@
153
168
 
154
169
  == 0.5.0 (2009-11-29)
155
170
  * Complete rewrite.
156
-
@@ -16,7 +16,7 @@ Instantiate Savon::Client, passing in the WSDL of your service.
16
16
 
17
17
  client = Savon::Client.new "http://example.com/UserService?wsdl"
18
18
 
19
- For production, it is highly recommended to not use Savon::WSDL. Information on {how to disable the WSDL}[http://savon.rubiii.com/docs/latest/classes/Savon/WSDL.html].
19
+ For production, it is highly recommended to not use Savon::WSDL. Information on {how to disable the WSDL}[http://savon.rubiii.com/docs/0.7.7/classes/Savon/WSDL.html].
20
20
 
21
21
  == Calling a SOAP action
22
22
 
@@ -56,9 +56,9 @@ Savon::Response represents the HTTP and SOAP response. It contains and raises er
56
56
  == HTTP errors and SOAP faults
57
57
 
58
58
  Savon raises a Savon::SOAPFault in case of a SOAP fault and a Savon::HTTPError in case of an HTTP error.
59
- More information: {Errors}[http://savon.rubiii.com/docs/latest/classes/Savon/Response.html]
59
+ More information: {Errors}[http://savon.rubiii.com/docs/0.7.7/classes/Savon/Response.html]
60
60
 
61
61
  == Logging
62
62
 
63
63
  Savon logs each request and response to STDOUT. But there are a couple of options to change the default behavior.
64
- More information: {Logging}[http://savon.rubiii.com/docs/latest/classes/Savon/Request.html]
64
+ More information: {Logging}[http://savon.rubiii.com/docs/0.7.7/classes/Savon/Request.html]
data/Rakefile CHANGED
@@ -36,7 +36,6 @@ Spec::Rake::SpecTask.new(:run_integration_spec) do |spec|
36
36
  end
37
37
 
38
38
  begin
39
- $:.unshift File.join(File.dirname(__FILE__), "..", "hanna", "lib")
40
39
  require "hanna/rdoctask"
41
40
 
42
41
  Rake::RDocTask.new do |rdoc|
@@ -14,6 +14,9 @@ require "net/https"
14
14
  require "base64"
15
15
  require "digest/sha1"
16
16
  require "rexml/document"
17
+ require "stringio"
18
+ require "zlib"
19
+ require "cgi"
17
20
 
18
21
  # gem dependencies
19
22
  require "builder"
@@ -29,3 +32,4 @@ require "savon/response"
29
32
  require "savon/wsdl_stream"
30
33
  require "savon/wsdl"
31
34
  require "savon/client"
35
+ require "savon/version"
@@ -27,6 +27,19 @@ module Savon
27
27
  #
28
28
  # client = Savon::Client.new "http://example.com/UserService?wsdl", :proxy => "http://proxy.example.com"
29
29
  #
30
+ # == Forcing a particular SOAP endpoint
31
+ #
32
+ # In case you don't want to use the SOAP endpoint specified in the WSDL, you can tell Savon to use
33
+ # another SOAP endpoint.
34
+ #
35
+ # client = Savon::Client.new "http://example.com/UserService?wsdl", :soap_endpoint => "http://localhost/UserService"
36
+ #
37
+ # == Gzipped SOAP requests
38
+ #
39
+ # Sending gzipped SOAP requests can be specified per client instance.
40
+ #
41
+ # client = Savon::Client.new "http://example.com/UserService?wsdl", :gzip => true
42
+ #
30
43
  # == Savon::WSDL
31
44
  #
32
45
  # You can access Savon::WSDL via:
@@ -40,11 +53,17 @@ module Savon
40
53
  # client.request
41
54
  class Client
42
55
 
43
- # Expects a SOAP +endpoint+ string. Also accepts an optional hash of +options+ for specifying
44
- # a +:proxy+ server to use.
56
+ # Expects a SOAP +endpoint+ string. Also accepts a Hash of +options+.
57
+ #
58
+ # ==== Options:
59
+ #
60
+ # [proxy] the proxy server to use
61
+ # [gzip] whether to gzip SOAP requests
62
+ # [soap_endpoint] force to use this SOAP endpoint
45
63
  def initialize(endpoint, options = {})
64
+ soap_endpoint = options.delete(:soap_endpoint)
46
65
  @request = Request.new endpoint, options
47
- @wsdl = WSDL.new @request
66
+ @wsdl = WSDL.new @request, soap_endpoint
48
67
  end
49
68
 
50
69
  # Returns the Savon::WSDL.
@@ -1,14 +1,14 @@
1
1
  class Array
2
2
 
3
3
  # Translates the Array into SOAP compatible XML. See: Hash.to_soap_xml.
4
- def to_soap_xml(key, attributes = {})
4
+ def to_soap_xml(key, escape_xml = true, attributes = {})
5
5
  xml = Builder::XmlMarkup.new
6
6
 
7
7
  each_with_index do |item, index|
8
8
  attrs = tag_attributes attributes, index
9
9
  case item
10
10
  when Hash then xml.tag!(key, attrs) { xml << item.to_soap_xml }
11
- else xml.tag!(key, attrs) { xml << item.to_soap_value }
11
+ else xml.tag!(key, attrs) { xml << (escape_xml ? item.to_soap_value : item.to_soap_value!) }
12
12
  end
13
13
  end
14
14
 
@@ -5,4 +5,6 @@ class DateTime
5
5
  strftime Savon::SOAP::DateTimeFormat
6
6
  end
7
7
 
8
+ alias_method :to_soap_value!, :to_soap_value
9
+
8
10
  end
@@ -35,7 +35,11 @@ class Hash
35
35
  # <perform_at>2012-06-11T10:42:21</perform_at>
36
36
  # </magicRequest>
37
37
  #
38
- # ==== :order!
38
+ # ==== Escaped XML values
39
+ #
40
+ # By default, special characters in XML String values are escaped.
41
+ #
42
+ # ==== Fixed order of XML tags
39
43
  #
40
44
  # In case your service requires the tags to be in a specific order (parameterOrder), you have two
41
45
  # options. The first is to specify your body as an XML string. The second is to specify the order
@@ -44,7 +48,7 @@ class Hash
44
48
  # { :name => "Eve", :id => 123, :order! => [:id, :name] }.to_soap_xml
45
49
  # # => "<id>123</id><name>Eve</name>"
46
50
  #
47
- # ==== :attributes!
51
+ # ==== XML attributes
48
52
  #
49
53
  # If you need attributes, you could either go with an XML string or add another hash under the
50
54
  # +:attributes!+ key.
@@ -58,12 +62,13 @@ class Hash
58
62
  order.each do |key|
59
63
  attrs = attributes[key] || {}
60
64
  value = self[key]
65
+ escape_xml = key.to_s[-1, 1] != "!"
61
66
  key = key.to_soap_key
62
67
 
63
68
  case value
64
- when Array then xml << value.to_soap_xml(key, attrs)
69
+ when Array then xml << value.to_soap_xml(key, escape_xml, attrs)
65
70
  when Hash then xml.tag!(key, attrs) { xml << value.to_soap_xml }
66
- else xml.tag!(key, attrs) { xml << value.to_soap_value }
71
+ else xml.tag!(key, attrs) { xml << (escape_xml ? value.to_soap_value : value.to_soap_value!) }
67
72
  end
68
73
  end
69
74
 
@@ -5,15 +5,12 @@ class Object
5
5
  respond_to?(:empty?) ? empty? : !self
6
6
  end unless defined? blank?
7
7
 
8
- # Returns the Object as a SOAP request compliant key.
9
- def to_soap_key
10
- to_s
11
- end
12
-
13
8
  # Returns the Object as a SOAP request compliant value.
14
9
  def to_soap_value
15
10
  return to_s unless respond_to? :to_datetime
16
11
  to_datetime.to_soap_value
17
12
  end
18
13
 
14
+ alias_method :to_soap_value!, :to_soap_value
15
+
19
16
  end
@@ -51,16 +51,19 @@ class String
51
51
  self
52
52
  end
53
53
 
54
- # Returns the String as a SOAP request compliant value.
55
- # Escapes special characters for XML.
54
+ # Returns the Object as a SOAP request compliant key.
55
+ def to_soap_key
56
+ self[-1, 1] == "!" ? chop : self
57
+ end
58
+
59
+ # Returns the String as a SOAP value. Escapes special characters for XML.
56
60
  def to_soap_value
57
- str = dup
58
- str.gsub! "&", "&amp;"
59
- str.gsub! '"', "&quot;"
60
- str.gsub! "'", "&apos;"
61
- str.gsub! "<", "&lt;"
62
- str.gsub! ">", "&gt;"
63
- str
61
+ CGI.escapeHTML self
62
+ end
63
+
64
+ # Convert the String into a SOAP value without escaping special characters.
65
+ def to_soap_value!
66
+ self
64
67
  end
65
68
 
66
69
  end
@@ -2,7 +2,7 @@ class Symbol
2
2
 
3
3
  # Returns the Symbol as a lowerCamelCase String.
4
4
  def to_soap_key
5
- to_s.lower_camelcase
5
+ to_s.to_soap_key.lower_camelcase
6
6
  end
7
7
 
8
8
  end
@@ -46,11 +46,11 @@ module Savon
46
46
  # Content-Types by SOAP version.
47
47
  ContentType = { 1 => "text/xml;charset=UTF-8", 2 => "application/soap+xml;charset=UTF-8" }
48
48
 
49
- # Expects a SOAP +endpoint+ String. Also accepts an optional Hash
50
- # of +options+ for specifying a proxy server.
49
+ # Expects a WSDL or SOAP +endpoint+ and accepts a custom +proxy+ address.
51
50
  def initialize(endpoint, options = {})
52
51
  @endpoint = URI endpoint
53
- @proxy = options[:proxy] ? URI(options[:proxy]) : URI("")
52
+ @proxy = URI options[:proxy] || ""
53
+ headers["Accept-encoding"] = "gzip,deflate" if options[:gzip]
54
54
  end
55
55
 
56
56
  # Returns the endpoint URI.
@@ -135,3 +135,4 @@ module Savon
135
135
 
136
136
  end
137
137
  end
138
+
@@ -100,12 +100,12 @@ module Savon
100
100
 
101
101
  # Returns the SOAP response body as a Hash.
102
102
  def to_hash
103
- @body ||= (Crack::XML.parse(@http.body) rescue {}).find_soap_body
103
+ @hash ||= (Crack::XML.parse(body) rescue {}).find_soap_body
104
104
  end
105
105
 
106
106
  # Returns the SOAP response XML.
107
107
  def to_xml
108
- @http.body
108
+ body
109
109
  end
110
110
 
111
111
  # Returns the HTTP response object.
@@ -115,6 +115,24 @@ module Savon
115
115
 
116
116
  private
117
117
 
118
+ # Returns the response body.
119
+ def body
120
+ @body || gzipped_body? ? decoded_body : @http.body
121
+ end
122
+
123
+ # Returns whether the body is gzipped.
124
+ def gzipped_body?
125
+ @http["content-encoding"] == "gzip" || @http.body[0..1] == "\x1f\x8b"
126
+ end
127
+
128
+ # Returns the gzip decoded body.
129
+ def decoded_body
130
+ gz = Zlib::GzipReader.new StringIO.new(@http.body)
131
+ gz.read
132
+ ensure
133
+ gz.close
134
+ end
135
+
118
136
  # Handles SOAP faults. Raises a Savon::SOAPFault unless the default behavior of raising errors
119
137
  # was turned off.
120
138
  def handle_soap_fault
@@ -146,10 +164,11 @@ module Savon
146
164
  def handle_http_error
147
165
  if @http.code.to_i > MaxNonErrorResponseCode
148
166
  @http_error = "#{@http.message} (#{@http.code})"
149
- @http_error << ": #{@http.body}" unless @http.body.empty?
167
+ @http_error << ": #{body}" unless body.empty?
150
168
  raise Savon::HTTPError, http_error if self.class.raise_errors?
151
169
  end
152
170
  end
153
171
 
154
172
  end
155
173
  end
174
+
@@ -0,0 +1,5 @@
1
+ module Savon
2
+
3
+ Version = "0.7.7"
4
+
5
+ end
@@ -71,9 +71,9 @@ module Savon
71
71
  # end
72
72
  class WSDL
73
73
 
74
- # Initializer, expects a Savon::Request.
75
- def initialize(request)
76
- @request, @enabled = request, true
74
+ # Expects a Savon::Request and accepts a custom +soap_endpoint+.
75
+ def initialize(request, soap_endpoint = nil)
76
+ @request, @enabled, @soap_endpoint = request, true, soap_endpoint
77
77
  end
78
78
 
79
79
  # Sets whether to use the WSDL.
@@ -0,0 +1,7 @@
1
+ class GzipResponseFixture
2
+
3
+ def self.message
4
+ File.read(File.join(File.dirname(__FILE__), 'message.gz'))
5
+ end
6
+ end
7
+
@@ -14,6 +14,11 @@ describe Savon::Client do
14
14
  client.request.http.proxy_address == "http://proxy"
15
15
  end
16
16
 
17
+ it "should accept a SOAP endpoint via an optional Hash of options" do
18
+ client = Savon::Client.new EndpointHelper.wsdl_endpoint, :soap_endpoint => "http://localhost"
19
+ client.wsdl.soap_endpoint.should == "http://localhost"
20
+ end
21
+
17
22
  it "should have a method that returns the Savon::WSDL" do
18
23
  @client.wsdl.should be_a(Savon::WSDL)
19
24
  end
@@ -3,17 +3,47 @@ require "spec_helper"
3
3
  describe Array do
4
4
 
5
5
  describe "to_soap_xml" do
6
- describe "should return SOAP request compatible XML" do
7
- it "for an Array of Hashes" do
8
- hash, result = [{ :name => "Eve" }], "<findUser><name>Eve</name></findUser>"
9
- hash.to_soap_xml("findUser").should == result
10
- end
11
-
12
- it "for an Array of Strings and other Objects" do
13
- hash, result = [:id, :name], "<someValues>id</someValues><someValues>name</someValues>"
14
- hash.to_soap_xml("someValues").should == result
15
- end
6
+ it "should return the XML for an Array of Hashes" do
7
+ array = [{ :name => "adam" }, { :name => "eve" }]
8
+ result = "<user><name>adam</name></user><user><name>eve</name></user>"
9
+
10
+ array.to_soap_xml("user").should == result
11
+ end
12
+
13
+ it "should return the XML for an Array of different Objects" do
14
+ array = [:symbol, "string", 123]
15
+ result = "<value>symbol</value><value>string</value><value>123</value>"
16
+
17
+ array.to_soap_xml("value").should == result
18
+ end
19
+
20
+ it "should default to escape special characters" do
21
+ array = ["<tag />", "adam & eve"]
22
+ result = "<value>&lt;tag /&gt;</value><value>adam &amp; eve</value>"
23
+
24
+ array.to_soap_xml("value").should == result
25
+ end
26
+
27
+ it "should not escape special characters when told to" do
28
+ array = ["<tag />", "adam & eve"]
29
+ result = "<value><tag /></value><value>adam & eve</value>"
30
+
31
+ array.to_soap_xml("value", false).should == result
32
+ end
33
+
34
+ it "should add attributes to a given tag" do
35
+ array = ["adam", "eve"]
36
+ result = '<value active="true">adam</value><value active="true">eve</value>'
37
+
38
+ array.to_soap_xml("value", :escape_xml, :active => true).should == result
39
+ end
40
+
41
+ it "should add attributes to duplicate tags" do
42
+ array = ["adam", "eve"]
43
+ result = '<value id="1">adam</value><value id="2">eve</value>'
44
+
45
+ array.to_soap_xml("value", :escape_xml, :id => [1, 2]).should == result
16
46
  end
17
47
  end
18
48
 
19
- end
49
+ end
@@ -1,11 +1,20 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe DateTime do
4
+ before do
5
+ @datetime = DateTime.new 2012, 03, 22, 16, 22, 33
6
+ @datetime_string = "2012-03-22T16:22:33Z"
7
+ end
4
8
 
5
9
  describe "to_soap_value" do
6
- it "returns an xs:dateTime compliant String" do
7
- DateTime.new(2012, 03, 22, 16, 22, 33).to_soap_value.
8
- should == "2012-03-22T16:22:33Z"
10
+ it "should return an xs:dateTime compliant String" do
11
+ @datetime.to_soap_value.should == @datetime_string
12
+ end
13
+ end
14
+
15
+ describe "to_soap_value!" do
16
+ it "should act like :to_soap_value" do
17
+ @datetime.to_soap_value.should == @datetime_string
9
18
  end
10
19
  end
11
20
 
@@ -85,6 +85,18 @@ describe Hash do
85
85
  end
86
86
  end
87
87
 
88
+ it "should default to escape special characters" do
89
+ result = { :some => { :nested => "<tag />" }, :tag => "<tag />" }.to_soap_xml
90
+ result.should include("<tag>&lt;tag /&gt;</tag>")
91
+ result.should include("<some><nested>&lt;tag /&gt;</nested></some>")
92
+ end
93
+
94
+ it "should not escape special characters for keys marked with an exclamation mark" do
95
+ result = { :some => { :nested! => "<tag />" }, :tag! => "<tag />" }.to_soap_xml
96
+ result.should include("<tag><tag /></tag>")
97
+ result.should include("<some><nested><tag /></nested></some>")
98
+ end
99
+
88
100
  it "should preserve the order of Hash keys and values specified through :order!" do
89
101
  hash = { :find_user => { :name => "Lucy", :id => 666, :order! => [:id, :name] } }
90
102
  result = "<findUser><id>666</id><name>Lucy</name></findUser>"
@@ -16,12 +16,6 @@ describe Object do
16
16
  end
17
17
  end
18
18
 
19
- describe "to_soap_key" do
20
- it "calls to_s for every Object" do
21
- Object.to_soap_key.should == Object.to_s
22
- end
23
- end
24
-
25
19
  describe "to_soap_value" do
26
20
  it "returns an xs:dateTime compliant String for Objects responding to to_datetime" do
27
21
  singleton = Object.new
@@ -74,13 +74,25 @@ describe String do
74
74
  end
75
75
  end
76
76
 
77
+ describe "to_soap_key" do
78
+ it "removes exclamation marks from the end of the String" do
79
+ "value".to_soap_key.should == "value"
80
+ "value!".to_soap_key.should == "value"
81
+ end
82
+ end
83
+
77
84
  describe "to_soap_value" do
78
- it "should return the string value and escape special characters" do
85
+ it "should return the String value and escape special characters" do
79
86
  "string".to_soap_value.should == "string"
80
87
  "<tag>".to_soap_value.should == "&lt;tag&gt;"
81
88
  "at&t".to_soap_value.should == "at&amp;t"
82
89
  '"quotes"'.to_soap_value.should == "&quot;quotes&quot;"
83
- "'apos'".to_soap_value.should == "&apos;apos&apos;"
90
+ end
91
+ end
92
+
93
+ describe "to_soap_value!" do
94
+ it "should just return the String value without escaping special characters" do
95
+ "<tag>".to_soap_value!.should == "<tag>"
84
96
  end
85
97
  end
86
98
 
@@ -5,6 +5,7 @@ describe Symbol do
5
5
  describe "to_soap_key" do
6
6
  it "converts the Symbol from snake_case to a lowerCamelCase String" do
7
7
  :lower_camel_case.to_soap_key.should == "lowerCamelCase"
8
+ :lower_camel_case!.to_soap_key.should == "lowerCamelCase"
8
9
  end
9
10
  end
10
11
 
@@ -75,14 +75,38 @@ describe Savon::Request do
75
75
  wsdl_response.body.should == WSDLFixture.authentication
76
76
  end
77
77
 
78
- it "executes a SOAP request and returns the Net::HTTP response" do
79
- operation = WSDLFixture.authentication(:operations)[:authenticate]
80
- action, input = operation[:action], operation[:input]
81
- soap = Savon::SOAP.new action, input, EndpointHelper.soap_endpoint
82
- soap_response = @request.soap soap
83
78
 
84
- soap_response.should be_a(Net::HTTPResponse)
85
- soap_response.body.should == ResponseFixture.authentication
79
+ describe "when executing a SOAP request" do
80
+ before :each do
81
+ operation = WSDLFixture.authentication(:operations)[:authenticate]
82
+ action, input = operation[:action], operation[:input]
83
+ @soap = Savon::SOAP.new action, input, EndpointHelper.soap_endpoint
84
+ end
85
+
86
+ it "should return the Net::HTTP response" do
87
+ soap_response = @request.soap @soap
88
+
89
+ soap_response.should be_a(Net::HTTPResponse)
90
+ soap_response.body.should == ResponseFixture.authentication
91
+ end
92
+
93
+ it "should include Accept-Encoding gzip if it is enabled" do
94
+ @request = Savon::Request.new EndpointHelper.wsdl_endpoint, :gzip => true
95
+ a_post = Net::HTTP::Post.new(@soap.endpoint.request_uri, {})
96
+
97
+ Net::HTTP::Post.expects(:new).with(anything, has_entry("Accept-encoding" => "gzip,deflate")).returns(a_post)
98
+
99
+ @request.soap @soap
100
+ end
101
+
102
+ it "should not include Accept-Encoding gzip if it is not enabled" do
103
+ @request = Savon::Request.new EndpointHelper.wsdl_endpoint, :gzip => false
104
+ a_post = Net::HTTP::Post.new(@soap.endpoint.request_uri, {})
105
+
106
+ Net::HTTP::Post.expects(:new).with(anything, Not(has_entry("Accept-encoding" => "gzip,deflate"))).returns(a_post)
107
+
108
+ @request.soap @soap
109
+ end
86
110
  end
87
111
 
88
112
  it "should not include host when creating HTTP requests" do
@@ -90,4 +114,4 @@ describe Savon::Request do
90
114
  request.path.should_not include("example.com")
91
115
  end
92
116
 
93
- end
117
+ end
@@ -21,13 +21,13 @@ describe Savon::Response do
21
21
  it "raises a Savon::SOAPFault in case of a SOAP fault" do
22
22
  lambda { savon_response_with :soap_fault }.should raise_error(Savon::SOAPFault)
23
23
  end
24
-
24
+
25
25
  it "does not raise a Savon::SOAPFault in case the default is turned off" do
26
26
  Savon::Response.raise_errors = false
27
27
  savon_response_with :soap_fault
28
28
  Savon::Response.raise_errors = true
29
29
  end
30
-
30
+
31
31
  it "raises a Savon::HTTPError in case of an HTTP error" do
32
32
  lambda { savon_response_with :http_error }.should raise_error(Savon::HTTPError)
33
33
  end
@@ -102,7 +102,7 @@ describe Savon::Response do
102
102
  @response = Savon::Response.new http_response_mock(200, ResponseFixture.multi_ref, "OK")
103
103
 
104
104
  @response.to_hash[:list_response].should be_a(Hash)
105
- @response.to_hash[:multi_ref].should be_an(Array)
105
+ @response.to_hash[:multi_ref].should be_an(Array)
106
106
  end
107
107
 
108
108
  it "should return the raw SOAP response body" do
@@ -117,6 +117,44 @@ describe Savon::Response do
117
117
  @response.http.should respond_to(:body)
118
118
  end
119
119
 
120
+ describe "GZipped responses" do
121
+ it "should be decoded if Content-encoding header is gzip" do
122
+ @response = Savon::Response.new http_response_mock(200, body = "Encoded", "OK", 'content-encoding' => 'gzip')
123
+
124
+ should_decode_body body
125
+
126
+ @response.to_xml
127
+ end
128
+
129
+ # header logic extracted from http://dev.ctor.org/svn/soap4r/trunk/lib/soap/streamHandler.rb
130
+ it "should be decoded if body starts with gzip header" do
131
+ @response = Savon::Response.new http_response_mock(200, body = "\x1f\x8bEncoded", "OK")
132
+
133
+ should_decode_body body
134
+
135
+ @response.to_xml
136
+ end
137
+
138
+ it "should be decoded when header is set" do
139
+ @response = Savon::Response.new http_response_mock(200, GzipResponseFixture.message, "OK", 'content-encoding' => 'gzip')
140
+ @response.to_xml.should == "A short gzip encoded message\n"
141
+ end
142
+
143
+ it "should be decoded when header is not set" do
144
+ @response = Savon::Response.new http_response_mock(200, GzipResponseFixture.message, "OK")
145
+ @response.to_xml.should == "A short gzip encoded message\n"
146
+ end
147
+ end
148
+
149
+ def should_decode_body(body)
150
+ StringIO.expects(:new).with(body).returns(stream = mock("StringIO"))
151
+
152
+ Zlib::GzipReader.expects(:new).with(stream).returns(mock("Zlib::GzipReader") do
153
+ expects(:read)
154
+ expects(:close)
155
+ end)
156
+ end
157
+
120
158
  def savon_response_with(error_type)
121
159
  mock = case error_type
122
160
  when :soap_fault then http_response_mock 200, ResponseFixture.soap_fault
@@ -126,12 +164,16 @@ describe Savon::Response do
126
164
  Savon::Response.new mock
127
165
  end
128
166
 
129
- def http_response_mock(code = 200, body = nil, message = "OK")
167
+ def http_response_mock(code = 200, body = nil, message = "OK", headers = {})
130
168
  body ||= ResponseFixture.authentication
131
169
  mock = mock "Net::HTTPResponse"
132
- mock.stubs :code => code.to_s, :message => message,
133
- :content_type => "text/html", :body => body
170
+ mock.stubs :code => code.to_s, :message => message, :content_type => "text/html", :body => body
171
+
172
+ mock.stubs("[]").with(anything).returns(nil)
173
+ headers.each { |key, value| mock.stubs("[]").with(key).returns(value) }
174
+
134
175
  mock
135
176
  end
136
177
 
137
178
  end
179
+
@@ -49,7 +49,7 @@ describe Savon::SOAP do
49
49
  @namespace = { "xmlns:ns" => "http://example.com" }
50
50
  @namespace_string = 'xmlns:ns="http://example.com"'
51
51
  @namespaces = { "xmlns:ns" => "http://ns.example.com", "xmlns:ns2" => "http://ns2.example.com" }
52
-
52
+
53
53
  # reset to defaults
54
54
  Savon::SOAP.version = 1
55
55
  Savon::SOAP.header = {}
@@ -137,15 +137,15 @@ describe Savon::SOAP do
137
137
  it "should merge global and per request headers defined as Hashes" do
138
138
  Savon::SOAP.header = { :key => "value", :key2 => "global value" }
139
139
  @soap.header[:key2] = "request value"
140
- @soap.to_xml.should include(
141
- "<env:Header><key>value</key><key2>request value</key2></env:Header>"
140
+ @soap.to_xml.should match(
141
+ /<env:Header>(<key>value<\/key><key2>request value<\/key2>|<key2>request value<\/key2><key>value<\/key>)<\/env:Header>/
142
142
  )
143
143
  end
144
144
 
145
145
  it "should use the :header method from a given WSSE object to include a WSSE header" do
146
146
  wsse = "some compliant object"
147
147
  wsse.stubs(:header).returns("<wsse>authentication</wsse>")
148
-
148
+
149
149
  @soap.wsse = wsse
150
150
  @soap.to_xml.should include("<env:Header><wsse>authentication</wsse></env:Header>")
151
151
  end
@@ -195,7 +195,8 @@ describe Savon::SOAP do
195
195
  '<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">' <<
196
196
  '<env:Body><wsdl:authenticate></wsdl:authenticate></env:Body>' <<
197
197
  '</env:Envelope>'
198
- )
198
+ )
199
199
  end
200
200
  end
201
- end
201
+ end
202
+
@@ -8,6 +8,11 @@ describe Savon::WSDL do
8
8
  Savon::WSDL.new Savon::Request.new(EndpointHelper.wsdl_endpoint)
9
9
  end
10
10
 
11
+ it "it accepts a custom SOAP endpoint" do
12
+ wsdl = Savon::WSDL.new Savon::Request.new(EndpointHelper.wsdl_endpoint), "http://localhost"
13
+ wsdl.soap_endpoint.should == "http://localhost"
14
+ end
15
+
11
16
  it "is enabled by default" do
12
17
  @wsdl.enabled?.should be_true
13
18
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 7
8
- - 6
9
- version: 0.7.6
8
+ - 7
9
+ version: 0.7.7
10
10
  platform: ruby
11
11
  authors:
12
12
  - Daniel Harrington
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-03-21 00:00:00 +01:00
17
+ date: 2010-05-09 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -113,12 +113,14 @@ files:
113
113
  - lib/savon/request.rb
114
114
  - lib/savon/response.rb
115
115
  - lib/savon/soap.rb
116
+ - lib/savon/version.rb
116
117
  - lib/savon/wsdl.rb
117
118
  - lib/savon/wsdl_stream.rb
118
119
  - lib/savon/wsse.rb
119
120
  - lib/savon.rb
120
121
  - spec/basic_spec_helper.rb
121
122
  - spec/endpoint_helper.rb
123
+ - spec/fixtures/gzip/gzip_response_fixture.rb
122
124
  - spec/fixtures/response/response_fixture.rb
123
125
  - spec/fixtures/wsdl/wsdl_fixture.rb
124
126
  - spec/http_stubs.rb
@@ -147,6 +149,7 @@ files:
147
149
  - spec/fixtures/wsdl/xml/geotrust.xml
148
150
  - spec/fixtures/wsdl/xml/namespaced_actions.xml
149
151
  - spec/fixtures/wsdl/xml/no_namespace.xml
152
+ - spec/fixtures/gzip/message.gz
150
153
  has_rdoc: true
151
154
  homepage: http://github.com/rubiii/savon
152
155
  licenses: []
@@ -184,6 +187,7 @@ summary: Heavy metal Ruby SOAP client library
184
187
  test_files:
185
188
  - spec/basic_spec_helper.rb
186
189
  - spec/endpoint_helper.rb
190
+ - spec/fixtures/gzip/gzip_response_fixture.rb
187
191
  - spec/fixtures/response/response_fixture.rb
188
192
  - spec/fixtures/wsdl/wsdl_fixture.rb
189
193
  - spec/http_stubs.rb