soap4r-middleware-192 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in soap4r-middleware.gemspec
4
+ gemspec
@@ -0,0 +1,61 @@
1
+ Soap4r Rack Middleware
2
+ ======================
3
+
4
+ This small library provides a Rack Middleware interface to exposing
5
+ Soap4r server endpoints. This is a lightweight alternative to using
6
+ ActionWebService for exposing SOAP in a Rails application, as well as
7
+ allowing SOAP endpoints in any other Rack-based application. It's been
8
+ tested with Rails 2.3.x, but should work fine in Rails 3 as well.
9
+
10
+ Install
11
+ -------
12
+
13
+ $ gem install soap4r-middleware
14
+
15
+ Usage
16
+ -----
17
+
18
+ First, get yourself some Soap4r endpoint code. The easiest way to do
19
+ this is to generate it from a WSDL file. Details are in the Soap4r
20
+ documentation, or see http://dev.ctor.org/soap4r/wiki/HowtouseWSDL4R ,
21
+ but basically:
22
+
23
+ $ wsdl2ruby.rb --wsdl /path/to/definiton.wsdl --type server
24
+
25
+ You'll get some generated files. One of them will be named
26
+ like `*APIService.rb`, near the bottom will be a class of the same name.
27
+ To enable middleware functionality, you want to copy this class'
28
+ initialization code into a new class that subclasses `Soap4r::Middleware::Base`, and replace the initialize method with a block passed to `setup`. For instance:
29
+
30
+ gem 'soap4r-middleware' # or use Bundler
31
+ require 'soap4r-middleware'
32
+
33
+ class MyAPIMiddleware < Soap4r::Middleware::Base
34
+ setup do
35
+ self.endpoint = %r{^/url/to/soap/endpoint/}
36
+ servant MyAPIPort.new
37
+ MyAPIPort::Methods.each do |definitions|
38
+ opt = definitions.last
39
+ if opt[:request_style] == :document
40
+ @router.add_document_operation(servant, *definitions)
41
+ else
42
+ @router.add_rpc_operation(servant, *definitions)
43
+ end
44
+ end
45
+ self.mapping_registry = UrnMyAPIMappingRegistry::EncodedRegistry
46
+ self.literal_mapping_registry = UrnMyAPIMappingRegistry::LiteralRegistry
47
+ end
48
+ end
49
+
50
+ Then use this middleware anywhere you'd use a Rack middleware. It
51
+ doubles as a Rack application as well, so you can host it directly using
52
+ `run MyAPIMiddleware.new` in your `rackup.ru` file.
53
+
54
+ ### TODO
55
+
56
+ I guess I could wrap `wsdl2ruby.rb` and make this automatic.
57
+
58
+ ### Wait, This is For Seriously??
59
+
60
+ Sometimes you just gotta SOAP. Might as well make it suck as little as
61
+ possible.
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,179 @@
1
+ require 'soap/rpc/router'
2
+
3
+ module Soap4r
4
+ module Middleware
5
+ include SOAP
6
+
7
+ def self.included(klass)
8
+ klass.send(:extend, ::Soap4r::Middleware::ClassMethods)
9
+ end
10
+
11
+ def initialize(app = nil)
12
+ @app = app
13
+ end
14
+
15
+ def call(env)
16
+ if env['PATH_INFO'].match(self.class.endpoint)
17
+ handle(env)
18
+ else
19
+ # we can act as both a middleware and an app
20
+ @app ?
21
+ @app.call(env) :
22
+ ( return 404, { "Content-Type" => "text/plain" }, ["404 - Not Found"] )
23
+ end
24
+ end
25
+
26
+ def handle(env)
27
+ # yeah, all soap calls are over POST
28
+ if env['REQUEST_METHOD'] != 'POST'
29
+ return 405, {
30
+ 'Allow' => 'POST',
31
+ 'Content-Type' => 'text/plain' }, ["405 - Method Not Allowed"]
32
+ end
33
+
34
+ conn_data = ::SOAP::StreamHandler::ConnectionData.new
35
+ setup_request(conn_data, env)
36
+ conn_data = self.class.router.route(conn_data)
37
+ status, headers, body = setup_response(conn_data, env)
38
+ [ status, headers, body ]
39
+ rescue
40
+ raise # TODO -- do we 500 right here, or let the exception bubble up?
41
+ end
42
+
43
+ def setup_request(conn_data, env)
44
+ # TODO: we're reading the whole input here, which kind of stinks if rack is
45
+ # reading from the client on demand. We can't just pass in the rack input
46
+ # object, since REXML needs an IO that responds to :eof? -- we'd need a
47
+ # wrapper IO-like object.
48
+ conn_data.receive_string = env['rack.input'].read
49
+ conn_data.receive_contenttype = env['CONTENT_TYPE']
50
+ conn_data.soapaction = parse_soapaction(env['HTTP_SOAPAction'])
51
+ end
52
+
53
+ def setup_response(conn_data, env)
54
+ status = 200
55
+ headers = {}
56
+ body = []
57
+ headers['content-type'] = conn_data.send_contenttype
58
+ # TODO: cookies?
59
+ if conn_data.is_nocontent
60
+ status = 202 # ACCEPTED
61
+ elsif conn_data.is_fault
62
+ # rather than sending the 500 here, let's bubble up the exception so the
63
+ # parent application can do with it what it will. The only downside is
64
+ # soap4r has already converted the exception into a soap response body at
65
+ # this point, which isn't what we want at all.
66
+ # maybe someday i'll re-parse the response or something. but not today.
67
+ raise conn_data.send_string
68
+ else
69
+ body << conn_data.send_string
70
+ end
71
+ return status, headers, body
72
+ end
73
+
74
+ def parse_soapaction(soapaction)
75
+ if !soapaction.nil? and !soapaction.empty?
76
+ if /\A"(.+)"\z/ =~ soapaction
77
+ return $1
78
+ end
79
+ end
80
+ nil
81
+ end
82
+
83
+ module ClassMethods
84
+ def setup
85
+ @router = ::SOAP::RPC::Router.new(self.class.name)
86
+ yield self
87
+ end
88
+
89
+ def router
90
+ @router
91
+ end
92
+
93
+ def endpoint=(regex)
94
+ @endpoint = regex
95
+ end
96
+
97
+ def endpoint
98
+ @endpoint
99
+ end
100
+
101
+ # SOAP interface
102
+
103
+ def mapping_registry
104
+ router.mapping_registry
105
+ end
106
+
107
+ def mapping_registry=(mapping_registry)
108
+ router.mapping_registry = mapping_registry
109
+ end
110
+
111
+ def literal_mapping_registry
112
+ router.literal_mapping_registry
113
+ end
114
+
115
+ def literal_mapping_registry=(literal_mapping_registry)
116
+ router.literal_mapping_registry = literal_mapping_registry
117
+ end
118
+
119
+ def generate_explicit_type
120
+ router.generate_explicit_type
121
+ end
122
+
123
+ def generate_explicit_type=(generate_explicit_type)
124
+ router.generate_explicit_type = generate_explicit_type
125
+ end
126
+
127
+ # servant entry interface
128
+
129
+ def add_rpc_servant(obj, namespace = self.default_namespace)
130
+ router.add_rpc_servant(obj, namespace)
131
+ end
132
+ alias add_servant add_rpc_servant
133
+
134
+ def add_headerhandler(obj)
135
+ router.add_headerhandler(obj)
136
+ end
137
+ alias add_rpc_headerhandler add_headerhandler
138
+
139
+ def filterchain
140
+ router.filterchain
141
+ end
142
+
143
+ # method entry interface
144
+
145
+ def add_rpc_method(obj, name, *param)
146
+ add_rpc_method_with_namespace_as(default_namespace, obj, name, name, *param)
147
+ end
148
+ alias add_method add_rpc_method
149
+
150
+ def add_rpc_method_as(obj, name, name_as, *param)
151
+ add_rpc_method_with_namespace_as(default_namespace, obj, name, name_as, *param)
152
+ end
153
+ alias add_method_as add_rpc_method_as
154
+
155
+ def add_rpc_method_with_namespace(namespace, obj, name, *param)
156
+ add_rpc_method_with_namespace_as(namespace, obj, name, name, *param)
157
+ end
158
+ alias add_method_with_namespace add_rpc_method_with_namespace
159
+
160
+ def add_rpc_method_with_namespace_as(namespace, obj, name, name_as, *param)
161
+ qname = XSD::QName.new(namespace, name_as)
162
+ soapaction = nil
163
+ param_def = SOAPMethod.derive_rpc_param_def(obj, name, *param)
164
+ router.add_rpc_operation(obj, qname, soapaction, name, param_def)
165
+ end
166
+ alias add_method_with_namespace_as add_rpc_method_with_namespace_as
167
+
168
+ def add_rpc_operation(receiver, qname, soapaction, name, param_def, opt = {})
169
+ router.add_rpc_operation(receiver, qname, soapaction, name, param_def, opt)
170
+ end
171
+
172
+ def add_document_operation(receiver, soapaction, name, param_def, opt = {})
173
+ router.add_document_operation(receiver, soapaction, name, param_def, opt)
174
+ end
175
+ end # ClassMethods
176
+ end
177
+ end
178
+
179
+ require 'soap4r-middleware/base'
@@ -0,0 +1,3 @@
1
+ class Soap4r::Middleware::Base
2
+ include ::Soap4r::Middleware
3
+ end
@@ -0,0 +1,5 @@
1
+ module Soap4r
2
+ module Middleware
3
+ VERSION = "0.8.2"
4
+ end
5
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "soap4r-middleware/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "soap4r-middleware-192"
7
+ s.version = Soap4r::Middleware::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Brian Palmer"]
10
+ s.email = ["brian@codekitchen.net"]
11
+ s.homepage = "https://www.github.com/codekitchen/soap4r-middleware"
12
+ s.summary = %q{Provides a Rack middleware for exposing SOAP server endpoints}
13
+ s.description = %q{Sometimes, you just gotta SOAP.}
14
+
15
+ s.rubyforge_project = "soap4r-middleware"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_dependency 'rubyjedi-soap4r', '~> 1.5'
23
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: soap4r-middleware-192
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.8.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Brian Palmer
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-10-06 00:00:00.000000000 +04:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rubyjedi-soap4r
17
+ requirement: &15804500 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: '1.5'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *15804500
26
+ description: Sometimes, you just gotta SOAP.
27
+ email:
28
+ - brian@codekitchen.net
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - .gitignore
34
+ - Gemfile
35
+ - README.md
36
+ - Rakefile
37
+ - lib/soap4r-middleware.rb
38
+ - lib/soap4r-middleware/base.rb
39
+ - lib/soap4r-middleware/version.rb
40
+ - soap4r-middleware.gemspec
41
+ has_rdoc: true
42
+ homepage: https://www.github.com/codekitchen/soap4r-middleware
43
+ licenses: []
44
+ post_install_message:
45
+ rdoc_options: []
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ! '>='
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ requirements: []
61
+ rubyforge_project: soap4r-middleware
62
+ rubygems_version: 1.6.2
63
+ signing_key:
64
+ specification_version: 3
65
+ summary: Provides a Rack middleware for exposing SOAP server endpoints
66
+ test_files: []