savon 0.9.7 → 0.9.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,4 @@
1
1
  # https://github.com/travis-ci/travis-ci/wiki/.travis.yml-options
2
- bundler_args: --without developer_happiness
3
2
  script: "bundle exec rake"
4
3
  rvm:
5
4
  - 1.8.7
@@ -9,3 +8,5 @@ rvm:
9
8
  - rbx
10
9
  - rbx-2.0
11
10
  - jruby
11
+ notifications:
12
+ irc: "irc.freenode.org#savon"
data/.yardopts CHANGED
@@ -1,2 +1,5 @@
1
+ --markup markdown
2
+ --markup-provider redcarpet
1
3
  -
2
- CHANGELOG.rdoc
4
+ CHANGELOG.md
5
+ LICENSE
@@ -1,3 +1,37 @@
1
+ ## 0.9.8 (2012-02-15)
2
+
3
+ * Feature: Savon now ships with [Savon::Model](http://rubygems.org/gems/savon_model).
4
+ Savon::Model is a lightweight DSL to be used inside your domain models. It's been refactored
5
+ and is now [even more useful](http://savonrb.com/#how_to_date_a_model) than before.
6
+
7
+ * Feature: Merged [pull request 230](https://github.com/rubiii/savon/pull/230) to allow filtering values
8
+ in logged SOAP request XML messages.
9
+
10
+ ``` ruby
11
+ Savon.configure do |config|
12
+ config.log_filter = ["password"]
13
+ end
14
+ ```
15
+
16
+ * Feature: Added an option to change the default encoding of the XML directive tag (defaults to UTF-8)
17
+ to fix [issue 234](https://github.com/rubiii/savon/issues/234).
18
+
19
+ ``` ruby
20
+ client.request(:find_user) do
21
+ soap.encoding = "UTF-16"
22
+ soap.body = { :id => 1 }
23
+ end
24
+ ```
25
+
26
+ * Improvement: Merged [pull request 231](https://github.com/rubiii/savon/pull/231) to gracefully handle
27
+ invalid response bodies by throwing a `Savon::SOAP::InvalidResponseError`.
28
+
29
+ * Fix: [issue 237](https://github.com/rubiii/savon/issues/237) - Set the Content-Type and Content-Length
30
+ headers for every request.
31
+
32
+ * Fix: [pull request 250](https://github.com/rubiii/savon/pull/250) - The Content-Length header should
33
+ be the size in bytes.
34
+
1
35
  ## 0.9.7 (2011-08-25)
2
36
 
3
37
  * Feature: Merged [pull request 210](https://github.com/rubiii/savon/pull/210) by
data/Gemfile CHANGED
@@ -2,8 +2,3 @@ source :rubygems
2
2
  gemspec
3
3
 
4
4
  gem "httpclient", "~> 2.1.5"
5
-
6
- # excluded from travis
7
- group :developer_happiness do
8
- gem "autotest"
9
- end
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
- Savon [![Build Status](http://travis-ci.org/rubiii/savon.png)](http://travis-ci.org/rubiii/savon)
1
+ Savon [![Build Status](https://secure.travis-ci.org/rubiii/savon.png)](http://travis-ci.org/rubiii/savon)
2
2
  =====
3
3
 
4
4
  Heavy metal Ruby SOAP client
5
5
 
6
6
  [Documentation](http://savonrb.com) | [RDoc](http://rubydoc.info/gems/savon) |
7
- [Mailing list](http://groups.google.com/group/savon-soap) | [Twitter](http://twitter.com/savonrb)
7
+ [Mailing list](https://groups.google.com/forum/#!forum/savonrb) | [Twitter](http://twitter.com/savonrb)
8
8
 
9
9
  Installation
10
10
  ------------
@@ -15,26 +15,28 @@ Savon is available through [Rubygems](http://rubygems.org/gems/savon) and can be
15
15
  $ gem install savon
16
16
  ```
17
17
 
18
- Basic workflow
19
- --------------
18
+ Introduction
19
+ ------------
20
20
 
21
21
  ``` ruby
22
- # Setting up a Savon::Client representing a SOAP service.
23
- client = Savon::Client.new "http://service.example.com?wsdl"
22
+ require "savon"
23
+
24
+ # create a client for your SOAP service
25
+ client = Savon::Client.new("http://service.example.com?wsdl")
24
26
 
25
27
  client.wsdl.soap_actions
26
28
  # => [:create_user, :get_user, :get_all_users]
27
29
 
28
- # Executing a SOAP request to call a "getUser" action.
29
- response = client.request :get_user do
30
+ # execute a SOAP request to call the "getUser" action
31
+ response = client.request(:get_user) do
30
32
  soap.body = { :id => 1 }
31
33
  end
32
34
 
33
- response.to_hash
35
+ response.body
34
36
  # => { :get_user_response => { :first_name => "The", :last_name => "Hoff" } }
35
37
  ```
36
38
 
37
- Ready for more?
38
- ---------------
39
+ Documentation
40
+ -------------
39
41
 
40
- [Go ahead and read the official documentation](http://savonrb.com).
42
+ Continue reading at [savonrb.com](http://savonrb.com)
data/Rakefile CHANGED
@@ -1,11 +1,7 @@
1
- require "bundler"
2
- Bundler::GemHelper.install_tasks
3
-
1
+ require "bundler/gem_tasks"
4
2
  require "rspec/core/rake_task"
5
3
 
6
- RSpec::Core::RakeTask.new do |t|
7
- t.rspec_opts = %w(-c)
8
- end
4
+ RSpec::Core::RakeTask.new
9
5
 
10
6
  task :default => :spec
11
7
  task :test => :spec
@@ -1,12 +1,13 @@
1
1
  require "savon/version"
2
- require "savon/global"
2
+ require "savon/config"
3
3
  require "savon/client"
4
+ require "savon/model"
4
5
 
5
6
  module Savon
6
- extend Global
7
+ extend Config
7
8
 
8
9
  # Yields this module to a given +block+. Please refer to the
9
- # <tt>Savon::Global</tt> module for configuration options.
10
+ # <tt>Savon::Config</tt> module for configuration options.
10
11
  def self.configure
11
12
  yield self if block_given?
12
13
  end
@@ -0,0 +1,103 @@
1
+ require "logger"
2
+ require "savon/soap"
3
+ require "savon/hooks/group"
4
+
5
+ module Savon
6
+ module Config
7
+
8
+ # Sets whether to log HTTP requests.
9
+ attr_writer :log
10
+
11
+ # Returns whether to log HTTP requests. Defaults to +true+.
12
+ def log?
13
+ @log != false
14
+ end
15
+
16
+ # Sets the logger to use.
17
+ attr_writer :logger
18
+
19
+ # Returns the logger. Defaults to an instance of +Logger+ writing to STDOUT.
20
+ def logger
21
+ @logger ||= ::Logger.new STDOUT
22
+ end
23
+
24
+ # Sets the log level.
25
+ attr_writer :log_level
26
+
27
+ # Returns the log level. Defaults to :debug.
28
+ def log_level
29
+ @log_level ||= :debug
30
+ end
31
+
32
+ # Logs a given +message+. Optionally filtered if +xml+ is truthy.
33
+ def log(message, xml = false)
34
+ return unless log?
35
+ message = filter_xml(message) if xml && !log_filter.empty?
36
+ logger.send log_level, message
37
+ end
38
+
39
+ # Returns the log filter. Defaults to an empty Array.
40
+ def log_filter
41
+ @log_filter ||= []
42
+ end
43
+
44
+ # Sets the log filter. Expects an Array.
45
+ attr_writer :log_filter
46
+
47
+ # Filters the given +xml+ based on log filter.
48
+ def filter_xml(xml)
49
+ doc = Nokogiri::XML(xml)
50
+ return xml unless doc.errors.empty?
51
+
52
+ log_filter.each do |filter|
53
+ doc.xpath("//*[local-name()='#{filter}']").map { |node| node.content = "***FILTERED***" }
54
+ end
55
+
56
+ doc.root.to_s
57
+ end
58
+
59
+ # Sets whether to raise HTTP errors and SOAP faults.
60
+ attr_writer :raise_errors
61
+
62
+ # Returns whether to raise errors. Defaults to +true+.
63
+ def raise_errors?
64
+ @raise_errors != false
65
+ end
66
+
67
+ # Sets the global SOAP version.
68
+ def soap_version=(version)
69
+ raise ArgumentError, "Invalid SOAP version: #{version}" if version && !SOAP::Versions.include?(version)
70
+ @version = version
71
+ end
72
+
73
+ # Returns SOAP version. Defaults to +DefaultVersion+.
74
+ def soap_version
75
+ @version ||= SOAP::DefaultVersion
76
+ end
77
+
78
+ # Accessor for the global env_namespace.
79
+ attr_accessor :env_namespace
80
+
81
+ # Accessor for the global soap_header.
82
+ attr_accessor :soap_header
83
+
84
+ # Returns the hooks.
85
+ def hooks
86
+ @hooks ||= Hooks::Group.new
87
+ end
88
+
89
+ # Reset to default configuration.
90
+ def reset_config!
91
+ self.log = nil
92
+ self.logger = nil
93
+ self.log_level = nil
94
+ self.log_filter = nil
95
+ self.raise_errors = nil
96
+ self.soap_version = nil
97
+ self.env_namespace = nil
98
+ self.soap_header = nil
99
+ end
100
+
101
+ end
102
+ end
103
+
@@ -0,0 +1,46 @@
1
+ require "savon/hooks/hook"
2
+
3
+ module Savon
4
+ module Hooks
5
+
6
+ # = Savon::Hooks::Group
7
+ #
8
+ # Manages a list of hooks.
9
+ class Group
10
+
11
+ # Accepts an Array of +hooks+ to start with.
12
+ def initialize(hooks = nil)
13
+ self.hooks = hooks
14
+ end
15
+
16
+ attr_writer :hooks
17
+
18
+ def hooks
19
+ @hooks ||= []
20
+ end
21
+
22
+ # Adds a new hook.
23
+ def define(id, hook, &block)
24
+ hooks << Hook.new(id, hook, &block)
25
+ end
26
+
27
+ # Removes hooks matching the given +ids+.
28
+ def reject!(*ids)
29
+ ids = ids.flatten
30
+ hooks.reject! { |hook| ids.include? hook.id }
31
+ end
32
+
33
+ # Returns a new group for a given +hook+.
34
+ def select(hook)
35
+ Group.new hooks.select { |h| h.hook == hook }
36
+ end
37
+
38
+ # Calls the hooks with the given +args+ and returns the
39
+ # value of the last hooks.
40
+ def call(*args)
41
+ hooks.inject(nil) { |memo, hook| hook.call(*args) }
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,36 @@
1
+ module Savon
2
+ module Hooks
3
+
4
+ # = Savon::Hooks::Hook
5
+ #
6
+ # A hook used somewhere in the system.
7
+ class Hook
8
+
9
+ HOOKS = [
10
+
11
+ # Replaces the POST request executed to call a service.
12
+ # See: Savon::SOAP::Request#response
13
+ #
14
+ # Receives the <tt>Savon::SOAP::Request</tt> and is expected to return an <tt>HTTPI::Response</tt>.
15
+ # It can change the request and return something falsy to still execute the POST request.
16
+ :soap_request
17
+
18
+ ]
19
+
20
+ # Expects an +id+, the name of the +hook+ to use and a +block+ to be called.
21
+ def initialize(id, hook, &block)
22
+ self.id = id
23
+ self.hook = hook
24
+ self.block = block
25
+ end
26
+
27
+ attr_accessor :id, :hook, :block
28
+
29
+ # Calls the +block+ with the given +args+.
30
+ def call(*args)
31
+ block.call(*args)
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,103 @@
1
+ module Savon
2
+
3
+ # = Savon::Model
4
+ #
5
+ # Model for SOAP service oriented applications.
6
+ module Model
7
+
8
+ def self.extended(base)
9
+ base.setup
10
+ end
11
+
12
+ def setup
13
+ class_action_module
14
+ instance_action_module
15
+ end
16
+
17
+ # Accepts one or more SOAP actions and generates both class and instance methods named
18
+ # after the given actions. Each generated method accepts an optional SOAP body Hash and
19
+ # a block to be passed to <tt>Savon::Client#request</tt> and executes a SOAP request.
20
+ def actions(*actions)
21
+ actions.each do |action|
22
+ define_class_action(action)
23
+ define_instance_action(action)
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ # Defines a class-level SOAP action method.
30
+ def define_class_action(action)
31
+ class_action_module.module_eval %{
32
+ def #{action.to_s.snakecase}(body = nil, &block)
33
+ response = client.request :wsdl, #{action.inspect}, :body => body, &block
34
+ Savon.hooks.select(:model_soap_response).call(response) || response
35
+ end
36
+ }
37
+ end
38
+
39
+ # Defines an instance-level SOAP action method.
40
+ def define_instance_action(action)
41
+ instance_action_module.module_eval %{
42
+ def #{action.to_s.snakecase}(body = nil, &block)
43
+ self.class.#{action.to_s.snakecase} body, &block
44
+ end
45
+ }
46
+ end
47
+
48
+ # Class methods.
49
+ def class_action_module
50
+ @class_action_module ||= Module.new do
51
+
52
+ # Returns the memoized <tt>Savon::Client</tt>.
53
+ def client(&block)
54
+ @client ||= Savon::Client.new(&block)
55
+ end
56
+
57
+ # Sets the SOAP endpoint to the given +uri+.
58
+ def endpoint(uri)
59
+ client.wsdl.endpoint = uri
60
+ end
61
+
62
+ # Sets the target namespace.
63
+ def namespace(uri)
64
+ client.wsdl.namespace = uri
65
+ end
66
+
67
+ # Sets the WSDL document to the given +uri+.
68
+ def document(uri)
69
+ client.wsdl.document = uri
70
+ end
71
+
72
+ # Sets the HTTP headers.
73
+ def headers(headers)
74
+ client.http.headers = headers
75
+ end
76
+
77
+ # Sets basic auth +login+ and +password+.
78
+ def basic_auth(login, password)
79
+ client.http.auth.basic(login, password)
80
+ end
81
+
82
+ # Sets WSSE auth credentials.
83
+ def wsse_auth(*args)
84
+ client.wsse.credentials(*args)
85
+ end
86
+
87
+ end.tap { |mod| extend(mod) }
88
+ end
89
+
90
+ # Instance methods.
91
+ def instance_action_module
92
+ @instance_action_module ||= Module.new do
93
+
94
+ # Returns the <tt>Savon::Client</tt> from the class instance.
95
+ def client(&block)
96
+ self.class.client(&block)
97
+ end
98
+
99
+ end.tap { |mod| include(mod) }
100
+ end
101
+
102
+ end
103
+ end
@@ -0,0 +1,11 @@
1
+ require "savon/error"
2
+
3
+ module Savon
4
+ module SOAP
5
+ # = Savon::SOAP::InvalidResponseError
6
+ #
7
+ # Represents an error when the response was not a valid SOAP envelope.
8
+ class InvalidResponseError < Error
9
+ end
10
+ end
11
+ end