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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/README.rdoc +1 -1
  3. data/Rakefile +7 -7
  4. data/benchmark.rb +44 -37
  5. data/ext/rocketamf_ext/class_mapping.c +11 -11
  6. data/ext/rocketamf_ext/remoting.c +1 -1
  7. data/lib/rocketamf.rb +41 -98
  8. data/lib/rocketamf/constants.rb +20 -20
  9. data/lib/rocketamf/errors.rb +2 -0
  10. data/lib/rocketamf/errors/amf_error.rb +5 -0
  11. data/lib/rocketamf/errors/amf_error_incomplete.rb +5 -0
  12. data/lib/rocketamf/ext.rb +0 -6
  13. data/lib/rocketamf/extensions.rb +4 -4
  14. data/lib/rocketamf/{class_mapping.rb → mapping/class_mapping.rb} +70 -103
  15. data/lib/rocketamf/mapping/mapping_set.rb +63 -0
  16. data/lib/rocketamf/pure.rb +1 -9
  17. data/lib/rocketamf/pure/deserializer.rb +234 -262
  18. data/lib/rocketamf/pure/helpers/io_helper_base.rb +19 -0
  19. data/lib/rocketamf/pure/helpers/io_helper_read.rb +67 -0
  20. data/lib/rocketamf/pure/helpers/io_helper_write.rb +48 -0
  21. data/lib/rocketamf/pure/helpers/object_cache.rb +20 -0
  22. data/lib/rocketamf/pure/helpers/string_cache.rb +14 -0
  23. data/lib/rocketamf/pure/serializer.rb +138 -271
  24. data/lib/rocketamf/types.rb +1 -0
  25. data/lib/rocketamf/{values → types}/typed_hash.rb +12 -2
  26. data/mrpin-rocketamf.gemspec +27 -16
  27. data/spec/class_mapping_spec.rb +59 -52
  28. data/spec/deserializer_spec.rb +164 -328
  29. data/spec/fast_class_mapping_spec.rb +52 -46
  30. data/spec/helpers/class_mapping_test.rb +4 -0
  31. data/spec/helpers/class_mapping_test2.rb +3 -0
  32. data/spec/helpers/externalizable_test.rb +24 -0
  33. data/spec/helpers/fixtures.rb +28 -0
  34. data/spec/helpers/other_class.rb +4 -0
  35. data/spec/helpers/ruby_class.rb +4 -0
  36. data/spec/helpers/test_ruby_class.rb +4 -0
  37. data/spec/serializer_spec.rb +248 -339
  38. data/spec/spec_helper.rb +4 -49
  39. metadata +47 -53
  40. data/lib/rocketamf/pure/io_helpers.rb +0 -94
  41. data/lib/rocketamf/pure/remoting.rb +0 -117
  42. data/lib/rocketamf/remoting.rb +0 -196
  43. data/lib/rocketamf/values/messages.rb +0 -214
  44. data/spec/fixtures/objects/amf0-boolean.bin +0 -1
  45. data/spec/fixtures/objects/amf0-complex-encoded-string.bin +0 -0
  46. data/spec/fixtures/objects/amf0-date.bin +0 -0
  47. data/spec/fixtures/objects/amf0-ecma-ordinal-array.bin +0 -0
  48. data/spec/fixtures/objects/amf0-empty-string-key-hash.bin +0 -0
  49. data/spec/fixtures/objects/amf0-hash.bin +0 -0
  50. data/spec/fixtures/objects/amf0-null.bin +0 -1
  51. data/spec/fixtures/objects/amf0-number.bin +0 -0
  52. data/spec/fixtures/objects/amf0-object.bin +0 -0
  53. data/spec/fixtures/objects/amf0-ref-test.bin +0 -0
  54. data/spec/fixtures/objects/amf0-strict-array.bin +0 -0
  55. data/spec/fixtures/objects/amf0-string.bin +0 -0
  56. data/spec/fixtures/objects/amf0-time.bin +0 -0
  57. data/spec/fixtures/objects/amf0-typed-object.bin +0 -0
  58. data/spec/fixtures/objects/amf0-undefined.bin +0 -1
  59. data/spec/fixtures/objects/amf0-untyped-object.bin +0 -0
  60. data/spec/fixtures/objects/amf0-xml-doc.bin +0 -0
  61. data/spec/messages_spec.rb +0 -39
  62. 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
- # Helper classes
26
- class RubyClass; attr_accessor :baz, :foo; end;
27
- class OtherClass; attr_accessor :bar, :foo; end;
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
- def write_external ser
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: 1.0.4
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: 2014-08-26 00:00:00.000000000 Z
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
- - perl.programmer@gmail.com
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
- - lib/rocketamf/class_mapping.rb
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/io_helpers.rb
48
- - lib/rocketamf/pure/remoting.rb
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/pure.rb
51
- - lib/rocketamf/remoting.rb
52
- - lib/rocketamf/values/messages.rb
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
- - ext/rocketamf_ext/class_mapping.c
134
- - ext/rocketamf_ext/deserializer.c
135
- - ext/rocketamf_ext/remoting.c
136
- - ext/rocketamf_ext/rocketamf_ext.c
137
- - ext/rocketamf_ext/serializer.c
138
- - ext/rocketamf_ext/constants.h
139
- - ext/rocketamf_ext/deserializer.h
140
- - ext/rocketamf_ext/serializer.h
141
- - ext/rocketamf_ext/utility.h
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.1.11
162
+ rubygems_version: 2.2.2
166
163
  signing_key:
167
164
  specification_version: 4
168
- summary: Fast AMF serializer/deserializer with remoting request/response wrappers
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
@@ -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