mrpin-rocketamf 1.0.4 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.rdoc +1 -1
- data/Rakefile +7 -7
- data/benchmark.rb +44 -37
- data/ext/rocketamf_ext/class_mapping.c +11 -11
- data/ext/rocketamf_ext/remoting.c +1 -1
- data/lib/rocketamf.rb +41 -98
- data/lib/rocketamf/constants.rb +20 -20
- data/lib/rocketamf/errors.rb +2 -0
- data/lib/rocketamf/errors/amf_error.rb +5 -0
- data/lib/rocketamf/errors/amf_error_incomplete.rb +5 -0
- data/lib/rocketamf/ext.rb +0 -6
- data/lib/rocketamf/extensions.rb +4 -4
- data/lib/rocketamf/{class_mapping.rb → mapping/class_mapping.rb} +70 -103
- data/lib/rocketamf/mapping/mapping_set.rb +63 -0
- data/lib/rocketamf/pure.rb +1 -9
- data/lib/rocketamf/pure/deserializer.rb +234 -262
- data/lib/rocketamf/pure/helpers/io_helper_base.rb +19 -0
- data/lib/rocketamf/pure/helpers/io_helper_read.rb +67 -0
- data/lib/rocketamf/pure/helpers/io_helper_write.rb +48 -0
- data/lib/rocketamf/pure/helpers/object_cache.rb +20 -0
- data/lib/rocketamf/pure/helpers/string_cache.rb +14 -0
- data/lib/rocketamf/pure/serializer.rb +138 -271
- data/lib/rocketamf/types.rb +1 -0
- data/lib/rocketamf/{values → types}/typed_hash.rb +12 -2
- data/mrpin-rocketamf.gemspec +27 -16
- data/spec/class_mapping_spec.rb +59 -52
- data/spec/deserializer_spec.rb +164 -328
- data/spec/fast_class_mapping_spec.rb +52 -46
- data/spec/helpers/class_mapping_test.rb +4 -0
- data/spec/helpers/class_mapping_test2.rb +3 -0
- data/spec/helpers/externalizable_test.rb +24 -0
- data/spec/helpers/fixtures.rb +28 -0
- data/spec/helpers/other_class.rb +4 -0
- data/spec/helpers/ruby_class.rb +4 -0
- data/spec/helpers/test_ruby_class.rb +4 -0
- data/spec/serializer_spec.rb +248 -339
- data/spec/spec_helper.rb +4 -49
- metadata +47 -53
- data/lib/rocketamf/pure/io_helpers.rb +0 -94
- data/lib/rocketamf/pure/remoting.rb +0 -117
- data/lib/rocketamf/remoting.rb +0 -196
- data/lib/rocketamf/values/messages.rb +0 -214
- data/spec/fixtures/objects/amf0-boolean.bin +0 -1
- data/spec/fixtures/objects/amf0-complex-encoded-string.bin +0 -0
- data/spec/fixtures/objects/amf0-date.bin +0 -0
- data/spec/fixtures/objects/amf0-ecma-ordinal-array.bin +0 -0
- data/spec/fixtures/objects/amf0-empty-string-key-hash.bin +0 -0
- data/spec/fixtures/objects/amf0-hash.bin +0 -0
- data/spec/fixtures/objects/amf0-null.bin +0 -1
- data/spec/fixtures/objects/amf0-number.bin +0 -0
- data/spec/fixtures/objects/amf0-object.bin +0 -0
- data/spec/fixtures/objects/amf0-ref-test.bin +0 -0
- data/spec/fixtures/objects/amf0-strict-array.bin +0 -0
- data/spec/fixtures/objects/amf0-string.bin +0 -0
- data/spec/fixtures/objects/amf0-time.bin +0 -0
- data/spec/fixtures/objects/amf0-typed-object.bin +0 -0
- data/spec/fixtures/objects/amf0-undefined.bin +0 -1
- data/spec/fixtures/objects/amf0-untyped-object.bin +0 -0
- data/spec/fixtures/objects/amf0-xml-doc.bin +0 -0
- data/spec/messages_spec.rb +0 -39
- data/spec/remoting_spec.rb +0 -196
data/spec/spec_helper.rb
CHANGED
@@ -1,55 +1,10 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'rspec'
|
3
|
-
require 'rspec/autorun'
|
4
3
|
|
5
4
|
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
6
|
-
require 'rocketamf'
|
7
|
-
require 'rocketamf/pure/io_helpers' # Just to make sure they get loaded
|
8
|
-
|
9
|
-
def request_fixture(binary_path)
|
10
|
-
data = File.open(File.dirname(__FILE__) + '/fixtures/request/' + binary_path, "rb").read
|
11
|
-
data.force_encoding("ASCII-8BIT") if data.respond_to?(:force_encoding)
|
12
|
-
data
|
13
|
-
end
|
14
|
-
|
15
|
-
def object_fixture(binary_path)
|
16
|
-
data = File.open(File.dirname(__FILE__) + '/fixtures/objects/' + binary_path, "rb").read
|
17
|
-
data.force_encoding("ASCII-8BIT") if data.respond_to?(:force_encoding)
|
18
|
-
data
|
19
|
-
end
|
20
|
-
|
21
|
-
def create_envelope(binary_path)
|
22
|
-
RocketAMF::Envelope.new.populate_from_stream(StringIO.new(request_fixture(binary_path)))
|
23
|
-
end
|
24
5
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
class ClassMappingTest
|
29
|
-
attr_accessor :prop_a
|
30
|
-
attr_accessor :prop_b
|
31
|
-
end
|
32
|
-
class ClassMappingTest2 < ClassMappingTest
|
33
|
-
attr_accessor :prop_c
|
34
|
-
end
|
35
|
-
module ANamespace; class TestRubyClass; end; end
|
36
|
-
class ExternalizableTest
|
37
|
-
include RocketAMF::Pure::ReadIOHelpers
|
38
|
-
include RocketAMF::Pure::WriteIOHelpers
|
39
|
-
|
40
|
-
attr_accessor :one, :two
|
41
|
-
|
42
|
-
def encode_amf serializer
|
43
|
-
serializer.write_object(self, nil, {:class_name => 'ExternalizableTest', :dynamic => false, :externalizable => true, :members => []})
|
44
|
-
end
|
45
|
-
|
46
|
-
def read_external des
|
47
|
-
@one = read_double(des.source)
|
48
|
-
@two = read_double(des.source)
|
49
|
-
end
|
6
|
+
require 'rocketamf'
|
7
|
+
require 'rocketamf/pure/helpers/io_helper_write' # Just to make sure they get loaded
|
8
|
+
require 'rocketamf/pure/helpers/io_helper_read' # Just to make sure they get loaded
|
50
9
|
|
51
|
-
|
52
|
-
ser.stream << pack_double(@one)
|
53
|
-
ser.stream << pack_double(@two)
|
54
|
-
end
|
55
|
-
end
|
10
|
+
Dir[File.dirname(__FILE__) + '/helpers/*.rb'].each { |file| require file }
|
metadata
CHANGED
@@ -1,34 +1,36 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mrpin-rocketamf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jacob Henry
|
8
8
|
- Stephen Augenstein
|
9
9
|
- Joc O'Connor
|
10
|
+
- Gregory Tkach
|
10
11
|
autorequire:
|
11
12
|
bindir: bin
|
12
13
|
cert_chain: []
|
13
|
-
date:
|
14
|
+
date: 2015-01-01 00:00:00.000000000 Z
|
14
15
|
dependencies:
|
15
16
|
- !ruby/object:Gem::Dependency
|
16
17
|
name: rake-compiler
|
17
18
|
requirement: !ruby/object:Gem::Requirement
|
18
19
|
requirements:
|
19
|
-
- -
|
20
|
+
- - ~>
|
20
21
|
- !ruby/object:Gem::Version
|
21
22
|
version: '0'
|
22
23
|
type: :development
|
23
24
|
prerelease: false
|
24
25
|
version_requirements: !ruby/object:Gem::Requirement
|
25
26
|
requirements:
|
26
|
-
- -
|
27
|
+
- - ~>
|
27
28
|
- !ruby/object:Gem::Version
|
28
29
|
version: '0'
|
29
|
-
description:
|
30
|
+
description: Fast AMF3 serializer/deserializer with remoting request/response wrappers
|
31
|
+
to simplify integration
|
30
32
|
email:
|
31
|
-
-
|
33
|
+
- gregory.tkach@gmail.com
|
32
34
|
executables: []
|
33
35
|
extensions:
|
34
36
|
- ext/rocketamf_ext/extconf.rb
|
@@ -36,46 +38,41 @@ extra_rdoc_files:
|
|
36
38
|
- README.rdoc
|
37
39
|
files:
|
38
40
|
- README.rdoc
|
39
|
-
- benchmark.rb
|
40
|
-
- mrpin-rocketamf.gemspec
|
41
41
|
- Rakefile
|
42
|
-
-
|
42
|
+
- benchmark.rb
|
43
|
+
- ext/rocketamf_ext/class_mapping.c
|
44
|
+
- ext/rocketamf_ext/constants.h
|
45
|
+
- ext/rocketamf_ext/deserializer.c
|
46
|
+
- ext/rocketamf_ext/deserializer.h
|
47
|
+
- ext/rocketamf_ext/extconf.rb
|
48
|
+
- ext/rocketamf_ext/remoting.c
|
49
|
+
- ext/rocketamf_ext/rocketamf_ext.c
|
50
|
+
- ext/rocketamf_ext/serializer.c
|
51
|
+
- ext/rocketamf_ext/serializer.h
|
52
|
+
- ext/rocketamf_ext/utility.h
|
53
|
+
- lib/rocketamf.rb
|
43
54
|
- lib/rocketamf/constants.rb
|
55
|
+
- lib/rocketamf/errors.rb
|
56
|
+
- lib/rocketamf/errors/amf_error.rb
|
57
|
+
- lib/rocketamf/errors/amf_error_incomplete.rb
|
44
58
|
- lib/rocketamf/ext.rb
|
45
59
|
- lib/rocketamf/extensions.rb
|
60
|
+
- lib/rocketamf/mapping/class_mapping.rb
|
61
|
+
- lib/rocketamf/mapping/mapping_set.rb
|
62
|
+
- lib/rocketamf/pure.rb
|
46
63
|
- lib/rocketamf/pure/deserializer.rb
|
47
|
-
- lib/rocketamf/pure/
|
48
|
-
- lib/rocketamf/pure/
|
64
|
+
- lib/rocketamf/pure/helpers/io_helper_base.rb
|
65
|
+
- lib/rocketamf/pure/helpers/io_helper_read.rb
|
66
|
+
- lib/rocketamf/pure/helpers/io_helper_write.rb
|
67
|
+
- lib/rocketamf/pure/helpers/object_cache.rb
|
68
|
+
- lib/rocketamf/pure/helpers/string_cache.rb
|
49
69
|
- lib/rocketamf/pure/serializer.rb
|
50
|
-
- lib/rocketamf/
|
51
|
-
- lib/rocketamf/
|
52
|
-
-
|
53
|
-
- lib/rocketamf/values/typed_hash.rb
|
54
|
-
- lib/rocketamf.rb
|
70
|
+
- lib/rocketamf/types.rb
|
71
|
+
- lib/rocketamf/types/typed_hash.rb
|
72
|
+
- mrpin-rocketamf.gemspec
|
55
73
|
- spec/class_mapping_spec.rb
|
56
74
|
- spec/deserializer_spec.rb
|
57
75
|
- spec/fast_class_mapping_spec.rb
|
58
|
-
- spec/messages_spec.rb
|
59
|
-
- spec/remoting_spec.rb
|
60
|
-
- spec/serializer_spec.rb
|
61
|
-
- spec/spec_helper.rb
|
62
|
-
- spec/fixtures/objects/amf0-boolean.bin
|
63
|
-
- spec/fixtures/objects/amf0-complex-encoded-string.bin
|
64
|
-
- spec/fixtures/objects/amf0-date.bin
|
65
|
-
- spec/fixtures/objects/amf0-ecma-ordinal-array.bin
|
66
|
-
- spec/fixtures/objects/amf0-empty-string-key-hash.bin
|
67
|
-
- spec/fixtures/objects/amf0-hash.bin
|
68
|
-
- spec/fixtures/objects/amf0-null.bin
|
69
|
-
- spec/fixtures/objects/amf0-number.bin
|
70
|
-
- spec/fixtures/objects/amf0-object.bin
|
71
|
-
- spec/fixtures/objects/amf0-ref-test.bin
|
72
|
-
- spec/fixtures/objects/amf0-strict-array.bin
|
73
|
-
- spec/fixtures/objects/amf0-string.bin
|
74
|
-
- spec/fixtures/objects/amf0-time.bin
|
75
|
-
- spec/fixtures/objects/amf0-typed-object.bin
|
76
|
-
- spec/fixtures/objects/amf0-undefined.bin
|
77
|
-
- spec/fixtures/objects/amf0-untyped-object.bin
|
78
|
-
- spec/fixtures/objects/amf0-xml-doc.bin
|
79
76
|
- spec/fixtures/objects/amf3-0.bin
|
80
77
|
- spec/fixtures/objects/amf3-array-collection.bin
|
81
78
|
- spec/fixtures/objects/amf3-array-ref.bin
|
@@ -130,18 +127,18 @@ files:
|
|
130
127
|
- spec/fixtures/request/simple-request.bin
|
131
128
|
- spec/fixtures/request/simple-response.bin
|
132
129
|
- spec/fixtures/request/unsupportedCommandMessage.bin
|
133
|
-
-
|
134
|
-
-
|
135
|
-
-
|
136
|
-
-
|
137
|
-
-
|
138
|
-
-
|
139
|
-
-
|
140
|
-
-
|
141
|
-
-
|
142
|
-
- ext/rocketamf_ext/extconf.rb
|
130
|
+
- spec/helpers/class_mapping_test.rb
|
131
|
+
- spec/helpers/class_mapping_test2.rb
|
132
|
+
- spec/helpers/externalizable_test.rb
|
133
|
+
- spec/helpers/fixtures.rb
|
134
|
+
- spec/helpers/other_class.rb
|
135
|
+
- spec/helpers/ruby_class.rb
|
136
|
+
- spec/helpers/test_ruby_class.rb
|
137
|
+
- spec/serializer_spec.rb
|
138
|
+
- spec/spec_helper.rb
|
143
139
|
homepage: https://github.com/mrpin/mrpin-rocketamf
|
144
|
-
licenses:
|
140
|
+
licenses:
|
141
|
+
- MIT
|
145
142
|
metadata: {}
|
146
143
|
post_install_message:
|
147
144
|
rdoc_options:
|
@@ -162,15 +159,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
162
159
|
version: '0'
|
163
160
|
requirements: []
|
164
161
|
rubyforge_project:
|
165
|
-
rubygems_version: 2.
|
162
|
+
rubygems_version: 2.2.2
|
166
163
|
signing_key:
|
167
164
|
specification_version: 4
|
168
|
-
summary: Fast
|
169
|
-
to simplify integration
|
165
|
+
summary: Fast AMF3 serializer/deserializer
|
170
166
|
test_files:
|
171
167
|
- spec/class_mapping_spec.rb
|
172
168
|
- spec/deserializer_spec.rb
|
173
169
|
- spec/fast_class_mapping_spec.rb
|
174
|
-
- spec/messages_spec.rb
|
175
|
-
- spec/remoting_spec.rb
|
176
170
|
- spec/serializer_spec.rb
|
@@ -1,94 +0,0 @@
|
|
1
|
-
module RocketAMF
|
2
|
-
module Pure
|
3
|
-
module ReadIOHelpers #:nodoc:
|
4
|
-
def read_int8 source
|
5
|
-
source.read(1).unpack('c').first
|
6
|
-
end
|
7
|
-
|
8
|
-
def read_word8 source
|
9
|
-
source.read(1).unpack('C').first
|
10
|
-
end
|
11
|
-
|
12
|
-
def read_double source
|
13
|
-
source.read(8).unpack('G').first
|
14
|
-
end
|
15
|
-
|
16
|
-
def read_word16_network source
|
17
|
-
source.read(2).unpack('n').first
|
18
|
-
end
|
19
|
-
|
20
|
-
def read_int16_network source
|
21
|
-
str = source.read(2)
|
22
|
-
str.reverse! if byte_order_little? # swap bytes as native=little (and we want network)
|
23
|
-
str.unpack('s').first
|
24
|
-
end
|
25
|
-
|
26
|
-
def read_word32_network source
|
27
|
-
source.read(4).unpack('N').first
|
28
|
-
end
|
29
|
-
|
30
|
-
def byte_order
|
31
|
-
if [0x12345678].pack("L") == "\x12\x34\x56\x78"
|
32
|
-
:BigEndian
|
33
|
-
else
|
34
|
-
:LittleEndian
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def byte_order_little?
|
39
|
-
(byte_order == :LittleEndian) ? true : false;
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
module WriteIOHelpers #:nodoc:
|
44
|
-
def pack_integer(integer)
|
45
|
-
integer = integer & 0x1fffffff
|
46
|
-
if(integer < 0x80)
|
47
|
-
[integer].pack('c')
|
48
|
-
elsif(integer < 0x4000)
|
49
|
-
[integer >> 7 & 0x7f | 0x80].pack('c')+
|
50
|
-
[integer & 0x7f].pack('c')
|
51
|
-
elsif(integer < 0x200000)
|
52
|
-
[integer >> 14 & 0x7f | 0x80].pack('c') +
|
53
|
-
[integer >> 7 & 0x7f | 0x80].pack('c') +
|
54
|
-
[integer & 0x7f].pack('c')
|
55
|
-
else
|
56
|
-
[integer >> 22 & 0x7f | 0x80].pack('c')+
|
57
|
-
[integer >> 15 & 0x7f | 0x80].pack('c')+
|
58
|
-
[integer >> 8 & 0x7f | 0x80].pack('c')+
|
59
|
-
[integer & 0xff].pack('c')
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def pack_double(double)
|
64
|
-
[double].pack('G')
|
65
|
-
end
|
66
|
-
|
67
|
-
def pack_int8(val)
|
68
|
-
[val].pack('c')
|
69
|
-
end
|
70
|
-
|
71
|
-
def pack_int16_network(val)
|
72
|
-
[val].pack('n')
|
73
|
-
end
|
74
|
-
|
75
|
-
def pack_word32_network(val)
|
76
|
-
str = [val].pack('L')
|
77
|
-
str.reverse! if byte_order_little? # swap bytes as native=little (and we want network)
|
78
|
-
str
|
79
|
-
end
|
80
|
-
|
81
|
-
def byte_order
|
82
|
-
if [0x12345678].pack("L") == "\x12\x34\x56\x78"
|
83
|
-
:BigEndian
|
84
|
-
else
|
85
|
-
:LittleEndian
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def byte_order_little?
|
90
|
-
(byte_order == :LittleEndian) ? true : false;
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
@@ -1,117 +0,0 @@
|
|
1
|
-
require 'rocketamf/pure/io_helpers'
|
2
|
-
|
3
|
-
module RocketAMF
|
4
|
-
module Pure
|
5
|
-
# Included into RocketAMF::Envelope, this module replaces the
|
6
|
-
# populate_from_stream and serialize methods with actual working versions
|
7
|
-
module Envelope
|
8
|
-
# Included into RocketAMF::Envelope, this method handles deserializing an
|
9
|
-
# AMF request/response into the envelope
|
10
|
-
def populate_from_stream stream, class_mapper=nil
|
11
|
-
stream = StringIO.new(stream) unless StringIO === stream
|
12
|
-
des = Deserializer.new(class_mapper || RocketAMF::ClassMapper.new)
|
13
|
-
des.source = stream
|
14
|
-
|
15
|
-
# Initialize
|
16
|
-
@amf_version = 0
|
17
|
-
@headers = {}
|
18
|
-
@messages = []
|
19
|
-
|
20
|
-
# Read AMF version
|
21
|
-
@amf_version = read_word16_network stream
|
22
|
-
|
23
|
-
# Read in headers
|
24
|
-
header_count = read_word16_network stream
|
25
|
-
0.upto(header_count-1) do
|
26
|
-
name = stream.read(read_word16_network(stream))
|
27
|
-
name.force_encoding("UTF-8") if name.respond_to?(:force_encoding)
|
28
|
-
|
29
|
-
must_understand = read_int8(stream) != 0
|
30
|
-
|
31
|
-
length = read_word32_network stream
|
32
|
-
data = des.deserialize(0, nil)
|
33
|
-
|
34
|
-
@headers[name] = RocketAMF::Header.new(name, must_understand, data)
|
35
|
-
end
|
36
|
-
|
37
|
-
# Read in messages
|
38
|
-
message_count = read_word16_network stream
|
39
|
-
0.upto(message_count-1) do
|
40
|
-
target_uri = stream.read(read_word16_network(stream))
|
41
|
-
target_uri.force_encoding("UTF-8") if target_uri.respond_to?(:force_encoding)
|
42
|
-
|
43
|
-
response_uri = stream.read(read_word16_network(stream))
|
44
|
-
response_uri.force_encoding("UTF-8") if response_uri.respond_to?(:force_encoding)
|
45
|
-
|
46
|
-
length = read_word32_network stream
|
47
|
-
data = des.deserialize(0, nil)
|
48
|
-
if data.is_a?(Array) && data.length == 1 && data[0].is_a?(::RocketAMF::Values::AbstractMessage)
|
49
|
-
data = data[0]
|
50
|
-
end
|
51
|
-
|
52
|
-
@messages << RocketAMF::Message.new(target_uri, response_uri, data)
|
53
|
-
end
|
54
|
-
|
55
|
-
self
|
56
|
-
end
|
57
|
-
|
58
|
-
# Included into RocketAMF::Envelope, this method handles serializing an
|
59
|
-
# AMF request/response into a string
|
60
|
-
def serialize class_mapper=nil
|
61
|
-
ser = Serializer.new(class_mapper || RocketAMF::ClassMapper.new)
|
62
|
-
stream = ser.stream
|
63
|
-
|
64
|
-
# Write version
|
65
|
-
stream << pack_int16_network(@amf_version)
|
66
|
-
|
67
|
-
# Write headers
|
68
|
-
stream << pack_int16_network(@headers.length) # Header count
|
69
|
-
@headers.each_value do |h|
|
70
|
-
# Write header name
|
71
|
-
name_str = h.name
|
72
|
-
name_str.encode!("UTF-8").force_encoding("ASCII-8BIT") if name_str.respond_to?(:encode)
|
73
|
-
stream << pack_int16_network(name_str.bytesize)
|
74
|
-
stream << name_str
|
75
|
-
|
76
|
-
# Write must understand flag
|
77
|
-
stream << pack_int8(h.must_understand ? 1 : 0)
|
78
|
-
|
79
|
-
# Serialize data
|
80
|
-
stream << pack_word32_network(-1) # length of data - -1 if you don't know
|
81
|
-
ser.serialize(0, h.data)
|
82
|
-
end
|
83
|
-
|
84
|
-
# Write messages
|
85
|
-
stream << pack_int16_network(@messages.length) # Message count
|
86
|
-
@messages.each do |m|
|
87
|
-
# Write target_uri
|
88
|
-
uri_str = m.target_uri
|
89
|
-
uri_str.encode!("UTF-8").force_encoding("ASCII-8BIT") if uri_str.respond_to?(:encode)
|
90
|
-
stream << pack_int16_network(uri_str.bytesize)
|
91
|
-
stream << uri_str
|
92
|
-
|
93
|
-
# Write response_uri
|
94
|
-
uri_str = m.response_uri
|
95
|
-
uri_str.encode!("UTF-8").force_encoding("ASCII-8BIT") if uri_str.respond_to?(:encode)
|
96
|
-
stream << pack_int16_network(uri_str.bytesize)
|
97
|
-
stream << uri_str
|
98
|
-
|
99
|
-
# Serialize data
|
100
|
-
stream << pack_word32_network(-1) # length of data - -1 if you don't know
|
101
|
-
if @amf_version == 3
|
102
|
-
stream << AMF0_AMF3_MARKER
|
103
|
-
ser.serialize(3, m.data)
|
104
|
-
else
|
105
|
-
ser.serialize(0, m.data)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
stream
|
110
|
-
end
|
111
|
-
|
112
|
-
private
|
113
|
-
include RocketAMF::Pure::ReadIOHelpers
|
114
|
-
include RocketAMF::Pure::WriteIOHelpers
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
data/lib/rocketamf/remoting.rb
DELETED
@@ -1,196 +0,0 @@
|
|
1
|
-
module RocketAMF
|
2
|
-
# Container for the AMF request/response.
|
3
|
-
class Envelope
|
4
|
-
attr_reader :amf_version, :headers, :messages
|
5
|
-
|
6
|
-
def initialize props={}
|
7
|
-
@amf_version = props[:amf_version] || 0
|
8
|
-
@headers = props[:headers] || {}
|
9
|
-
@messages = props[:messages] || []
|
10
|
-
end
|
11
|
-
|
12
|
-
# Populates the envelope from the given stream or string using the given
|
13
|
-
# class mapper, or creates a new one. Returns self for easy chaining.
|
14
|
-
#
|
15
|
-
# Example:
|
16
|
-
#
|
17
|
-
# req = RocketAMF::Envelope.new.populate_from_stream(env['rack.input'].read)
|
18
|
-
#--
|
19
|
-
# Implemented in pure/remoting.rb RocketAMF::Pure::Envelope
|
20
|
-
def populate_from_stream stream, class_mapper=nil
|
21
|
-
raise AMFError, 'Must load "rocketamf/pure"'
|
22
|
-
end
|
23
|
-
|
24
|
-
# Creates the appropriate message and adds it to <tt>messages</tt> to call
|
25
|
-
# the given target using the standard (old) remoting APIs. You can call multiple
|
26
|
-
# targets in the same request, unlike with the flex remotings APIs.
|
27
|
-
#
|
28
|
-
# Example:
|
29
|
-
#
|
30
|
-
# req = RocketAMF::Envelope.new
|
31
|
-
# req.call 'test', "arg_1", ["args", "args"]
|
32
|
-
# req.call 'Controller.action'
|
33
|
-
def call target, *args
|
34
|
-
raise "Cannot use different call types" unless @call_type.nil? || @call_type == :simple
|
35
|
-
@call_type = :simple
|
36
|
-
|
37
|
-
msg_num = messages.length+1
|
38
|
-
@messages << RocketAMF::Message.new(target, "/#{msg_num}", args)
|
39
|
-
end
|
40
|
-
|
41
|
-
# Creates the appropriate message and adds it to <tt>messages</tt> using the
|
42
|
-
# new flex (RemoteObject) remoting APIs. You can only make one flex remoting
|
43
|
-
# call per envelope, and the AMF version must be set to 3.
|
44
|
-
#
|
45
|
-
# Example:
|
46
|
-
#
|
47
|
-
# req = RocketAMF::Envelope.new :amf_version => 3
|
48
|
-
# req.call_flex 'Controller.action', "arg_1", ["args", "args"]
|
49
|
-
def call_flex target, *args
|
50
|
-
raise "Can only call one flex target per request" if @call_type == :flex
|
51
|
-
raise "Cannot use different call types" if @call_type == :simple
|
52
|
-
raise "Cannot use flex remoting calls with AMF0" if @amf_version != 3
|
53
|
-
@call_type = :flex
|
54
|
-
|
55
|
-
flex_msg = RocketAMF::Values::RemotingMessage.new
|
56
|
-
target_parts = target.split(".")
|
57
|
-
flex_msg.operation = target_parts.pop # Use pop so that a missing source is possible without issues
|
58
|
-
flex_msg.source = target_parts.pop
|
59
|
-
flex_msg.body = args
|
60
|
-
@messages << RocketAMF::Message.new('null', '/2', flex_msg) # /2 because it always sends a command message before
|
61
|
-
end
|
62
|
-
|
63
|
-
# Serializes the envelope to a string using the given class mapper, or creates
|
64
|
-
# a new one, and returns the result
|
65
|
-
#--
|
66
|
-
# Implemented in pure/remoting.rb RocketAMF::Pure::Envelope
|
67
|
-
def serialize class_mapper=nil
|
68
|
-
raise AMFError, 'Must load "rocketamf/pure"'
|
69
|
-
end
|
70
|
-
|
71
|
-
# Builds response from the request, iterating over each method call and using
|
72
|
-
# the return value as the method call's return value. Marks as envelope as
|
73
|
-
# constructed after running.
|
74
|
-
#--
|
75
|
-
# Iterate over all the sent messages. If they're somthing we can handle, like
|
76
|
-
# a command message, then simply add the response message ourselves. If it's
|
77
|
-
# a method call, then call the block with the method and args, catching errors
|
78
|
-
# for handling. Then create the appropriate response message using the return
|
79
|
-
# value of the block as the return value for the method call.
|
80
|
-
def each_method_call request, &block
|
81
|
-
raise 'Response already constructed' if @constructed
|
82
|
-
|
83
|
-
# Set version from response
|
84
|
-
# Can't just copy version because FMS sends version as 1
|
85
|
-
@amf_version = request.amf_version == 3 ? 3 : 0
|
86
|
-
|
87
|
-
request.messages.each do |m|
|
88
|
-
# What's the request body?
|
89
|
-
case m.data
|
90
|
-
when Values::CommandMessage
|
91
|
-
# Pings should be responded to with an AcknowledgeMessage built using the ping
|
92
|
-
# Everything else is unsupported
|
93
|
-
command_msg = m.data
|
94
|
-
if command_msg.operation == Values::CommandMessage::CLIENT_PING_OPERATION
|
95
|
-
response_value = Values::AcknowledgeMessage.new(command_msg)
|
96
|
-
else
|
97
|
-
e = Exception.new("CommandMessage #{command_msg.operation} not implemented")
|
98
|
-
e.set_backtrace ["RocketAMF::Envelope each_method_call"]
|
99
|
-
response_value = Values::ErrorMessage.new(command_msg, e)
|
100
|
-
end
|
101
|
-
when Values::RemotingMessage
|
102
|
-
# Using RemoteObject style message calls
|
103
|
-
remoting_msg = m.data
|
104
|
-
acknowledge_msg = Values::AcknowledgeMessage.new(remoting_msg)
|
105
|
-
method_base = remoting_msg.source.to_s.empty? ? '' : remoting_msg.source+'.'
|
106
|
-
body = dispatch_call :method => method_base+remoting_msg.operation, :args => remoting_msg.body, :source => remoting_msg, :block => block
|
107
|
-
|
108
|
-
# Response should be the bare ErrorMessage if there was an error
|
109
|
-
if body.is_a?(Values::ErrorMessage)
|
110
|
-
response_value = body
|
111
|
-
else
|
112
|
-
acknowledge_msg.body = body
|
113
|
-
response_value = acknowledge_msg
|
114
|
-
end
|
115
|
-
else
|
116
|
-
# Standard response message
|
117
|
-
response_value = dispatch_call :method => m.target_uri, :args => m.data, :source => m, :block => block
|
118
|
-
end
|
119
|
-
|
120
|
-
target_uri = m.response_uri
|
121
|
-
target_uri += response_value.is_a?(Values::ErrorMessage) ? '/onStatus' : '/onResult'
|
122
|
-
@messages << ::RocketAMF::Message.new(target_uri, '', response_value)
|
123
|
-
end
|
124
|
-
|
125
|
-
@constructed = true
|
126
|
-
end
|
127
|
-
|
128
|
-
# Returns the result of a response envelope, or an array of results if there
|
129
|
-
# are multiple action call messages. It automatically unwraps flex-style
|
130
|
-
# RemoteObject response messages, where the response result is inside a
|
131
|
-
# RocketAMF::Values::AcknowledgeMessage.
|
132
|
-
#
|
133
|
-
# Example:
|
134
|
-
#
|
135
|
-
# req = RocketAMF::Envelope.new
|
136
|
-
# req.call('TestController.test', 'first_arg', 'second_arg')
|
137
|
-
# res = RocketAMF::Envelope.new
|
138
|
-
# res.each_method_call req do |method, args|
|
139
|
-
# ['a', 'b']
|
140
|
-
# end
|
141
|
-
# res.result #=> ['a', 'b']
|
142
|
-
def result
|
143
|
-
results = []
|
144
|
-
messages.each do |msg|
|
145
|
-
if msg.data.is_a?(Values::AcknowledgeMessage)
|
146
|
-
results << msg.data.body
|
147
|
-
else
|
148
|
-
results << msg.data
|
149
|
-
end
|
150
|
-
end
|
151
|
-
results.length > 1 ? results : results[0]
|
152
|
-
end
|
153
|
-
|
154
|
-
# Whether or not the response has been constructed. Can be used to prevent
|
155
|
-
# serialization when no processing has taken place.
|
156
|
-
def constructed?
|
157
|
-
@constructed
|
158
|
-
end
|
159
|
-
|
160
|
-
# Return the serialized envelope as a string
|
161
|
-
def to_s
|
162
|
-
serialize
|
163
|
-
end
|
164
|
-
|
165
|
-
def dispatch_call p #:nodoc:
|
166
|
-
begin
|
167
|
-
p[:block].call(p[:method], p[:args])
|
168
|
-
rescue Exception => e
|
169
|
-
# Create ErrorMessage object using the source message as the base
|
170
|
-
Values::ErrorMessage.new(p[:source], e)
|
171
|
-
end
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
# RocketAMF::Envelope header
|
176
|
-
class Header
|
177
|
-
attr_accessor :name, :must_understand, :data
|
178
|
-
|
179
|
-
def initialize name, must_understand, data
|
180
|
-
@name = name
|
181
|
-
@must_understand = must_understand
|
182
|
-
@data = data
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
# RocketAMF::Envelope message
|
187
|
-
class Message
|
188
|
-
attr_accessor :target_uri, :response_uri, :data
|
189
|
-
|
190
|
-
def initialize target_uri, response_uri, data
|
191
|
-
@target_uri = target_uri
|
192
|
-
@response_uri = response_uri
|
193
|
-
@data = data
|
194
|
-
end
|
195
|
-
end
|
196
|
-
end
|