rubysl-xmlrpc 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,146 +1,7 @@
1
- =begin
2
- = xmlrpc/server.rb
3
- Copyright (C) 2001, 2002, 2003, 2005 by Michael Neumann (mneumann@ntecs.de)
4
-
5
- Released under the same term of license as Ruby.
6
-
7
- = Classes
8
- * ((<XMLRPC::BasicServer>))
9
- * ((<XMLRPC::CGIServer>))
10
- * ((<XMLRPC::ModRubyServer>))
11
- * ((<XMLRPC::Server>))
12
- * ((<XMLRPC::WEBrickServlet>))
13
-
14
- = XMLRPC::BasicServer
15
- == Description
16
- Is the base class for all XML-RPC server-types (CGI, standalone).
17
- You can add handler and set a default handler.
18
- Do not use this server, as this is/should be an abstract class.
19
-
20
- === How the method to call is found
21
- The arity (number of accepted arguments) of a handler (method or (({Proc})) object) is
22
- compared to the given arguments submitted by the client for a RPC ((-Remote Procedure Call-)).
23
- A handler is only called if it accepts the number of arguments, otherwise the search
24
- for another handler will go on. When at the end no handler was found,
25
- the ((<default_handler|XMLRPC::BasicServer#set_default_handler>)) will be called.
26
- With this technique it is possible to do overloading by number of parameters, but
27
- only for (({Proc})) handler, because you cannot define two methods of the same name in
28
- the same class.
29
-
30
-
31
- == Class Methods
32
- --- XMLRPC::BasicServer.new( class_delim="." )
33
- Creates a new (({XMLRPC::BasicServer})) instance, which should not be
34
- done, because (({XMLRPC::BasicServer})) is an abstract class. This
35
- method should be called from a subclass indirectly by a (({super})) call
36
- in the method (({initialize})). The paramter ((|class_delim|)) is used
37
- in ((<add_handler|XMLRPC::BasicServer#add_handler>)) when an object is
38
- added as handler, to delimit the object-prefix and the method-name.
39
-
40
- == Instance Methods
41
- --- XMLRPC::BasicServer#add_handler( name, signature=nil, help=nil ) { aBlock }
42
- Adds ((|aBlock|)) to the list of handlers, with ((|name|)) as the name of the method.
43
- Parameters ((|signature|)) and ((|help|)) are used by the Introspection method if specified,
44
- where ((|signature|)) is either an Array containing strings each representing a type of it's
45
- signature (the first is the return value) or an Array of Arrays if the method has multiple
46
- signatures. Value type-names are "int, boolean, double, string, dateTime.iso8601, base64, array, struct".
47
-
48
- Parameter ((|help|)) is a String with informations about how to call this method etc.
49
-
50
- A handler method or code-block can return the types listed at
51
- ((<XMLRPC::Client#call|URL:client.html#index:0>)).
52
- When a method fails, it can tell it the client by throwing an
53
- (({XMLRPC::FaultException})) like in this example:
54
- s.add_handler("michael.div") do |a,b|
55
- if b == 0
56
- raise XMLRPC::FaultException.new(1, "division by zero")
57
- else
58
- a / b
59
- end
60
- end
61
- The client gets in the case of (({b==0})) an object back of type
62
- (({XMLRPC::FaultException})) that has a ((|faultCode|)) and ((|faultString|))
63
- field.
64
-
65
- --- XMLRPC::BasicServer#add_handler( prefix, obj )
66
- This is the second form of ((<add_handler|XMLRPC::BasicServer#add_handler>)).
67
- To add an object write:
68
- server.add_handler("michael", MyHandlerClass.new)
69
- All public methods of (({MyHandlerClass})) are accessible to
70
- the XML-RPC clients by (('michael."name of method"')). This is
71
- where the ((|class_delim|)) in ((<new|XMLRPC::BasicServer.new>))
72
- has it's role, a XML-RPC method-name is defined by
73
- ((|prefix|)) + ((|class_delim|)) + (('"name of method"')).
74
-
75
- --- XMLRPC::BasicServer#add_handler( interface, obj )
76
- This is the third form of ((<add_handler|XMLRPC::BasicServer#add_handler>)).
77
-
78
- Use (({XMLRPC::interface})) to generate an ServiceInterface object, which
79
- represents an interface (with signature and help text) for a handler class.
80
-
81
- Parameter ((|interface|)) must be of type (({XMLRPC::ServiceInterface})).
82
- Adds all methods of ((|obj|)) which are defined in ((|interface|)) to the
83
- server.
84
-
85
- This is the recommended way of adding services to a server!
86
-
87
-
88
- --- XMLRPC::BasicServer#get_default_handler
89
- Returns the default-handler, which is called when no handler for
90
- a method-name is found.
91
- It is a (({Proc})) object or (({nil})).
92
-
93
- --- XMLRPC::BasicServer#set_default_handler ( &handler )
94
- Sets ((|handler|)) as the default-handler, which is called when
95
- no handler for a method-name is found. ((|handler|)) is a code-block.
96
- The default-handler is called with the (XML-RPC) method-name as first argument, and
97
- the other arguments are the parameters given by the client-call.
98
-
99
- If no block is specified the default of (({XMLRPC::BasicServer})) is used, which raises a
100
- XMLRPC::FaultException saying "method missing".
101
-
102
-
103
- --- XMLRPC::BasicServer#set_writer( writer )
104
- Sets the XML writer to use for generating XML output.
105
- Should be an instance of a class from module (({XMLRPC::XMLWriter})).
106
- If this method is not called, then (({XMLRPC::Config::DEFAULT_WRITER})) is used.
107
-
108
- --- XMLRPC::BasicServer#set_parser( parser )
109
- Sets the XML parser to use for parsing XML documents.
110
- Should be an instance of a class from module (({XMLRPC::XMLParser})).
111
- If this method is not called, then (({XMLRPC::Config::DEFAULT_PARSER})) is used.
112
-
113
- --- XMLRPC::BasicServer#add_introspection
114
- Adds the introspection handlers "system.listMethods", "system.methodSignature" and "system.methodHelp",
115
- where only the first one works.
116
-
117
- --- XMLRPC::BasicServer#add_multicall
118
- Adds the multi-call handler "system.multicall".
119
-
120
- --- XMLRPC::BasicServer#get_service_hook
121
- Returns the service-hook, which is called on each service request (RPC) unless it's (({nil})).
122
-
123
- --- XMLRPC::BasicServer#set_service_hook ( &handler )
124
- A service-hook is called for each service request (RPC).
125
- You can use a service-hook for example to wrap existing methods and catch exceptions of them or
126
- convert values to values recognized by XMLRPC. You can disable it by passing (({nil})) as parameter
127
- ((|handler|)) .
128
-
129
- The service-hook is called with a (({Proc})) object and with the parameters for this (({Proc})).
130
- An example:
131
-
132
- server.set_service_hook {|obj, *args|
133
- begin
134
- ret = obj.call(*args) # call the original service-method
135
- # could convert the return value
136
- resuce
137
- # rescue exceptions
138
- end
139
- }
140
-
141
- =end
142
-
143
-
1
+ # xmlrpc/server.rb
2
+ # Copyright (C) 2001, 2002, 2003, 2005 by Michael Neumann (mneumann@ntecs.de)
3
+ #
4
+ # Released under the same term of license as Ruby.
144
5
 
145
6
  require "xmlrpc/parser"
146
7
  require "xmlrpc/create"
@@ -149,15 +10,32 @@ require "xmlrpc/utils" # ParserWriterChooseMixin
149
10
 
150
11
 
151
12
 
152
- module XMLRPC
13
+ module XMLRPC # :nodoc:
153
14
 
154
15
 
16
+ # This is the base class for all XML-RPC server-types (CGI, standalone).
17
+ # You can add handler and set a default handler.
18
+ # Do not use this server, as this is/should be an abstract class.
19
+ #
20
+ # === How the method to call is found
21
+ # The arity (number of accepted arguments) of a handler (method or Proc
22
+ # object) is compared to the given arguments submitted by the client for a
23
+ # RPC, or Remote Procedure Call.
24
+ #
25
+ # A handler is only called if it accepts the number of arguments, otherwise
26
+ # the search for another handler will go on. When at the end no handler was
27
+ # found, the default_handler, XMLRPC::BasicServer#set_default_handler will be
28
+ # called.
29
+ #
30
+ # With this technique it is possible to do overloading by number of parameters, but
31
+ # only for Proc handler, because you cannot define two methods of the same name in
32
+ # the same class.
155
33
  class BasicServer
156
34
 
157
35
  include ParserWriterChooseMixin
158
36
  include ParseContentType
159
37
 
160
- ERR_METHOD_MISSING = 1
38
+ ERR_METHOD_MISSING = 1
161
39
  ERR_UNCAUGHT_EXCEPTION = 2
162
40
  ERR_MC_WRONG_PARAM = 3
163
41
  ERR_MC_MISSING_PARAMS = 4
@@ -167,9 +45,17 @@ class BasicServer
167
45
  ERR_MC_EXPECTED_STRUCT = 8
168
46
 
169
47
 
48
+ # Creates a new XMLRPC::BasicServer instance, which should not be
49
+ # done, because XMLRPC::BasicServer is an abstract class. This
50
+ # method should be called from a subclass indirectly by a +super+ call
51
+ # in the initialize method.
52
+ #
53
+ # The paramter +class_delim+ is used by add_handler, see
54
+ # XMLRPC::BasicServer#add_handler, when an object is added as a handler, to
55
+ # delimit the object-prefix and the method-name.
170
56
  def initialize(class_delim=".")
171
57
  @handler = []
172
- @default_handler = nil
58
+ @default_handler = nil
173
59
  @service_hook = nil
174
60
 
175
61
  @class_delim = class_delim
@@ -180,10 +66,56 @@ class BasicServer
180
66
  add_introspection if Config::ENABLE_INTROSPECTION
181
67
  end
182
68
 
69
+ # Adds +aBlock+ to the list of handlers, with +name+ as the name of
70
+ # the method.
71
+ #
72
+ # Parameters +signature+ and +help+ are used by the Introspection method if
73
+ # specified, where +signature+ is either an Array containing strings each
74
+ # representing a type of it's signature (the first is the return value) or
75
+ # an Array of Arrays if the method has multiple signatures.
76
+ #
77
+ # Value type-names are "int, boolean, double, string, dateTime.iso8601,
78
+ # base64, array, struct".
79
+ #
80
+ # Parameter +help+ is a String with information about how to call this method etc.
81
+ #
82
+ # When a method fails, it can tell the client by throwing an
83
+ # XMLRPC::FaultException like in this example:
84
+ #
85
+ # s.add_handler("michael.div") do |a,b|
86
+ # if b == 0
87
+ # raise XMLRPC::FaultException.new(1, "division by zero")
88
+ # else
89
+ # a / b
90
+ # end
91
+ # end
92
+ #
93
+ # In the case of <code>b==0</code> the client gets an object back of type
94
+ # XMLRPC::FaultException that has a +faultCode+ and +faultString+ field.
95
+ #
96
+ # This is the second form of ((<add_handler|XMLRPC::BasicServer#add_handler>)).
97
+ # To add an object write:
98
+ #
99
+ # server.add_handler("michael", MyHandlerClass.new)
100
+ #
101
+ # All public methods of MyHandlerClass are accessible to
102
+ # the XML-RPC clients by <code>michael."name of method"</code>. This is
103
+ # where the +class_delim+ in XMLRPC::BasicServer.new plays it's role, a
104
+ # XML-RPC method-name is defined by +prefix+ + +class_delim+ + <code>"name
105
+ # of method"</code>.
106
+ #
107
+ # The third form of +add_handler is to use XMLRPC::Service::Interface to
108
+ # generate an object, which represents an interface (with signature and
109
+ # help text) for a handler class.
110
+ #
111
+ # The +interface+ parameter must be an instance of XMLRPC::Service::Interface.
112
+ # Adds all methods of +obj+ which are defined in the +interface+ to the server.
113
+ #
114
+ # This is the recommended way of adding services to a server!
183
115
  def add_handler(prefix, obj_or_signature=nil, help=nil, &block)
184
116
  if block_given?
185
117
  # proc-handler
186
- @handler << [prefix, block, obj_or_signature, help]
118
+ @handler << [prefix, block, obj_or_signature, help]
187
119
  else
188
120
  if prefix.kind_of? String
189
121
  # class-handler
@@ -200,34 +132,72 @@ class BasicServer
200
132
  self
201
133
  end
202
134
 
135
+ # Returns the service-hook, which is called on each service request (RPC)
136
+ # unless it's +nil+.
203
137
  def get_service_hook
204
138
  @service_hook
205
139
  end
206
140
 
141
+ # A service-hook is called for each service request (RPC).
142
+ #
143
+ # You can use a service-hook for example to wrap existing methods and catch
144
+ # exceptions of them or convert values to values recognized by XMLRPC.
145
+ #
146
+ # You can disable it by passing +nil+ as the +handler+ parameter.
147
+ #
148
+ # The service-hook is called with a Proc object along with any parameters.
149
+ #
150
+ # An example:
151
+ #
152
+ # server.set_service_hook {|obj, *args|
153
+ # begin
154
+ # ret = obj.call(*args) # call the original service-method
155
+ # # could convert the return value
156
+ # rescue
157
+ # # rescue exceptions
158
+ # end
159
+ # }
160
+ #
207
161
  def set_service_hook(&handler)
208
162
  @service_hook = handler
209
163
  self
210
164
  end
211
-
165
+
166
+ # Returns the default-handler, which is called when no handler for
167
+ # a method-name is found.
168
+ #
169
+ # It is either a Proc object or +nil+.
212
170
  def get_default_handler
213
171
  @default_handler
214
172
  end
215
173
 
216
- def set_default_handler (&handler)
174
+ # Sets +handler+ as the default-handler, which is called when
175
+ # no handler for a method-name is found.
176
+ #
177
+ # +handler+ is a code-block.
178
+ #
179
+ # The default-handler is called with the (XML-RPC) method-name as first
180
+ # argument, and the other arguments are the parameters given by the
181
+ # client-call.
182
+ #
183
+ # If no block is specified the default of XMLRPC::BasicServer is
184
+ # used, which raises a XMLRPC::FaultException saying "method missing".
185
+ def set_default_handler(&handler)
217
186
  @default_handler = handler
218
187
  self
219
- end
188
+ end
220
189
 
190
+ # Adds the multi-call handler <code>"system.multicall"</code>.
221
191
  def add_multicall
222
192
  add_handler("system.multicall", %w(array array), "Multicall Extension") do |arrStructs|
223
- unless arrStructs.is_a? Array
193
+ unless arrStructs.is_a? Array
224
194
  raise XMLRPC::FaultException.new(ERR_MC_WRONG_PARAM, "system.multicall expects an array")
225
195
  end
226
196
 
227
197
  arrStructs.collect {|call|
228
198
  if call.is_a? Hash
229
199
  methodName = call["methodName"]
230
- params = call["params"]
200
+ params = call["params"]
231
201
 
232
202
  if params.nil?
233
203
  multicall_fault(ERR_MC_MISSING_PARAMS, "Missing params")
@@ -246,20 +216,23 @@ class BasicServer
246
216
  [val]
247
217
  else
248
218
  # exception
249
- multicall_fault(val.faultCode, val.faultString)
219
+ multicall_fault(val.faultCode, val.faultString)
250
220
  end
251
221
  end
252
222
  end
253
- end
254
-
223
+ end
224
+
255
225
  else
256
226
  multicall_fault(ERR_MC_EXPECTED_STRUCT, "system.multicall expected struct")
257
227
  end
258
- }
228
+ }
259
229
  end # end add_handler
260
230
  self
261
231
  end
262
232
 
233
+ # Adds the introspection handlers <code>"system.listMethods"</code>,
234
+ # <code>"system.methodSignature"</code> and
235
+ # <code>"system.methodHelp"</code>, where only the first one works.
263
236
  def add_introspection
264
237
  add_handler("system.listMethods",%w(array), "List methods available on this XML-RPC server") do
265
238
  methods = []
@@ -284,7 +257,7 @@ class BasicServer
284
257
  sig.each {|s| sigs << s}
285
258
  else
286
259
  # sig is a single signature, e.g. ["array"]
287
- sigs << sig
260
+ sigs << sig
288
261
  end
289
262
  end
290
263
  end
@@ -292,11 +265,11 @@ class BasicServer
292
265
  end
293
266
 
294
267
  add_handler("system.methodHelp", %w(string string), "Returns help on using this method") do |meth|
295
- help = nil
268
+ help = nil
296
269
  @handler.each do |name, obj, sig, hlp|
297
- if obj.kind_of? Proc and name == meth
270
+ if obj.kind_of? Proc and name == meth
298
271
  help = hlp
299
- break
272
+ break
300
273
  end
301
274
  end
302
275
  help || ""
@@ -306,21 +279,18 @@ class BasicServer
306
279
  end
307
280
 
308
281
 
309
-
282
+
310
283
  def process(data)
311
- method, params = parser().parseMethodCall(data)
284
+ method, params = parser().parseMethodCall(data)
312
285
  handle(method, *params)
313
286
  end
314
-
315
- private # --------------------------------------------------------------
287
+
288
+ private
316
289
 
317
290
  def multicall_fault(nr, str)
318
291
  {"faultCode" => nr, "faultString" => str}
319
292
  end
320
-
321
- #
322
- # method dispatch
323
- #
293
+
324
294
  def dispatch(methodname, *args)
325
295
  for name, obj in @handler
326
296
  if obj.kind_of? Proc
@@ -333,31 +303,29 @@ class BasicServer
333
303
 
334
304
  if check_arity(obj, args.size)
335
305
  if @service_hook.nil?
336
- return obj.call(*args)
306
+ return obj.call(*args)
337
307
  else
338
308
  return @service_hook.call(obj, *args)
339
309
  end
340
310
  end
341
- end
342
-
311
+ end
312
+
343
313
  if @default_handler.nil?
344
314
  raise XMLRPC::FaultException.new(ERR_METHOD_MISSING, "Method #{methodname} missing or wrong number of parameters!")
345
315
  else
346
- @default_handler.call(methodname, *args)
316
+ @default_handler.call(methodname, *args)
347
317
  end
348
318
  end
349
319
 
350
320
 
351
- #
352
- # returns true, if the arity of "obj" matches
353
- #
321
+ # Returns +true+, if the arity of +obj+ matches +n_args+
354
322
  def check_arity(obj, n_args)
355
323
  ary = obj.arity
356
324
 
357
325
  if ary >= 0
358
326
  n_args == ary
359
327
  else
360
- n_args >= (ary+1).abs
328
+ n_args >= (ary+1).abs
361
329
  end
362
330
  end
363
331
 
@@ -366,16 +334,13 @@ class BasicServer
366
334
  def call_method(methodname, *args)
367
335
  begin
368
336
  [true, dispatch(methodname, *args)]
369
- rescue XMLRPC::FaultException => e
370
- [false, e]
337
+ rescue XMLRPC::FaultException => e
338
+ [false, e]
371
339
  rescue Exception => e
372
340
  [false, XMLRPC::FaultException.new(ERR_UNCAUGHT_EXCEPTION, "Uncaught exception #{e.message} in method #{methodname}")]
373
341
  end
374
342
  end
375
343
 
376
- #
377
- #
378
- #
379
344
  def handle(methodname, *args)
380
345
  create().methodResponse(*call_method(methodname, *args))
381
346
  end
@@ -384,57 +349,44 @@ class BasicServer
384
349
  end
385
350
 
386
351
 
387
- =begin
388
- = XMLRPC::CGIServer
389
- == Synopsis
390
- require "xmlrpc/server"
391
-
392
- s = XMLRPC::CGIServer.new
393
-
394
- s.add_handler("michael.add") do |a,b|
395
- a + b
396
- end
397
-
398
- s.add_handler("michael.div") do |a,b|
399
- if b == 0
400
- raise XMLRPC::FaultException.new(1, "division by zero")
401
- else
402
- a / b
403
- end
404
- end
405
-
406
- s.set_default_handler do |name, *args|
407
- raise XMLRPC::FaultException.new(-99, "Method #{name} missing" +
408
- " or wrong number of parameters!")
409
- end
410
-
411
- s.serve
412
-
413
- == Description
414
- Implements a CGI-based XML-RPC server.
415
-
416
- == Superclass
417
- ((<XMLRPC::BasicServer>))
418
-
419
- == Class Methods
420
- --- XMLRPC::CGIServer.new( *a )
421
- Creates a new (({XMLRPC::CGIServer})) instance. All parameters given
422
- are by-passed to ((<XMLRPC::BasicServer.new>)). You can only create
423
- ((*one*)) (({XMLRPC::CGIServer})) instance, because more than one makes
424
- no sense.
425
-
426
- == Instance Methods
427
- --- XMLRPC::CGIServer#serve
428
- Call this after you have added all you handlers to the server.
429
- This method processes a XML-RPC methodCall and sends the answer
430
- back to the client.
431
- Make sure that you don't write to standard-output in a handler, or in
432
- any other part of your program, this would case a CGI-based server to fail!
433
- =end
434
-
352
+ # Implements a CGI-based XML-RPC server.
353
+ #
354
+ # require "xmlrpc/server"
355
+ #
356
+ # s = XMLRPC::CGIServer.new
357
+ #
358
+ # s.add_handler("michael.add") do |a,b|
359
+ # a + b
360
+ # end
361
+ #
362
+ # s.add_handler("michael.div") do |a,b|
363
+ # if b == 0
364
+ # raise XMLRPC::FaultException.new(1, "division by zero")
365
+ # else
366
+ # a / b
367
+ # end
368
+ # end
369
+ #
370
+ # s.set_default_handler do |name, *args|
371
+ # raise XMLRPC::FaultException.new(-99, "Method #{name} missing" +
372
+ # " or wrong number of parameters!")
373
+ # end
374
+ #
375
+ # s.serve
376
+ #
377
+ #
378
+ # <b>Note:</b> Make sure that you don't write to standard-output in a
379
+ # handler, or in any other part of your program, this would cause a CGI-based
380
+ # server to fail!
435
381
  class CGIServer < BasicServer
436
382
  @@obj = nil
437
383
 
384
+ # Creates a new XMLRPC::CGIServer instance.
385
+ #
386
+ # All parameters given are by-passed to XMLRPC::BasicServer.new.
387
+ #
388
+ # You can only create <b>one</b> XMLRPC::CGIServer instance, because more
389
+ # than one makes no sense.
438
390
  def CGIServer.new(*a)
439
391
  @@obj = super(*a) if @@obj.nil?
440
392
  @@obj
@@ -443,20 +395,24 @@ class CGIServer < BasicServer
443
395
  def initialize(*a)
444
396
  super(*a)
445
397
  end
446
-
398
+
399
+ # Call this after you have added all you handlers to the server.
400
+ #
401
+ # This method processes a XML-RPC method call and sends the answer
402
+ # back to the client.
447
403
  def serve
448
404
  catch(:exit_serve) {
449
405
  length = ENV['CONTENT_LENGTH'].to_i
450
406
 
451
- http_error(405, "Method Not Allowed") unless ENV['REQUEST_METHOD'] == "POST"
407
+ http_error(405, "Method Not Allowed") unless ENV['REQUEST_METHOD'] == "POST"
452
408
  http_error(400, "Bad Request") unless parse_content_type(ENV['CONTENT_TYPE']).first == "text/xml"
453
- http_error(411, "Length Required") unless length > 0
409
+ http_error(411, "Length Required") unless length > 0
454
410
 
455
411
  # TODO: do we need a call to binmode?
456
412
  $stdin.binmode if $stdin.respond_to? :binmode
457
413
  data = $stdin.read(length)
458
414
 
459
- http_error(400, "Bad Request") if data.nil? or data.size != length
415
+ http_error(400, "Bad Request") if data.nil? or data.bytesize != length
460
416
 
461
417
  http_write(process(data), "Content-type" => "text/xml; charset=utf-8")
462
418
  }
@@ -467,7 +423,7 @@ class CGIServer < BasicServer
467
423
 
468
424
  def http_error(status, message)
469
425
  err = "#{status} #{message}"
470
- msg = <<-"MSGEND"
426
+ msg = <<-"MSGEND"
471
427
  <html>
472
428
  <head>
473
429
  <title>#{err}</title>
@@ -487,7 +443,7 @@ class CGIServer < BasicServer
487
443
  h = {}
488
444
  header.each {|key, value| h[key.to_s.capitalize] = value}
489
445
  h['Status'] ||= "200 OK"
490
- h['Content-length'] ||= body.size.to_s
446
+ h['Content-length'] ||= body.bytesize.to_s
491
447
 
492
448
  str = ""
493
449
  h.each {|key, value| str << "#{key}: #{value}\r\n"}
@@ -498,24 +454,24 @@ class CGIServer < BasicServer
498
454
 
499
455
  end
500
456
 
501
- =begin
502
- = XMLRPC::ModRubyServer
503
- == Description
504
- Implements a XML-RPC server, which works with Apache mod_ruby.
505
-
506
- Use it in the same way as CGIServer!
507
-
508
- == Superclass
509
- ((<XMLRPC::BasicServer>))
510
- =end
511
457
 
458
+ # Implements a XML-RPC server, which works with Apache mod_ruby.
459
+ #
460
+ # Use it in the same way as XMLRPC::CGIServer!
512
461
  class ModRubyServer < BasicServer
513
462
 
463
+ # Creates a new XMLRPC::ModRubyServer instance.
464
+ #
465
+ # All parameters given are by-passed to XMLRPC::BasicServer.new.
514
466
  def initialize(*a)
515
467
  @ap = Apache::request
516
468
  super(*a)
517
469
  end
518
470
 
471
+ # Call this after you have added all you handlers to the server.
472
+ #
473
+ # This method processes a XML-RPC method call and sends the answer
474
+ # back to the client.
519
475
  def serve
520
476
  catch(:exit_serve) {
521
477
  header = {}
@@ -523,15 +479,15 @@ class ModRubyServer < BasicServer
523
479
 
524
480
  length = header['Content-length'].to_i
525
481
 
526
- http_error(405, "Method Not Allowed") unless @ap.request_method == "POST"
482
+ http_error(405, "Method Not Allowed") unless @ap.request_method == "POST"
527
483
  http_error(400, "Bad Request") unless parse_content_type(header['Content-type']).first == "text/xml"
528
- http_error(411, "Length Required") unless length > 0
484
+ http_error(411, "Length Required") unless length > 0
529
485
 
530
486
  # TODO: do we need a call to binmode?
531
487
  @ap.binmode
532
488
  data = @ap.read(length)
533
489
 
534
- http_error(400, "Bad Request") if data.nil? or data.size != length
490
+ http_error(400, "Bad Request") if data.nil? or data.bytesize != length
535
491
 
536
492
  http_write(process(data), 200, "Content-type" => "text/xml; charset=utf-8")
537
493
  }
@@ -542,7 +498,7 @@ class ModRubyServer < BasicServer
542
498
 
543
499
  def http_error(status, message)
544
500
  err = "#{status} #{message}"
545
- msg = <<-"MSGEND"
501
+ msg = <<-"MSGEND"
546
502
  <html>
547
503
  <head>
548
504
  <title>#{err}</title>
@@ -562,148 +518,112 @@ class ModRubyServer < BasicServer
562
518
  h = {}
563
519
  header.each {|key, value| h[key.to_s.capitalize] = value}
564
520
  h['Status'] ||= "200 OK"
565
- h['Content-length'] ||= body.size.to_s
521
+ h['Content-length'] ||= body.bytesize.to_s
566
522
 
567
523
  h.each {|key, value| @ap.headers_out[key] = value }
568
- @ap.content_type = h["Content-type"]
569
- @ap.status = status.to_i
570
- @ap.send_http_header
524
+ @ap.content_type = h["Content-type"]
525
+ @ap.status = status.to_i
526
+ @ap.send_http_header
571
527
 
572
528
  @ap.print body
573
529
  end
574
530
 
575
531
  end
576
532
 
577
- =begin
578
- = XMLRPC::Server
579
- == Synopsis
580
- require "xmlrpc/server"
581
-
582
- s = XMLRPC::Server.new(8080)
583
-
584
- s.add_handler("michael.add") do |a,b|
585
- a + b
586
- end
587
-
588
- s.add_handler("michael.div") do |a,b|
589
- if b == 0
590
- raise XMLRPC::FaultException.new(1, "division by zero")
591
- else
592
- a / b
593
- end
594
- end
595
-
596
- s.set_default_handler do |name, *args|
597
- raise XMLRPC::FaultException.new(-99, "Method #{name} missing" +
598
- " or wrong number of parameters!")
599
- end
600
-
601
- s.serve
602
-
603
- == Description
604
- Implements a standalone XML-RPC server. The method (({serve}))) is left if a SIGHUP is sent to the
605
- program.
606
-
607
- == Superclass
608
- ((<XMLRPC::WEBrickServlet>))
609
-
610
- == Class Methods
611
- --- XMLRPC::Server.new( port=8080, host="127.0.0.1", maxConnections=4, stdlog=$stdout, audit=true, debug=true, *a )
612
- Creates a new (({XMLRPC::Server})) instance, which is a XML-RPC server listening on
613
- port ((|port|)) and accepts requests for the host ((|host|)), which is by default only the localhost.
614
- The server is not started, to start it you have to call ((<serve|XMLRPC::Server#serve>)).
615
-
616
- Parameters ((|audit|)) and ((|debug|)) are obsolete!
617
-
618
- All additionally given parameters in ((|*a|)) are by-passed to ((<XMLRPC::BasicServer.new>)).
619
-
620
- == Instance Methods
621
- --- XMLRPC::Server#serve
622
- Call this after you have added all you handlers to the server.
623
- This method starts the server to listen for XML-RPC requests and answer them.
624
-
625
- --- XMLRPC::Server#shutdown
626
- Stops and shuts the server down.
627
-
628
- =end
629
533
 
630
534
  class WEBrickServlet < BasicServer; end # forward declaration
631
535
 
536
+ # Implements a standalone XML-RPC server. The method XMLRPC::Server#serve is
537
+ # left if a SIGHUP is sent to the program.
538
+ #
539
+ # require "xmlrpc/server"
540
+ #
541
+ # s = XMLRPC::Server.new(8080)
542
+ #
543
+ # s.add_handler("michael.add") do |a,b|
544
+ # a + b
545
+ # end
546
+ #
547
+ # s.add_handler("michael.div") do |a,b|
548
+ # if b == 0
549
+ # raise XMLRPC::FaultException.new(1, "division by zero")
550
+ # else
551
+ # a / b
552
+ # end
553
+ # end
554
+ #
555
+ # s.set_default_handler do |name, *args|
556
+ # raise XMLRPC::FaultException.new(-99, "Method #{name} missing" +
557
+ # " or wrong number of parameters!")
558
+ # end
559
+ #
560
+ # s.serve
632
561
  class Server < WEBrickServlet
633
562
 
563
+ # Creates a new XMLRPC::Server instance, which is a XML-RPC server
564
+ # listening on the given +port+ and accepts requests for the given +host+,
565
+ # which is +localhost+ by default.
566
+ #
567
+ # The server is not started, to start it you have to call
568
+ # XMLRPC::Server#serve.
569
+ #
570
+ # The optional +audit+ and +debug+ parameters are obsolete!
571
+ #
572
+ # All additionally provided parameters in <code>*a</code> are by-passed to
573
+ # XMLRPC::BasicServer.new.
634
574
  def initialize(port=8080, host="127.0.0.1", maxConnections=4, stdlog=$stdout, audit=true, debug=true, *a)
635
575
  super(*a)
636
576
  require 'webrick'
637
- @server = WEBrick::HTTPServer.new(:Port => port, :BindAddress => host, :MaxClients => maxConnections,
577
+ @server = WEBrick::HTTPServer.new(:Port => port, :BindAddress => host, :MaxClients => maxConnections,
638
578
  :Logger => WEBrick::Log.new(stdlog))
639
579
  @server.mount("/", self)
640
580
  end
641
-
581
+
582
+ # Call this after you have added all you handlers to the server.
583
+ # This method starts the server to listen for XML-RPC requests and answer them.
642
584
  def serve
643
- if RUBY_PLATFORM =~ /mingw|mswin32/
644
- signals = [1]
645
- else
646
- signals = %w[INT TERM HUP]
647
- end
585
+ signals = %w[INT TERM HUP] & Signal.list.keys
648
586
  signals.each { |signal| trap(signal) { @server.shutdown } }
649
587
 
650
588
  @server.start
651
589
  end
652
-
590
+
591
+ # Stops and shuts the server down.
653
592
  def shutdown
654
593
  @server.shutdown
655
594
  end
656
-
657
- end
658
595
 
659
- =begin
660
- = XMLRPC::WEBrickServlet
661
- == Synopsis
662
-
663
- require "webrick"
664
- require "xmlrpc/server"
665
-
666
- s = XMLRPC::WEBrickServlet.new
667
- s.add_handler("michael.add") do |a,b|
668
- a + b
669
- end
670
-
671
- s.add_handler("michael.div") do |a,b|
672
- if b == 0
673
- raise XMLRPC::FaultException.new(1, "division by zero")
674
- else
675
- a / b
676
- end
677
- end
678
-
679
- s.set_default_handler do |name, *args|
680
- raise XMLRPC::FaultException.new(-99, "Method #{name} missing" +
681
- " or wrong number of parameters!")
682
- end
683
-
684
- httpserver = WEBrick::HTTPServer.new(:Port => 8080)
685
- httpserver.mount("/RPC2", s)
686
- trap("HUP") { httpserver.shutdown } # use 1 instead of "HUP" on Windows
687
- httpserver.start
688
-
689
- == Instance Methods
690
-
691
- --- XMLRPC::WEBrickServlet#set_valid_ip( *ip_addr )
692
- Specifies the valid IP addresses that are allowed to connect to the server.
693
- Each IP is either a (({String})) or a (({Regexp})).
694
-
695
- --- XMLRPC::WEBrickServlet#get_valid_ip
696
- Return the via method ((<set_valid_ip|XMLRPC::Server#set_valid_ip>)) specified
697
- valid IP addresses.
698
-
699
- == Description
700
- Implements a servlet for use with WEBrick, a pure Ruby (HTTP-) server framework.
701
-
702
- == Superclass
703
- ((<XMLRPC::BasicServer>))
596
+ end
704
597
 
705
- =end
706
598
 
599
+ # Implements a servlet for use with WEBrick, a pure Ruby (HTTP) server
600
+ # framework.
601
+ #
602
+ # require "webrick"
603
+ # require "xmlrpc/server"
604
+ #
605
+ # s = XMLRPC::WEBrickServlet.new
606
+ # s.add_handler("michael.add") do |a,b|
607
+ # a + b
608
+ # end
609
+ #
610
+ # s.add_handler("michael.div") do |a,b|
611
+ # if b == 0
612
+ # raise XMLRPC::FaultException.new(1, "division by zero")
613
+ # else
614
+ # a / b
615
+ # end
616
+ # end
617
+ #
618
+ # s.set_default_handler do |name, *args|
619
+ # raise XMLRPC::FaultException.new(-99, "Method #{name} missing" +
620
+ # " or wrong number of parameters!")
621
+ # end
622
+ #
623
+ # httpserver = WEBrick::HTTPServer.new(:Port => 8080)
624
+ # httpserver.mount("/RPC2", s)
625
+ # trap("HUP") { httpserver.shutdown } # use 1 instead of "HUP" on Windows
626
+ # httpserver.start
707
627
  class WEBrickServlet < BasicServer
708
628
  def initialize(*a)
709
629
  super
@@ -711,10 +631,9 @@ class WEBrickServlet < BasicServer
711
631
  @valid_ip = nil
712
632
  end
713
633
 
714
- # deprecated from WEBrick/1.2.2.
715
- # but does not break anything.
634
+ # Deprecated from WEBrick/1.2.2, but does not break anything.
716
635
  def require_path_info?
717
- false
636
+ false
718
637
  end
719
638
 
720
639
  def get_instance(config, *options)
@@ -722,6 +641,9 @@ class WEBrickServlet < BasicServer
722
641
  self
723
642
  end
724
643
 
644
+ # Specifies the valid IP addresses that are allowed to connect to the server.
645
+ #
646
+ # Each IP is either a String or a Regexp.
725
647
  def set_valid_ip(*ip_addr)
726
648
  if ip_addr.size == 1 and ip_addr[0].nil?
727
649
  @valid_ip = nil
@@ -730,13 +652,16 @@ class WEBrickServlet < BasicServer
730
652
  end
731
653
  end
732
654
 
655
+ # Return the valid IP addresses that are allowed to connect to the server.
656
+ #
657
+ # See also, XMLRPC::Server#set_valid_ip
733
658
  def get_valid_ip
734
659
  @valid_ip
735
660
  end
736
661
 
737
662
  def service(request, response)
738
663
 
739
- if @valid_ip
664
+ if @valid_ip
740
665
  raise WEBrick::HTTPStatus::Forbidden unless @valid_ip.any? { |ip| request.peeraddr[3] =~ ip }
741
666
  end
742
667
 
@@ -745,9 +670,9 @@ class WEBrickServlet < BasicServer
745
670
  "unsupported method `#{request.request_method}'."
746
671
  end
747
672
 
748
- if parse_content_type(request['Content-type']).first != "text/xml"
673
+ if parse_content_type(request['Content-type']).first != "text/xml"
749
674
  raise WEBrick::HTTPStatus::BadRequest
750
- end
675
+ end
751
676
 
752
677
  length = (request['Content-length'] || 0).to_i
753
678
 
@@ -755,19 +680,19 @@ class WEBrickServlet < BasicServer
755
680
 
756
681
  data = request.body
757
682
 
758
- if data.nil? or data.size != length
683
+ if data.nil? or data.bytesize != length
759
684
  raise WEBrick::HTTPStatus::BadRequest
760
685
  end
761
686
 
762
687
  resp = process(data)
763
- if resp.nil? or resp.size <= 0
688
+ if resp.nil? or resp.bytesize <= 0
764
689
  raise WEBrick::HTTPStatus::InternalServerError
765
690
  end
766
691
 
767
692
  response.status = 200
768
- response['Content-Length'] = resp.size
693
+ response['Content-Length'] = resp.bytesize
769
694
  response['Content-Type'] = "text/xml; charset=utf-8"
770
- response.body = resp
695
+ response.body = resp
771
696
  end
772
697
  end
773
698
 
@@ -777,6 +702,6 @@ end # module XMLRPC
777
702
 
778
703
  =begin
779
704
  = History
780
- $Id: server.rb 22461 2009-02-20 09:06:53Z shyouhei $
705
+ $Id$
781
706
  =end
782
707