Welcome to the "trac"-ing site of soap4r!
[soap4r] [httpclient] [openpgp4u] [pkcs1] [logger] [csv] [vtr]

root/trunk/lib/soap/rpc/cgistub.rb

Revision 1829, 5.7 kB (checked in by nahi, 2 years ago)
  • SOAPlet generated a wrong cookie. fixed.
  • Property svn:eol-style set to native
  • Property svn:keywords set to author date id revision
Line 
1 # SOAP4R - CGI/mod_ruby stub library
2 # Copyright (C) 2000-2007  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
3
4 # This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
5 # redistribute it and/or modify it under the same terms of Ruby's license;
6 # either the dual license version in 2003, or any later version.
7
8
9 require 'soap/streamHandler'
10 require 'webrick/httpresponse'
11 require 'webrick/httpstatus'
12 require 'logger'
13 require 'soap/rpc/soaplet'
14
15
16 module SOAP
17 module RPC
18
19
20 ###
21 # SYNOPSIS
22 #   CGIStub.new
23 #
24 # DESCRIPTION
25 #   To be written...
26 #
27 class CGIStub < Logger::Application
28   include SOAP
29   include WEBrick
30
31   class SOAPRequest
32     attr_reader :body
33
34     def [](var); end
35
36     def meta_vars; end
37
38     EMPTY_COOKIES = [].freeze
39     def cookies; EMPTY_COOKIES; end
40
41     def user; end
42   end
43
44   class SOAPStdinRequest < SOAPRequest
45     attr_reader :body
46
47     def initialize(stream)
48       size = ENV['CONTENT_LENGTH'].to_i || 0
49       @body = stream.read(size)
50     end
51
52     def [](var)
53       ENV[var.gsub(/-/, '_').upcase]
54     end
55
56     def meta_vars
57       {
58         'HTTP_SOAPACTION' => ENV['HTTP_SOAPAction']
59       }
60     end
61
62     def cookies
63       if cookie = ENV['HTTP_Cookie'] || ENV['Cookie']
64         [WEBrick::Cookie.parse(cookie)]
65       else
66         EMPTY_COOKIES
67       end
68     end
69
70     def user
71       ENV['REMOTE_USER']
72     end
73   end
74
75   class SOAPFCGIRequest < SOAPRequest
76     attr_reader :body
77
78     def initialize(request)
79       @request = request
80       @body = @request.in.read
81     end
82
83     def [](var)
84       @request.env[var.gsub(/-/, '_').upcase]
85     end
86
87     def meta_vars
88       {
89         'HTTP_SOAPACTION' => @request.env['HTTP_SOAPAction']
90       }
91     end
92
93     def cookies
94       if cookie = @request.env['HTTP_Cookie'] || @request.env['Cookie']
95         [WEBrick::Cookie.parse(cookie)]
96       else
97         EMPTY_COOKIES
98       end
99     end
100
101     def user
102       @request.env['REMOTE_USER']
103     end
104   end
105
106   def initialize(appname, default_namespace)
107     super(appname)
108     set_log(STDERR)
109     self.level = ERROR
110     @default_namespace = default_namespace
111     @remote_host = ENV['REMOTE_HOST'] || ENV['REMOTE_ADDR'] || 'unknown'
112     @router = ::SOAP::RPC::Router.new(self.class.name)
113     @soaplet = ::SOAP::RPC::SOAPlet.new(@router)
114     on_init
115   end
116  
117   def on_init
118     # do extra initialization in a derived class if needed.
119   end
120
121   def mapping_registry
122     @router.mapping_registry
123   end
124
125   def mapping_registry=(mapping_registry)
126     @router.mapping_registry = mapping_registry
127   end
128
129   def literal_mapping_registry
130     @router.literal_mapping_registry
131   end
132
133   def literal_mapping_registry=(literal_mapping_registry)
134     @router.literal_mapping_registry = literal_mapping_registry
135   end
136
137   def generate_explicit_type
138     @router.generate_explicit_type
139   end
140
141   def generate_explicit_type=(generate_explicit_type)
142     @router.generate_explicit_type = generate_explicit_type
143   end
144
145   # servant entry interface
146
147   def add_rpc_servant(obj, namespace = @default_namespace)
148     @router.add_rpc_servant(obj, namespace)
149   end
150   alias add_servant add_rpc_servant
151
152   def add_headerhandler(obj)
153     @router.add_headerhandler(obj)
154   end
155   alias add_rpc_headerhandler add_headerhandler
156
157   def filterchain
158     @router.filterchain
159   end
160
161   # method entry interface
162
163   def add_rpc_method(obj, name, *param)
164     add_rpc_method_with_namespace_as(@default_namespace, obj, name, name, *param)
165   end
166   alias add_method add_rpc_method
167
168   def add_rpc_method_as(obj, name, name_as, *param)
169     add_rpc_method_with_namespace_as(@default_namespace, obj, name, name_as, *param)
170   end
171   alias add_method_as add_rpc_method_as
172
173   def add_rpc_method_with_namespace(namespace, obj, name, *param)
174     add_rpc_method_with_namespace_as(namespace, obj, name, name, *param)
175   end
176   alias add_method_with_namespace add_rpc_method_with_namespace
177
178   def add_rpc_method_with_namespace_as(namespace, obj, name, name_as, *param)
179     qname = XSD::QName.new(namespace, name_as)
180     soapaction = nil
181     param_def = SOAPMethod.derive_rpc_param_def(obj, name, *param)
182     @router.add_rpc_operation(obj, qname, soapaction, name, param_def)
183   end
184   alias add_method_with_namespace_as add_rpc_method_with_namespace_as
185
186   def add_rpc_operation(receiver, qname, soapaction, name, param_def, opt = {})
187     @router.add_rpc_operation(receiver, qname, soapaction, name, param_def, opt)
188   end
189
190   def add_document_operation(receiver, soapaction, name, param_def, opt = {})
191     @router.add_document_operation(receiver, soapaction, name, param_def, opt)
192   end
193
194   def set_fcgi_request(request)
195     @fcgi = request
196   end
197
198 private
199
200   HTTPVersion = WEBrick::HTTPVersion.new('1.0')       # dummy; ignored
201
202   def run
203     res = WEBrick::HTTPResponse.new({:HTTPVersion => HTTPVersion})
204     begin
205       @log.info { "received a request from '#{ @remote_host }'" }
206       if @fcgi
207         req = SOAPFCGIRequest.new(@fcgi)
208       else
209         req = SOAPStdinRequest.new($stdin)
210       end
211       @soaplet.do_POST(req, res)
212     rescue HTTPStatus::EOFError, HTTPStatus::RequestTimeout => ex
213       res.set_error(ex)
214     rescue HTTPStatus::Error => ex
215       res.set_error(ex)
216     rescue HTTPStatus::Status => ex
217       res.status = ex.code
218     rescue StandardError, NameError => ex # for Ruby 1.6
219       res.set_error(ex, true)
220     ensure
221       if defined?(MOD_RUBY)
222         r = Apache.request
223         r.status = res.status
224         r.content_type = res.content_type
225         r.send_http_header
226         buf = res.body
227       else
228         buf = ''
229         res.send_response(buf)
230         buf.sub!(/^[^\r]+\r\n/, '')       # Trim status line.
231       end
232       @log.debug { "SOAP CGI Response:\n#{ buf }" }
233       if @fcgi
234         @fcgi.out.print buf
235         @fcgi.finish
236         @fcgi = nil
237       else
238         print buf
239       end
240     end
241     0
242   end
243 end
244
245
246 end
247 end
Note: See TracBrowser for help on using the browser.