1# coding: utf-8
2
3require 'test/unit'
4require 'webrick'
5require_relative 'webrick_testing'
6require "xmlrpc/server"
7require 'xmlrpc/client'
8require 'logger'
9
10class Test_Webrick < Test::Unit::TestCase
11  include WEBrick_Testing
12
13  @@basic_auth = WEBrick::HTTPAuth::BasicAuth.new(
14    :Realm => 'auth',
15    :UserDB => WEBrick::HTTPAuth::Htpasswd.new(File.expand_path('./htpasswd', File.dirname(__FILE__))),
16    :Logger => Logger.new(File::NULL),
17  )
18
19  def create_servlet
20    s = XMLRPC::WEBrickServlet.new
21
22    def s.service(req, res)
23      @@basic_auth.authenticate(req, res)
24      super(req, res)
25    end
26
27    s.add_handler("test.add") do |a,b|
28      a + b
29    end
30
31    s.add_handler("test.div") do |a,b|
32      if b == 0
33        raise XMLRPC::FaultException.new(1, "division by zero")
34      else
35        a / b
36      end
37    end
38
39    s.set_default_handler do |name, *args|
40      raise XMLRPC::FaultException.new(-99, "Method #{name} missing" +
41            " or wrong number of parameters!")
42    end
43
44    s.add_introspection
45
46    return s
47  end
48
49  def setup_http_server(port, use_ssl)
50    option = {
51      :BindAddress => "localhost",
52      :Port => port,
53      :SSLEnable => use_ssl,
54    }
55    if use_ssl
56      require 'webrick/https'
57      option.update(
58        :SSLVerifyClient => ::OpenSSL::SSL::VERIFY_NONE,
59        :SSLCertName => []
60      )
61    end
62
63    start_server(option) {|w| w.mount('/RPC2', create_servlet) }
64  end
65
66  PORT = 8071
67  def test_client_server
68    # NOTE: I don't enable SSL testing as this hangs
69    [false].each do |use_ssl|
70      begin
71        setup_http_server(PORT, use_ssl)
72        @s = XMLRPC::Client.new3(:port => PORT, :use_ssl => use_ssl)
73        @s.user = 'admin'
74        @s.password = 'admin'
75        silent do
76          do_test
77        end
78        @s = XMLRPC::Client.new3(:port => PORT, :use_ssl => use_ssl)
79        @s.user = '01234567890123456789012345678901234567890123456789012345678901234567890123456789'
80        @s.password = 'guest'
81        silent do
82          do_test
83        end
84      ensure
85        stop_server
86      end
87    end
88  end
89
90  def silent
91    begin
92      back, $VERBOSE = $VERBOSE, nil
93      yield
94    ensure
95      $VERBOSE = back
96    end
97  end
98
99  def do_test
100    # simple call
101    assert_equal 9, @s.call('test.add', 4, 5)
102
103    # fault exception
104    assert_raise(XMLRPC::FaultException) { @s.call('test.div', 1, 0) }
105
106    # fault exception via call2
107    ok, param = @s.call2('test.div', 1, 0)
108    assert_equal false, ok
109    assert_instance_of XMLRPC::FaultException, param
110    assert_equal 1, param.faultCode
111    assert_equal 'division by zero', param.faultString
112
113    # call2 without fault exception
114    ok, param = @s.call2('test.div', 10, 5)
115    assert_equal true, ok
116    assert_equal param, 2
117
118    # introspection
119    assert_equal ["test.add", "test.div", "system.listMethods", "system.methodSignature", "system.methodHelp"], @s.call("system.listMethods")
120
121    # default handler (missing handler)
122    ok, param = @s.call2('test.nonexisting')
123    assert_equal false, ok
124    assert_equal(-99, param.faultCode)
125
126    # default handler (wrong number of arguments)
127    ok, param = @s.call2('test.add', 1, 2, 3)
128    assert_equal false, ok
129    assert_equal(-99, param.faultCode)
130
131    # multibyte characters
132    assert_equal "あいうえおかきくけこ", @s.call('test.add', "あいうえお", "かきくけこ")
133  end
134end
135