hessian2 1.0.3 → 1.1.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.
- data/README.rdoc +5 -6
- data/hessian2.gemspec +1 -1
- data/lib/hessian2/hessian_client.rb +38 -0
- data/lib/hessian2/hessian_exception.rb +3 -0
- data/lib/hessian2/hessian_parser.rb +75 -0
- data/lib/hessian2/hessian_writer.rb +130 -0
- data/lib/hessian2/type_wrapper.rb +8 -0
- data/lib/hessian2/version.rb +1 -1
- data/lib/hessian2.rb +5 -230
- data/test/test_hessian_parser.rb +3 -4
- metadata +9 -5
- data/test/servlet_invoker.rb +0 -17
data/README.rdoc
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
= hessian2
|
2
2
|
|
3
|
-
hessian
|
4
|
-
|
5
|
-
hessian client. based on Christer Sandberg's hessian, fixed UTF-8 pack, allow declare long type, ruby1.9 tested.
|
3
|
+
implement hessian 1.0.2 specification. refactor Christer Sandberg's hessian, ruby 1.9.3 required.
|
6
4
|
|
7
5
|
== Using
|
8
6
|
|
@@ -14,9 +12,10 @@ hessian client. based on Christer Sandberg's hessian, fixed UTF-8 pack, allow de
|
|
14
12
|
|
15
13
|
client = Hessian2::HessianClient.new(url)
|
16
14
|
|
17
|
-
#call remote function:
|
18
|
-
|
19
|
-
|
15
|
+
# call remote function: public Person getPersonByUid(Long uid);
|
16
|
+
uid = Hessian2::TypeWrapper.new('L', 59)
|
17
|
+
puts client.getPersonByUid(uid)
|
18
|
+
|
20
19
|
== Authors
|
21
20
|
|
22
21
|
* {Takafan}[http://hululuu.com]
|
data/hessian2.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.email = ["takafan@163.com"]
|
10
10
|
s.homepage = "http://github.com/takafan/hessian2"
|
11
11
|
s.summary = %q{Hessian2}
|
12
|
-
s.description = %q{hessian
|
12
|
+
s.description = %q{implement hessian 1.0.2 specification. refactor Christer Sandberg's hessian, ruby 1.9.3 required.}
|
13
13
|
|
14
14
|
s.rubyforge_project = "hessian2"
|
15
15
|
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'net/http'
|
3
|
+
require 'net/https'
|
4
|
+
require 'hessian2/hessian_writer'
|
5
|
+
require 'hessian2/hessian_parser'
|
6
|
+
|
7
|
+
module Hessian2
|
8
|
+
class HessianClient
|
9
|
+
attr_accessor :user, :password
|
10
|
+
attr_reader :scheme, :host, :port, :path, :proxy
|
11
|
+
|
12
|
+
include HessianWriter
|
13
|
+
include HessianParser
|
14
|
+
|
15
|
+
def initialize(url, proxy = {})
|
16
|
+
uri = URI.parse(url)
|
17
|
+
@scheme, @host, @port, @path = uri.scheme, uri.host, uri.port, uri.path
|
18
|
+
raise "Unsupported Hessian protocol: #{@scheme}" unless %w(http https).include? @scheme
|
19
|
+
@proxy = proxy
|
20
|
+
end
|
21
|
+
|
22
|
+
def method_missing(id, *args)
|
23
|
+
return invoke(id.id2name, args)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
def invoke(method, args)
|
28
|
+
req = Net::HTTP::Post.new(@path, { 'Content-Type' => 'application/binary' })
|
29
|
+
req.basic_auth @user, @password if @user
|
30
|
+
conn = Net::HTTP.new(@host, @port, *@proxy.values_at(:host, :port, :user, :password))
|
31
|
+
conn.use_ssl = true and conn.verify_mode = OpenSSL::SSL::VERIFY_NONE if @scheme == 'https'
|
32
|
+
conn.start do |http|
|
33
|
+
parse http.request(req, write_call(method, args)).body
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Hessian2
|
2
|
+
module HessianParser
|
3
|
+
|
4
|
+
def parse(data, refs = [], chunks = [])
|
5
|
+
t = data.slice!(0)
|
6
|
+
case t
|
7
|
+
when 'r' # reply
|
8
|
+
data.slice!(0, 2)
|
9
|
+
parse(data)
|
10
|
+
when 'f' # fault
|
11
|
+
parse(data)
|
12
|
+
code = parse(data)
|
13
|
+
parse(data)
|
14
|
+
message = parse(data)
|
15
|
+
raise HessianException.new, "#{code}: #{message}"
|
16
|
+
when 'N' # null
|
17
|
+
nil
|
18
|
+
when 'T' # true
|
19
|
+
true
|
20
|
+
when 'F' # false
|
21
|
+
false
|
22
|
+
when 'I' # int
|
23
|
+
data.slice!(0, 4).unpack('l>')[0]
|
24
|
+
when 'L' # long
|
25
|
+
data.slice!(0, 8).unpack('q>')[0]
|
26
|
+
when 'D' # double
|
27
|
+
data.slice!(0, 8).unpack('G')[0]
|
28
|
+
when 'd' # date
|
29
|
+
val = data.slice!(0, 8).unpack('Q>')[0]
|
30
|
+
Time.at(val / 1000, val % 1000 * 1000)
|
31
|
+
when 'S', 's', 'X', 'x' # string, xml
|
32
|
+
len = data.slice!(0, 2).unpack('n')[0]
|
33
|
+
|
34
|
+
chunk = data.unpack("U#{len}")
|
35
|
+
chunks << chunk
|
36
|
+
data.slice!(0, chunk.pack('U*').bytesize)
|
37
|
+
|
38
|
+
if 'sx'.include?(t)
|
39
|
+
parse(data, refs, chunks)
|
40
|
+
else
|
41
|
+
chunks.flatten.pack('U*')
|
42
|
+
end
|
43
|
+
when 'B', 'b' # binary
|
44
|
+
len = data.slice!(0, 2).unpack('n')[0]
|
45
|
+
|
46
|
+
chunk = data.slice!(0, len)
|
47
|
+
chunks << chunk
|
48
|
+
|
49
|
+
if t == 'b'
|
50
|
+
parse(data, refs, chunks)
|
51
|
+
else
|
52
|
+
chunks.flatten
|
53
|
+
end
|
54
|
+
when 'V' # list
|
55
|
+
data.slice!(0, 3 + data.unpack('an')[1]) if data[0] == 't'
|
56
|
+
data.slice!(0, 5) if data[0] == 'l'
|
57
|
+
refs << (list = [])
|
58
|
+
list << parse(data, refs) while data[0] != 'z'
|
59
|
+
data.slice!(0)
|
60
|
+
list
|
61
|
+
when 'M' # map
|
62
|
+
data.slice!(0, 3 + data.unpack('an')[1]) if data[0] == 't'
|
63
|
+
refs << (map = {})
|
64
|
+
map[parse(data, refs)] = parse(data, refs) while data[0] != 'z'
|
65
|
+
data.slice!(0)
|
66
|
+
map
|
67
|
+
when 'R' # ref
|
68
|
+
refs[data.slice!(0, 4).unpack('N')[0]]
|
69
|
+
else
|
70
|
+
raise HessianException.new, "Invalid type: '#{t}'"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
module Hessian2
|
2
|
+
module HessianWriter
|
3
|
+
CHUNK_SIZE = 32768
|
4
|
+
|
5
|
+
def write_call(method, args)
|
6
|
+
refs = {}
|
7
|
+
out = [ 'c', '0', '1', 'm', method.length ].pack('ahhan') << method
|
8
|
+
args.each { |arg| out << write(arg, refs) }
|
9
|
+
out << 'z'
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
def write(val, refs = {}, chunks = [], type = nil)
|
14
|
+
case val
|
15
|
+
when TypeWrapper
|
16
|
+
obj, hessian_type = val.object, val.hessian_type
|
17
|
+
case hessian_type
|
18
|
+
when 'L', 'Long', 'long' # declare as long
|
19
|
+
[ 'L', obj ].pack('aq>') # long
|
20
|
+
when 'X', 'x' # declare as xml
|
21
|
+
if obj.size > CHUNK_SIZE
|
22
|
+
chunk = obj.slice!(0, CHUNK_SIZE)
|
23
|
+
if chunk.ascii_only?
|
24
|
+
chunks << [ 's', CHUNK_SIZE ].pack('an') << chunk
|
25
|
+
else
|
26
|
+
chunks << [ 's', CHUNK_SIZE, chunk.unpack('U*') ].flatten.pack('anU*')
|
27
|
+
end
|
28
|
+
write(TypeWrapper.new('X', obj), refs, chunks)
|
29
|
+
else
|
30
|
+
if obj.bytesize == obj.size
|
31
|
+
chunks << [ 'X', obj.size ].pack('an') << obj
|
32
|
+
else
|
33
|
+
chunks << [ 'X', obj.size, obj.unpack('U*') ].flatten.pack('anU*')
|
34
|
+
end
|
35
|
+
chunks.join # xml
|
36
|
+
end
|
37
|
+
when 'B', 'b' # declare as binary
|
38
|
+
[ 'B', obj.size ].pack('an') << obj
|
39
|
+
if obj.size > CHUNK_SIZE
|
40
|
+
chunk = obj.slice!(0, CHUNK_SIZE)
|
41
|
+
chunks << [ 'b', CHUNK_SIZE ].pack('an') << chunk
|
42
|
+
write(TypeWrapper.new('B', obj), refs, chunks)
|
43
|
+
else
|
44
|
+
chunks << [ 'B', obj.size ].pack('an') << obj
|
45
|
+
chunks.join # binary
|
46
|
+
end
|
47
|
+
else # type for list, map
|
48
|
+
write(obj, refs, chunks, hessian_type)
|
49
|
+
end
|
50
|
+
when NilClass
|
51
|
+
'N' # null
|
52
|
+
when TrueClass
|
53
|
+
'T' # true
|
54
|
+
when FalseClass
|
55
|
+
'F' # false
|
56
|
+
when Fixnum
|
57
|
+
[ 'I', val ].pack('al>') # int
|
58
|
+
when Bignum
|
59
|
+
[ 'L', val ].pack('aq>') # long
|
60
|
+
when Float
|
61
|
+
[ 'D', val ].pack('aG') # double
|
62
|
+
when Time
|
63
|
+
[ 'd', val.to_f * 1000 ].pack('aQ>') # date
|
64
|
+
when String
|
65
|
+
if val.size > CHUNK_SIZE
|
66
|
+
chunk = val.slice!(0, CHUNK_SIZE)
|
67
|
+
if chunk.ascii_only?
|
68
|
+
chunks << [ 's', CHUNK_SIZE ].pack('an') << chunk
|
69
|
+
else
|
70
|
+
# unpack-pack if chunk incompatible with ASCII-8BIT
|
71
|
+
chunks << [ 's', CHUNK_SIZE, chunk.unpack('U*') ].flatten.pack('anU*')
|
72
|
+
end
|
73
|
+
write(val, refs, chunks)
|
74
|
+
else
|
75
|
+
if val.bytesize == val.size
|
76
|
+
chunks << [ 'S', val.size ].pack('an') << val
|
77
|
+
else
|
78
|
+
chunks << [ 'S', val.size, val.unpack('U*') ].flatten.pack('anU*')
|
79
|
+
end
|
80
|
+
chunks.join # string
|
81
|
+
end
|
82
|
+
when Symbol
|
83
|
+
str = val.to_s
|
84
|
+
[ 'S', str.size ].pack('an') << str # string
|
85
|
+
when Array
|
86
|
+
id = refs[val.object_id]
|
87
|
+
return [ 'R', id ].pack('aN') if id
|
88
|
+
|
89
|
+
refs[val.object_id] = refs.size
|
90
|
+
|
91
|
+
str = 'V'
|
92
|
+
str << 't' << [ type.size, type ].pack('na*') if type
|
93
|
+
str << 'l' << [ val.size ].pack('N')
|
94
|
+
val.each{ |v| str << write(v, refs) }
|
95
|
+
str << 'z' # list
|
96
|
+
when Hash
|
97
|
+
id = refs[val.object_id]
|
98
|
+
return [ 'R', id ].pack('aN') if id
|
99
|
+
|
100
|
+
refs[val.object_id] = refs.size
|
101
|
+
|
102
|
+
str = 'M'
|
103
|
+
str << 't' << [ type.size, type ].pack('na*') if type
|
104
|
+
val.each do |k, v|
|
105
|
+
str << write(k, refs)
|
106
|
+
str << write(v, refs)
|
107
|
+
end
|
108
|
+
str << 'z' # map
|
109
|
+
else # covert val to hash
|
110
|
+
hash = {}.tap do |h|
|
111
|
+
val.instance_variables.each {|var| h[var.to_s.delete("@")] = val.instance_variable_get(var) }
|
112
|
+
end
|
113
|
+
|
114
|
+
unless type
|
115
|
+
# map ruby module to java package
|
116
|
+
arr = val.class.to_s.split('::')
|
117
|
+
if arr.size > 1
|
118
|
+
klass = arr.pop
|
119
|
+
type = arr.map{|m| m.downcase}.join('.') << ".#{klass}"
|
120
|
+
else
|
121
|
+
type = arr.first
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
write(hash, refs, chunks, type)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
end
|
data/lib/hessian2/version.rb
CHANGED
data/lib/hessian2.rb
CHANGED
@@ -1,231 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require 'uri'
|
4
|
-
require 'net/http'
|
5
|
-
require 'net/https'
|
6
|
-
|
7
|
-
module Hessian2
|
8
|
-
class TypeWrapper
|
9
|
-
attr_accessor :hessian_type, :object
|
10
|
-
def initialize(hessian_type, object)
|
11
|
-
@hessian_type, @object = hessian_type, object
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
class Binary
|
16
|
-
attr :data
|
17
|
-
def initialize(data)
|
18
|
-
@data = data.to_s
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
class HessianException < RuntimeError
|
23
|
-
attr_reader :code
|
24
|
-
def initialize(code)
|
25
|
-
@code = code
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
class HessianClient
|
30
|
-
attr_accessor :user, :password
|
31
|
-
attr_reader :scheme, :host, :port, :path, :proxy
|
32
|
-
def initialize(url, proxy = {})
|
33
|
-
uri = URI.parse(url)
|
34
|
-
@scheme, @host, @port, @path = uri.scheme, uri.host, uri.port, uri.path
|
35
|
-
raise "Unsupported Hessian protocol: #@scheme" unless @scheme == 'http' || @scheme == 'https'
|
36
|
-
@proxy = proxy
|
37
|
-
end
|
38
|
-
|
39
|
-
def method_missing(id, *args)
|
40
|
-
return invoke(id.id2name, args)
|
41
|
-
end
|
42
|
-
|
43
|
-
private
|
44
|
-
def invoke(method, args)
|
45
|
-
call = HessianWriter.new.write_call method, args
|
46
|
-
header = { 'Content-Type' => 'application/binary' }
|
47
|
-
req = Net::HTTP::Post.new(@path, header)
|
48
|
-
req.basic_auth @user, @password if @user
|
49
|
-
conn = Net::HTTP.new(@host, @port, *@proxy.values_at(:host, :port, :user, :password))
|
50
|
-
conn.use_ssl = true and conn.verify_mode = OpenSSL::SSL::VERIFY_NONE if @scheme == 'https'
|
51
|
-
conn.start do |http|
|
52
|
-
res = http.request(req, call)
|
53
|
-
HessianParser.new.parse_response res.body
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
class HessianWriter
|
58
|
-
def write_call(method, args)
|
59
|
-
@refs = {}
|
60
|
-
out = [ 'c', '0', '1', 'm', method.length ].pack('ahhan') << method
|
61
|
-
args.each { |arg| out << write_object(arg) }
|
62
|
-
out << 'z'
|
63
|
-
end
|
64
|
-
|
65
|
-
private
|
66
|
-
def write_object(val, hessian_type = nil)
|
67
|
-
return 'N' if val.nil?
|
68
|
-
case val
|
69
|
-
when TypeWrapper
|
70
|
-
val.hessian_type == 'Long' ? "L%s" % to_long(val.object) : write_object(val.object, val.hessian_type)
|
71
|
-
when Struct
|
72
|
-
write_object(val.members.inject({}) { |map, m| map[m] = val[m]; map })
|
73
|
-
when Binary
|
74
|
-
[ 'B', val.data.length ].pack('an') << val.data
|
75
|
-
when String
|
76
|
-
[ 'S', val.length ].pack('an') << val.unpack('U*').pack('U*')
|
77
|
-
when
|
78
|
-
Integer
|
79
|
-
# Max and min values for integers in Java.
|
80
|
-
if val >= -0x80000000 && val <= 0x7fffffff
|
81
|
-
[ 'I', val ].pack('aN')
|
82
|
-
else
|
83
|
-
"L%s" % to_long(val)
|
84
|
-
end
|
85
|
-
when Float
|
86
|
-
[ 'D', val ].pack('aG')
|
87
|
-
when Time
|
88
|
-
"d%s" % to_long((val.to_f * 1000).to_i)
|
89
|
-
when TrueClass
|
90
|
-
'T'
|
91
|
-
when FalseClass
|
92
|
-
'F'
|
93
|
-
when Array
|
94
|
-
ref = write_ref val; return ref if ref
|
95
|
-
t = hessian_type_string(hessian_type, val)
|
96
|
-
str = 'Vt' << t << 'l' << [ val.length ].pack('N')
|
97
|
-
val.each { |v| str << write_object(v) }
|
98
|
-
str << 'z'
|
99
|
-
when Hash
|
100
|
-
ref = write_ref val; return ref if ref
|
101
|
-
str = 'Mt' << hessian_type_string(hessian_type, val)
|
102
|
-
val.each { |k, v| str << write_object(k); str << write_object(v) }
|
103
|
-
str << 'z'
|
104
|
-
else
|
105
|
-
raise "Not implemented for #{val.class}"
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
def hessian_type_string(hessian_type, object)
|
110
|
-
if hessian_type.nil? && object.respond_to?(:hessian_type)
|
111
|
-
hessian_type = object.hessian_type
|
112
|
-
end
|
113
|
-
hessian_type ? [ hessian_type.length, hessian_type ].pack('na*') : "\000\000"
|
114
|
-
end
|
115
|
-
|
116
|
-
def to_long(val)
|
117
|
-
val2 = val.to_s(2)
|
118
|
-
['0' * (64 - val2.size) << val2].pack("B*")
|
119
|
-
end
|
120
|
-
|
121
|
-
def write_ref(val)
|
122
|
-
id = @refs[val.object_id]
|
123
|
-
if id
|
124
|
-
[ 'R', id ].pack('aN')
|
125
|
-
else
|
126
|
-
@refs[val.object_id] = @refs.length
|
127
|
-
nil
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
class HessianParser
|
133
|
-
def parse_response(res)
|
134
|
-
raise "Invalid response, expected 'r', received '#{res[0,1]}'" unless res[0,1] == 'r'
|
135
|
-
@chunks = []
|
136
|
-
@refs = []
|
137
|
-
@data = res[3..-1]
|
138
|
-
parse_object
|
139
|
-
end
|
140
|
-
|
141
|
-
private
|
142
|
-
def parse_object
|
143
|
-
t = @data.slice!(0, 1)
|
144
|
-
|
145
|
-
case t
|
146
|
-
when 'f'
|
147
|
-
raise_exception
|
148
|
-
when 's', 'S', 'x', 'X'
|
149
|
-
|
150
|
-
v = from_utf8(@data.slice!(0, 2).unpack('n')[0])
|
151
|
-
@data.slice!(0, v[1])
|
152
|
-
@chunks << v[0]
|
153
|
-
|
154
|
-
if 'sx'.include? t
|
155
|
-
|
156
|
-
parse_object
|
157
|
-
else
|
158
|
-
str = @chunks.join; @chunks.clear; str
|
159
|
-
end
|
160
|
-
when 'b', 'B'
|
161
|
-
v = @data.slice!(0, @data.slice!(0, 2).unpack('n')[0])
|
162
|
-
@chunks << v
|
163
|
-
if t == 'b'
|
164
|
-
parse_object
|
165
|
-
else
|
166
|
-
bytes = @chunks.join; @chunks.clear; Binary.new bytes
|
167
|
-
end
|
168
|
-
when 'I'
|
169
|
-
@data.slice!(0, 4).unpack('N')[0]
|
170
|
-
when 'L'
|
171
|
-
parse_long
|
172
|
-
when 'd'
|
173
|
-
l = parse_long; Time.at(l / 1000, l % 1000 * 1000)
|
174
|
-
when 'D'
|
175
|
-
@data.slice!(0, 8).unpack('G')[0]
|
176
|
-
when 'T'
|
177
|
-
true
|
178
|
-
when 'F'
|
179
|
-
false
|
180
|
-
when 'N'
|
181
|
-
nil
|
182
|
-
when 'R'
|
183
|
-
@refs[@data.slice!(0, 4).unpack('N')[0]]
|
184
|
-
when 'V'
|
185
|
-
# Skip type + type length (2 bytes) if specified.
|
186
|
-
@data.slice!(0, 3 + @data.unpack('an')[1]) if @data[0,1] == 't'
|
187
|
-
# Skip the list length if specified.
|
188
|
-
@data.slice!(0, 5) if @data[0,1] == 'l'
|
189
|
-
@refs << (list = [])
|
190
|
-
list << parse_object while @data[0,1] != 'z'
|
191
|
-
# Get rid of the 'z'.
|
192
|
-
@data.slice!(0, 1)
|
193
|
-
list
|
194
|
-
when 'M'
|
195
|
-
# Skip type + type length (2 bytes) if specified.
|
196
|
-
@data.slice!(0, 3 + @data.unpack('an')[1]) if @data[0,1] == 't'
|
197
|
-
@refs << (map = {})
|
198
|
-
map[parse_object()] = parse_object while @data[0,1] != 'z'
|
199
|
-
# Get rid of the 'z'.
|
200
|
-
@data.slice!(0, 1)
|
201
|
-
map
|
202
|
-
else
|
203
|
-
puts @data
|
204
|
-
raise "Invalid type: '#{t}'"
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
def from_utf8(len = '*')
|
209
|
-
s = @data.unpack("U#{len}").pack('U*')
|
210
|
-
[ s, s.unpack('C*').pack('U*').length ]
|
211
|
-
end
|
212
|
-
|
213
|
-
def parse_long
|
214
|
-
val, o = 0, 56
|
215
|
-
@data.slice!(0, 8).each_byte { |b| val += (b & 0xff) << o; o -= 8 }
|
216
|
-
val
|
217
|
-
end
|
218
|
-
|
219
|
-
def raise_exception
|
220
|
-
# Skip code description.
|
221
|
-
parse_object
|
222
|
-
code = parse_object
|
223
|
-
# Skip message description
|
224
|
-
parse_object
|
225
|
-
msg = parse_object
|
226
|
-
raise HessianException.new(code), msg
|
227
|
-
end
|
228
|
-
end
|
229
|
-
end
|
230
|
-
end
|
1
|
+
# http://hessian.caucho.com/doc/hessian-1.0-spec.xtp
|
231
2
|
|
3
|
+
require "hessian2/version"
|
4
|
+
require 'hessian2/hessian_client'
|
5
|
+
require 'hessian2/type_wrapper'
|
6
|
+
require 'hessian2/hessian_exception'
|
data/test/test_hessian_parser.rb
CHANGED
@@ -4,9 +4,8 @@ require 'hessian2'
|
|
4
4
|
require 'test/unit'
|
5
5
|
|
6
6
|
class HessianParserTest < Test::Unit::TestCase
|
7
|
-
|
8
|
-
|
9
|
-
end
|
7
|
+
|
8
|
+
include Hessian2::HessianParser
|
10
9
|
|
11
10
|
def test_integer
|
12
11
|
assert_equal 4711, parse("r\001\000I\000\000\022gz")
|
@@ -53,5 +52,5 @@ class HessianParserTest < Test::Unit::TestCase
|
|
53
52
|
assert_equal map, parse([ "r\001\000Mt\000\000S\000\anumbersVt\000\a[double",
|
54
53
|
"l\000\000\000\003D?\361\231\231\231\231\231\232D?\363333333D?",
|
55
54
|
"\364\314\314\314\314\314\315zS\000\006sillenI\000\000\000 zz" ].join)
|
56
|
-
|
55
|
+
end
|
57
56
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hessian2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,10 +9,10 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-12-08 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
|
-
description: hessian
|
15
|
-
|
14
|
+
description: implement hessian 1.0.2 specification. refactor Christer Sandberg's hessian,
|
15
|
+
ruby 1.9.3 required.
|
16
16
|
email:
|
17
17
|
- takafan@163.com
|
18
18
|
executables: []
|
@@ -25,8 +25,12 @@ files:
|
|
25
25
|
- Rakefile
|
26
26
|
- hessian2.gemspec
|
27
27
|
- lib/hessian2.rb
|
28
|
+
- lib/hessian2/hessian_client.rb
|
29
|
+
- lib/hessian2/hessian_exception.rb
|
30
|
+
- lib/hessian2/hessian_parser.rb
|
31
|
+
- lib/hessian2/hessian_writer.rb
|
32
|
+
- lib/hessian2/type_wrapper.rb
|
28
33
|
- lib/hessian2/version.rb
|
29
|
-
- test/servlet_invoker.rb
|
30
34
|
- test/test_hessian_parser.rb
|
31
35
|
homepage: http://github.com/takafan/hessian2
|
32
36
|
licenses: []
|
data/test/servlet_invoker.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
require 'net/http'
|
2
|
-
|
3
|
-
HEADER = { 'Content-Type' => 'application/binary' }
|
4
|
-
|
5
|
-
call = %w(c 0 1 m).pack('ahha')
|
6
|
-
methods = %w(
|
7
|
-
getInt getLong getDouble getFalse getTrue getString getNull
|
8
|
-
getDate getIntArray getObjectArray getArrayInList getMap
|
9
|
-
)
|
10
|
-
|
11
|
-
methods.each do |m|
|
12
|
-
Net::HTTP.start('localhost', 8080) do |http|
|
13
|
-
res = http.send_request('POST', '/test',
|
14
|
-
call + [ m.length, m ].pack('na*') + 'z', HEADER)
|
15
|
-
p res.body
|
16
|
-
end
|
17
|
-
end
|