thrift 0.22.0 → 0.24.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.
- checksums.yaml +4 -4
- data/README.md +235 -17
- data/benchmark/benchmark.rb +23 -8
- data/benchmark/client.rb +50 -6
- data/benchmark/server.rb +46 -7
- data/benchmark/thin_server.rb +2 -0
- data/ext/binary_protocol_accelerated.c +154 -42
- data/ext/bytes.c +14 -0
- data/ext/compact_protocol.c +138 -45
- data/ext/constants.h +12 -0
- data/ext/extconf.rb +17 -8
- data/ext/memory_buffer.c +44 -7
- data/ext/protocol.c +29 -0
- data/ext/protocol.h +35 -0
- data/ext/struct.c +48 -17
- data/ext/thrift_native.c +28 -3
- data/lib/thrift/bytes.rb +70 -100
- data/lib/thrift/client.rb +54 -13
- data/lib/thrift/exceptions.rb +6 -5
- data/lib/thrift/multiplexed_processor.rb +20 -10
- data/lib/thrift/processor.rb +7 -6
- data/lib/thrift/protocol/base_protocol.rb +52 -21
- data/lib/thrift/protocol/binary_protocol.rb +65 -20
- data/lib/thrift/protocol/binary_protocol_accelerated.rb +6 -5
- data/lib/thrift/protocol/compact_protocol.rb +76 -41
- data/lib/thrift/protocol/header_protocol.rb +321 -0
- data/lib/thrift/protocol/json_protocol.rb +44 -27
- data/lib/thrift/protocol/multiplexed_protocol.rb +6 -5
- data/lib/thrift/protocol/protocol_decorator.rb +13 -4
- data/lib/thrift/serializer/deserializer.rb +6 -5
- data/lib/thrift/serializer/serializer.rb +5 -5
- data/lib/thrift/server/base_server.rb +5 -4
- data/lib/thrift/server/mongrel_http_server.rb +7 -6
- data/lib/thrift/server/nonblocking_server.rb +35 -9
- data/lib/thrift/server/simple_server.rb +13 -5
- data/lib/thrift/server/thin_http_server.rb +4 -3
- data/lib/thrift/server/thread_pool_server.rb +7 -6
- data/lib/thrift/server/threaded_server.rb +13 -5
- data/lib/thrift/struct.rb +12 -11
- data/lib/thrift/struct_union.rb +14 -9
- data/lib/thrift/thrift_native.rb +3 -2
- data/lib/thrift/transport/base_server_transport.rb +8 -5
- data/lib/thrift/transport/base_transport.rb +18 -14
- data/lib/thrift/transport/buffered_transport.rb +7 -6
- data/lib/thrift/transport/framed_transport.rb +8 -7
- data/lib/thrift/transport/header_transport.rb +562 -0
- data/lib/thrift/transport/http_client_transport.rb +2 -1
- data/lib/thrift/transport/io_stream_transport.rb +4 -3
- data/lib/thrift/transport/memory_buffer_transport.rb +13 -6
- data/lib/thrift/transport/server_socket.rb +14 -8
- data/lib/thrift/transport/socket.rb +126 -60
- data/lib/thrift/transport/ssl_server_socket.rb +4 -3
- data/lib/thrift/transport/ssl_socket.rb +45 -13
- data/lib/thrift/transport/unix_server_socket.rb +9 -5
- data/lib/thrift/transport/unix_socket.rb +7 -6
- data/lib/thrift/types.rb +10 -6
- data/lib/thrift/union.rb +15 -8
- data/lib/thrift/uuid.rb +50 -0
- data/lib/thrift.rb +4 -1
- data/spec/ThriftSpec.thrift +21 -1
- data/spec/base_protocol_spec.rb +21 -2
- data/spec/base_transport_spec.rb +48 -8
- data/spec/binary_protocol_accelerated_spec.rb +1 -0
- data/spec/binary_protocol_spec.rb +1 -2
- data/spec/binary_protocol_spec_shared.rb +206 -155
- data/spec/bytes_spec.rb +71 -114
- data/spec/client_spec.rb +86 -19
- data/spec/compact_protocol_spec.rb +153 -16
- data/spec/constants_demo_spec.rb +102 -0
- data/spec/exception_spec.rb +1 -1
- data/spec/flat_spec.rb +1 -0
- data/spec/header_protocol_spec.rb +476 -0
- data/spec/header_transport_spec.rb +431 -0
- data/spec/http_client_spec.rb +5 -6
- data/spec/json_protocol_spec.rb +69 -47
- data/spec/multiplexed_processor_spec.rb +75 -0
- data/spec/namespaced_spec.rb +1 -1
- data/spec/nonblocking_server_spec.rb +174 -8
- data/spec/processor_spec.rb +1 -1
- data/spec/recursion_depth_spec.rb +223 -0
- data/spec/serializer_spec.rb +1 -1
- data/spec/server_socket_spec.rb +38 -1
- data/spec/server_spec.rb +60 -9
- data/spec/socket_spec.rb +119 -13
- data/spec/socket_spec_shared.rb +73 -9
- data/spec/spec_helper.rb +2 -1
- data/spec/ssl_server_socket_spec.rb +52 -1
- data/spec/ssl_socket_spec.rb +181 -11
- data/spec/struct_nested_containers_spec.rb +2 -2
- data/spec/struct_spec.rb +114 -9
- data/spec/support/header_protocol_helper.rb +55 -0
- data/spec/thin_http_server_spec.rb +4 -18
- data/spec/types_spec.rb +26 -26
- data/spec/union_spec.rb +70 -11
- data/spec/unix_socket_spec.rb +17 -2
- data/spec/uuid_validation_spec.rb +239 -0
- data/test/fuzz/Makefile +779 -0
- data/test/fuzz/Makefile.am +173 -0
- data/test/fuzz/Makefile.in +775 -0
- data/test/fuzz/README.md +149 -0
- data/test/fuzz/fuzz_common.rb +96 -0
- data/{lib/thrift/core_ext.rb → test/fuzz/fuzz_parse_binary_protocol.rb} +4 -4
- data/{lib/thrift/core_ext/fixnum.rb → test/fuzz/fuzz_parse_binary_protocol_accelerated.rb} +7 -13
- data/test/fuzz/fuzz_parse_binary_protocol_accelerated_harness.rb +23 -0
- data/test/fuzz/fuzz_parse_binary_protocol_harness.rb +23 -0
- data/test/fuzz/fuzz_parse_compact_protocol.rb +23 -0
- data/test/fuzz/fuzz_parse_compact_protocol_harness.rb +23 -0
- data/test/fuzz/fuzz_parse_json_protocol.rb +23 -0
- data/test/fuzz/fuzz_parse_json_protocol_harness.rb +23 -0
- data/test/fuzz/fuzz_roundtrip_binary_protocol.rb +23 -0
- data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated.rb +23 -0
- data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated_harness.rb +23 -0
- data/test/fuzz/fuzz_roundtrip_binary_protocol_harness.rb +23 -0
- data/test/fuzz/fuzz_roundtrip_compact_protocol.rb +23 -0
- data/test/fuzz/fuzz_roundtrip_compact_protocol_harness.rb +23 -0
- data/test/fuzz/fuzz_roundtrip_json_protocol.rb +23 -0
- data/test/fuzz/fuzz_roundtrip_json_protocol_harness.rb +23 -0
- data/test/fuzz/fuzz_tracer.rb +29 -0
- metadata +105 -70
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
#
|
|
2
3
|
# Licensed to the Apache Software Foundation (ASF) under one
|
|
3
4
|
# or more contributor license agreements. See the NOTICE file
|
|
4
5
|
# distributed with this work for additional information
|
|
@@ -6,9 +7,9 @@
|
|
|
6
7
|
# to you under the Apache License, Version 2.0 (the
|
|
7
8
|
# "License"); you may not use this file except in compliance
|
|
8
9
|
# with the License. You may obtain a copy of the License at
|
|
9
|
-
#
|
|
10
|
+
#
|
|
10
11
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
-
#
|
|
12
|
+
#
|
|
12
13
|
# Unless required by applicable law or agreed to in writing,
|
|
13
14
|
# software distributed under the License is distributed on an
|
|
14
15
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
@@ -23,17 +24,26 @@ module Thrift
|
|
|
23
24
|
class MultiplexedProcessor
|
|
24
25
|
def initialize
|
|
25
26
|
@actual_processors = {}
|
|
27
|
+
@default_processor = nil
|
|
26
28
|
end
|
|
27
|
-
|
|
29
|
+
|
|
28
30
|
def register_processor(service_name, processor)
|
|
29
31
|
@actual_processors[service_name] = processor
|
|
30
32
|
end
|
|
31
|
-
|
|
33
|
+
|
|
34
|
+
def register_default(processor)
|
|
35
|
+
@default_processor = processor
|
|
36
|
+
end
|
|
37
|
+
|
|
32
38
|
def process(iprot, oprot)
|
|
33
39
|
name, type, seqid = iprot.read_message_begin
|
|
34
40
|
check_type(type)
|
|
35
|
-
|
|
36
|
-
|
|
41
|
+
if name.count(':') < 1
|
|
42
|
+
check_default_processor(name)
|
|
43
|
+
return @default_processor.process(StoredMessageProtocol.new(iprot, [name, type, seqid]), oprot)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
service_name, method = name.split(':', 2)
|
|
37
47
|
processor(service_name).process(StoredMessageProtocol.new(iprot, [method, type, seqid]), oprot)
|
|
38
48
|
end
|
|
39
49
|
|
|
@@ -53,8 +63,8 @@ module Thrift
|
|
|
53
63
|
end
|
|
54
64
|
end
|
|
55
65
|
|
|
56
|
-
def
|
|
57
|
-
|
|
66
|
+
def check_default_processor(name)
|
|
67
|
+
unless @default_processor
|
|
58
68
|
raise Thrift::Exception.new("Service name not found in message name: #{name}. Did you forget to use a Thrift::Protocol::MultiplexedProtocol in your client?")
|
|
59
69
|
end
|
|
60
70
|
end
|
|
@@ -63,7 +73,7 @@ module Thrift
|
|
|
63
73
|
class StoredMessageProtocol < BaseProtocol
|
|
64
74
|
|
|
65
75
|
include ProtocolDecorator
|
|
66
|
-
|
|
76
|
+
|
|
67
77
|
def initialize(protocol, message_begin)
|
|
68
78
|
super(protocol)
|
|
69
79
|
@message_begin = message_begin
|
data/lib/thrift/processor.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
#
|
|
2
3
|
# Licensed to the Apache Software Foundation (ASF) under one
|
|
3
4
|
# or more contributor license agreements. See the NOTICE file
|
|
4
5
|
# distributed with this work for additional information
|
|
@@ -6,22 +7,22 @@
|
|
|
6
7
|
# to you under the Apache License, Version 2.0 (the
|
|
7
8
|
# "License"); you may not use this file except in compliance
|
|
8
9
|
# with the License. You may obtain a copy of the License at
|
|
9
|
-
#
|
|
10
|
+
#
|
|
10
11
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
-
#
|
|
12
|
+
#
|
|
12
13
|
# Unless required by applicable law or agreed to in writing,
|
|
13
14
|
# software distributed under the License is distributed on an
|
|
14
15
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
15
16
|
# KIND, either express or implied. See the License for the
|
|
16
17
|
# specific language governing permissions and limitations
|
|
17
18
|
# under the License.
|
|
18
|
-
#
|
|
19
|
+
#
|
|
19
20
|
|
|
20
21
|
require 'logger'
|
|
21
22
|
|
|
22
23
|
module Thrift
|
|
23
24
|
module Processor
|
|
24
|
-
def initialize(handler, logger=nil)
|
|
25
|
+
def initialize(handler, logger = nil)
|
|
25
26
|
@handler = handler
|
|
26
27
|
if logger.nil?
|
|
27
28
|
@logger = Logger.new(STDERR)
|
|
@@ -32,7 +33,7 @@ module Thrift
|
|
|
32
33
|
end
|
|
33
34
|
|
|
34
35
|
def process(iprot, oprot)
|
|
35
|
-
name, type, seqid
|
|
36
|
+
name, type, seqid = iprot.read_message_begin
|
|
36
37
|
if respond_to?("process_#{name}")
|
|
37
38
|
begin
|
|
38
39
|
send("process_#{name}", seqid, iprot, oprot)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
#
|
|
2
3
|
# Licensed to the Apache Software Foundation (ASF) under one
|
|
3
4
|
# or more contributor license agreements. See the NOTICE file
|
|
4
5
|
# distributed with this work for additional information
|
|
@@ -6,16 +7,16 @@
|
|
|
6
7
|
# to you under the Apache License, Version 2.0 (the
|
|
7
8
|
# "License"); you may not use this file except in compliance
|
|
8
9
|
# with the License. You may obtain a copy of the License at
|
|
9
|
-
#
|
|
10
|
+
#
|
|
10
11
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
-
#
|
|
12
|
+
#
|
|
12
13
|
# Unless required by applicable law or agreed to in writing,
|
|
13
14
|
# software distributed under the License is distributed on an
|
|
14
15
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
15
16
|
# KIND, either express or implied. See the License for the
|
|
16
17
|
# specific language governing permissions and limitations
|
|
17
18
|
# under the License.
|
|
18
|
-
#
|
|
19
|
+
#
|
|
19
20
|
|
|
20
21
|
# this require is to make generated struct definitions happy
|
|
21
22
|
require 'set'
|
|
@@ -33,7 +34,7 @@ module Thrift
|
|
|
33
34
|
|
|
34
35
|
attr_reader :type
|
|
35
36
|
|
|
36
|
-
def initialize(type=UNKNOWN, message=nil)
|
|
37
|
+
def initialize(type = UNKNOWN, message = nil)
|
|
37
38
|
super(message)
|
|
38
39
|
@type = type
|
|
39
40
|
end
|
|
@@ -116,7 +117,7 @@ module Thrift
|
|
|
116
117
|
raise NotImplementedError
|
|
117
118
|
end
|
|
118
119
|
|
|
119
|
-
# Writes a Thrift String.
|
|
120
|
+
# Writes a Thrift String. The String passed will be transcoded to UTF-8.
|
|
120
121
|
#
|
|
121
122
|
# str - The String to write.
|
|
122
123
|
#
|
|
@@ -127,7 +128,7 @@ module Thrift
|
|
|
127
128
|
raise NotImplementedError
|
|
128
129
|
end
|
|
129
130
|
|
|
130
|
-
# Writes a Thrift Binary (Thrift String with no encoding).
|
|
131
|
+
# Writes a Thrift Binary (Thrift String with no encoding). The String passed
|
|
131
132
|
# will forced into BINARY encoding.
|
|
132
133
|
#
|
|
133
134
|
# buf - The String to write.
|
|
@@ -137,6 +138,15 @@ module Thrift
|
|
|
137
138
|
raise NotImplementedError
|
|
138
139
|
end
|
|
139
140
|
|
|
141
|
+
# Writes a UUID as 16 bytes.
|
|
142
|
+
#
|
|
143
|
+
# uuid - The UUID string to write (e.g. "550e8400-e29b-41d4-a716-446655440000").
|
|
144
|
+
#
|
|
145
|
+
# Returns nothing.
|
|
146
|
+
def write_uuid(uuid)
|
|
147
|
+
raise NotImplementedError
|
|
148
|
+
end
|
|
149
|
+
|
|
140
150
|
def read_message_begin
|
|
141
151
|
raise NotImplementedError
|
|
142
152
|
end
|
|
@@ -197,14 +207,14 @@ module Thrift
|
|
|
197
207
|
raise NotImplementedError
|
|
198
208
|
end
|
|
199
209
|
|
|
200
|
-
# Reads a Thrift String.
|
|
210
|
+
# Reads a Thrift String. All Strings will be returned with an Encoding of UTF-8.
|
|
201
211
|
#
|
|
202
212
|
# Returns a String.
|
|
203
213
|
def read_string
|
|
204
214
|
raise NotImplementedError
|
|
205
215
|
end
|
|
206
216
|
|
|
207
|
-
# Reads a Thrift Binary (Thrift String without encoding).
|
|
217
|
+
# Reads a Thrift Binary (Thrift String without encoding). All Strings will be returned
|
|
208
218
|
# with an Encoding of BINARY.
|
|
209
219
|
#
|
|
210
220
|
# Returns a String.
|
|
@@ -212,6 +222,13 @@ module Thrift
|
|
|
212
222
|
raise NotImplementedError
|
|
213
223
|
end
|
|
214
224
|
|
|
225
|
+
# Reads a UUID as 16 bytes and returns it as a string.
|
|
226
|
+
#
|
|
227
|
+
# Returns a String (e.g. "550e8400-e29b-41d4-a716-446655440000").
|
|
228
|
+
def read_uuid
|
|
229
|
+
raise NotImplementedError
|
|
230
|
+
end
|
|
231
|
+
|
|
215
232
|
# Writes a field based on the field information, field ID and value.
|
|
216
233
|
#
|
|
217
234
|
# field_info - A Hash containing the definition of the field:
|
|
@@ -251,9 +268,9 @@ module Thrift
|
|
|
251
268
|
#
|
|
252
269
|
# Returns nothing.
|
|
253
270
|
def write_type(field_info, value)
|
|
254
|
-
# if field_info is a
|
|
271
|
+
# if field_info is a Integer, assume it is a Thrift::Types constant
|
|
255
272
|
# convert it into a field_info Hash for backwards compatibility
|
|
256
|
-
if field_info.is_a?
|
|
273
|
+
if field_info.is_a? Integer
|
|
257
274
|
field_info = {:type => field_info}
|
|
258
275
|
end
|
|
259
276
|
|
|
@@ -276,6 +293,8 @@ module Thrift
|
|
|
276
293
|
else
|
|
277
294
|
write_string(value)
|
|
278
295
|
end
|
|
296
|
+
when Types::UUID
|
|
297
|
+
write_uuid(value)
|
|
279
298
|
when Types::STRUCT
|
|
280
299
|
value.write(self)
|
|
281
300
|
else
|
|
@@ -291,9 +310,9 @@ module Thrift
|
|
|
291
310
|
#
|
|
292
311
|
# Returns the value read; object type varies based on field_info[:type].
|
|
293
312
|
def read_type(field_info)
|
|
294
|
-
# if field_info is a
|
|
313
|
+
# if field_info is a Integer, assume it is a Thrift::Types constant
|
|
295
314
|
# convert it into a field_info Hash for backwards compatibility
|
|
296
|
-
if field_info.is_a?
|
|
315
|
+
if field_info.is_a? Integer
|
|
297
316
|
field_info = {:type => field_info}
|
|
298
317
|
end
|
|
299
318
|
|
|
@@ -316,12 +335,15 @@ module Thrift
|
|
|
316
335
|
else
|
|
317
336
|
read_string
|
|
318
337
|
end
|
|
338
|
+
when Types::UUID
|
|
339
|
+
read_uuid
|
|
319
340
|
else
|
|
320
341
|
raise NotImplementedError
|
|
321
342
|
end
|
|
322
343
|
end
|
|
323
344
|
|
|
324
|
-
def skip(type)
|
|
345
|
+
def skip(type, max_depth = 64)
|
|
346
|
+
raise ProtocolException.new(ProtocolException::DEPTH_LIMIT, 'Maximum skip depth exceeded') if max_depth <= 0
|
|
325
347
|
case type
|
|
326
348
|
when Types::BOOL
|
|
327
349
|
read_bool
|
|
@@ -337,39 +359,48 @@ module Thrift
|
|
|
337
359
|
read_double
|
|
338
360
|
when Types::STRING
|
|
339
361
|
read_string
|
|
362
|
+
when Types::UUID
|
|
363
|
+
read_uuid
|
|
340
364
|
when Types::STRUCT
|
|
341
365
|
read_struct_begin
|
|
342
366
|
while true
|
|
343
367
|
name, type, id = read_field_begin
|
|
344
368
|
break if type == Types::STOP
|
|
345
|
-
skip(type)
|
|
369
|
+
skip(type, max_depth - 1)
|
|
346
370
|
read_field_end
|
|
347
371
|
end
|
|
348
372
|
read_struct_end
|
|
349
373
|
when Types::MAP
|
|
350
374
|
ktype, vtype, size = read_map_begin
|
|
375
|
+
validate_container_size(size)
|
|
351
376
|
size.times do
|
|
352
|
-
skip(ktype)
|
|
353
|
-
skip(vtype)
|
|
377
|
+
skip(ktype, max_depth - 1)
|
|
378
|
+
skip(vtype, max_depth - 1)
|
|
354
379
|
end
|
|
355
380
|
read_map_end
|
|
356
381
|
when Types::SET
|
|
357
382
|
etype, size = read_set_begin
|
|
383
|
+
validate_container_size(size)
|
|
358
384
|
size.times do
|
|
359
|
-
skip(etype)
|
|
385
|
+
skip(etype, max_depth - 1)
|
|
360
386
|
end
|
|
361
387
|
read_set_end
|
|
362
388
|
when Types::LIST
|
|
363
389
|
etype, size = read_list_begin
|
|
390
|
+
validate_container_size(size)
|
|
364
391
|
size.times do
|
|
365
|
-
skip(etype)
|
|
392
|
+
skip(etype, max_depth - 1)
|
|
366
393
|
end
|
|
367
394
|
read_list_end
|
|
368
395
|
else
|
|
369
396
|
raise ProtocolException.new(ProtocolException::INVALID_DATA, 'Invalid data')
|
|
370
397
|
end
|
|
371
398
|
end
|
|
372
|
-
|
|
399
|
+
|
|
400
|
+
def validate_container_size(size)
|
|
401
|
+
raise ProtocolException.new(ProtocolException::NEGATIVE_SIZE, 'Negative size') unless size >= 0
|
|
402
|
+
end
|
|
403
|
+
|
|
373
404
|
def to_s
|
|
374
405
|
"#{trans.to_s}"
|
|
375
406
|
end
|
|
@@ -379,7 +410,7 @@ module Thrift
|
|
|
379
410
|
def get_protocol(trans)
|
|
380
411
|
raise NotImplementedError
|
|
381
412
|
end
|
|
382
|
-
|
|
413
|
+
|
|
383
414
|
def to_s
|
|
384
415
|
"base"
|
|
385
416
|
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
#
|
|
2
3
|
# Licensed to the Apache Software Foundation (ASF) under one
|
|
3
4
|
# or more contributor license agreements. See the NOTICE file
|
|
4
5
|
# distributed with this work for additional information
|
|
@@ -6,26 +7,34 @@
|
|
|
6
7
|
# to you under the Apache License, Version 2.0 (the
|
|
7
8
|
# "License"); you may not use this file except in compliance
|
|
8
9
|
# with the License. You may obtain a copy of the License at
|
|
9
|
-
#
|
|
10
|
+
#
|
|
10
11
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
-
#
|
|
12
|
+
#
|
|
12
13
|
# Unless required by applicable law or agreed to in writing,
|
|
13
14
|
# software distributed under the License is distributed on an
|
|
14
15
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
15
16
|
# KIND, either express or implied. See the License for the
|
|
16
17
|
# specific language governing permissions and limitations
|
|
17
18
|
# under the License.
|
|
18
|
-
#
|
|
19
|
+
#
|
|
19
20
|
|
|
20
21
|
module Thrift
|
|
21
22
|
class BinaryProtocol < BaseProtocol
|
|
22
23
|
VERSION_MASK = 0xffff0000
|
|
23
24
|
VERSION_1 = 0x80010000
|
|
24
25
|
TYPE_MASK = 0x000000ff
|
|
25
|
-
|
|
26
|
+
BYTE_MIN = -2**7
|
|
27
|
+
BYTE_MAX = 2**7 - 1
|
|
28
|
+
I16_MIN = -2**15
|
|
29
|
+
I16_MAX = 2**15 - 1
|
|
30
|
+
I32_MIN = -2**31
|
|
31
|
+
I32_MAX = 2**31 - 1
|
|
32
|
+
I64_MIN = -2**63
|
|
33
|
+
I64_MAX = 2**63 - 1
|
|
34
|
+
|
|
26
35
|
attr_reader :strict_read, :strict_write
|
|
27
36
|
|
|
28
|
-
def initialize(trans, strict_read=true, strict_write=true)
|
|
37
|
+
def initialize(trans, strict_read = true, strict_write = true)
|
|
29
38
|
super(trans)
|
|
30
39
|
@strict_read = strict_read
|
|
31
40
|
@strict_write = strict_write
|
|
@@ -36,11 +45,10 @@ module Thrift
|
|
|
36
45
|
end
|
|
37
46
|
|
|
38
47
|
def write_message_begin(name, type, seqid)
|
|
39
|
-
# this is necessary because we added (needed) bounds checking to
|
|
40
|
-
# write_i32, and 0x80010000 is too big for that.
|
|
41
48
|
if strict_write
|
|
42
|
-
|
|
43
|
-
|
|
49
|
+
raise ::TypeError, 'integer argument expected' unless type.is_a?(Integer)
|
|
50
|
+
raise RangeError if type < BYTE_MIN || type > BYTE_MAX
|
|
51
|
+
trans.write([VERSION_1 | type].pack('N'))
|
|
44
52
|
write_string(name)
|
|
45
53
|
write_i32(seqid)
|
|
46
54
|
else
|
|
@@ -64,17 +72,17 @@ module Thrift
|
|
|
64
72
|
def write_map_begin(ktype, vtype, size)
|
|
65
73
|
write_byte(ktype)
|
|
66
74
|
write_byte(vtype)
|
|
67
|
-
|
|
75
|
+
write_i32_size(size)
|
|
68
76
|
end
|
|
69
77
|
|
|
70
78
|
def write_list_begin(etype, size)
|
|
71
79
|
write_byte(etype)
|
|
72
|
-
|
|
80
|
+
write_i32_size(size)
|
|
73
81
|
end
|
|
74
82
|
|
|
75
83
|
def write_set_begin(etype, size)
|
|
76
84
|
write_byte(etype)
|
|
77
|
-
|
|
85
|
+
write_i32_size(size)
|
|
78
86
|
end
|
|
79
87
|
|
|
80
88
|
def write_bool(bool)
|
|
@@ -82,40 +90,57 @@ module Thrift
|
|
|
82
90
|
end
|
|
83
91
|
|
|
84
92
|
def write_byte(byte)
|
|
85
|
-
raise
|
|
93
|
+
raise 'nil argument not allowed!' if byte.nil?
|
|
94
|
+
raise ::TypeError, 'integer argument expected' unless byte.is_a?(Integer)
|
|
95
|
+
raise RangeError if byte < BYTE_MIN || byte > BYTE_MAX
|
|
86
96
|
trans.write([byte].pack('c'))
|
|
87
97
|
end
|
|
88
98
|
|
|
89
99
|
def write_i16(i16)
|
|
100
|
+
raise 'nil argument not allowed!' if i16.nil?
|
|
101
|
+
raise ::TypeError, 'integer argument expected' unless i16.is_a?(Integer)
|
|
102
|
+
raise RangeError if i16 < I16_MIN || i16 > I16_MAX
|
|
90
103
|
trans.write([i16].pack('n'))
|
|
91
104
|
end
|
|
92
105
|
|
|
93
106
|
def write_i32(i32)
|
|
94
|
-
raise
|
|
107
|
+
raise 'nil argument not allowed!' if i32.nil?
|
|
108
|
+
raise ::TypeError, 'integer argument expected' unless i32.is_a?(Integer)
|
|
109
|
+
raise RangeError if i32 < I32_MIN || i32 > I32_MAX
|
|
95
110
|
trans.write([i32].pack('N'))
|
|
96
111
|
end
|
|
97
112
|
|
|
98
113
|
def write_i64(i64)
|
|
99
|
-
raise
|
|
114
|
+
raise 'nil argument not allowed!' if i64.nil?
|
|
115
|
+
raise ::TypeError, 'integer argument expected' unless i64.is_a?(Integer)
|
|
116
|
+
raise RangeError if i64 < I64_MIN || i64 > I64_MAX
|
|
100
117
|
hi = i64 >> 32
|
|
101
118
|
lo = i64 & 0xffffffff
|
|
102
119
|
trans.write([hi, lo].pack('N2'))
|
|
103
120
|
end
|
|
104
121
|
|
|
105
122
|
def write_double(dub)
|
|
123
|
+
raise 'nil argument not allowed!' if dub.nil?
|
|
106
124
|
trans.write([dub].pack('G'))
|
|
107
125
|
end
|
|
108
126
|
|
|
109
127
|
def write_string(str)
|
|
128
|
+
raise 'nil argument not allowed!' if str.nil?
|
|
110
129
|
buf = Bytes.convert_to_utf8_byte_buffer(str)
|
|
111
130
|
write_binary(buf)
|
|
112
131
|
end
|
|
113
132
|
|
|
114
133
|
def write_binary(buf)
|
|
115
|
-
|
|
134
|
+
raise 'nil argument not allowed!' if buf.nil?
|
|
135
|
+
write_i32_size(buf.bytesize)
|
|
116
136
|
trans.write(buf)
|
|
117
137
|
end
|
|
118
138
|
|
|
139
|
+
def write_uuid(uuid)
|
|
140
|
+
UUID.validate_uuid!(uuid)
|
|
141
|
+
trans.write(UUID.uuid_bytes(uuid))
|
|
142
|
+
end
|
|
143
|
+
|
|
119
144
|
def read_message_begin
|
|
120
145
|
version = read_i32
|
|
121
146
|
if version < 0
|
|
@@ -153,18 +178,21 @@ module Thrift
|
|
|
153
178
|
ktype = read_byte
|
|
154
179
|
vtype = read_byte
|
|
155
180
|
size = read_i32
|
|
181
|
+
raise ProtocolException.new(ProtocolException::NEGATIVE_SIZE, 'Negative size') unless size >= 0
|
|
156
182
|
[ktype, vtype, size]
|
|
157
183
|
end
|
|
158
184
|
|
|
159
185
|
def read_list_begin
|
|
160
186
|
etype = read_byte
|
|
161
187
|
size = read_i32
|
|
188
|
+
raise ProtocolException.new(ProtocolException::NEGATIVE_SIZE, 'Negative size') unless size >= 0
|
|
162
189
|
[etype, size]
|
|
163
190
|
end
|
|
164
191
|
|
|
165
192
|
def read_set_begin
|
|
166
193
|
etype = read_byte
|
|
167
194
|
size = read_i32
|
|
195
|
+
raise ProtocolException.new(ProtocolException::NEGATIVE_SIZE, 'Negative size') unless size >= 0
|
|
168
196
|
[etype, size]
|
|
169
197
|
end
|
|
170
198
|
|
|
@@ -224,19 +252,36 @@ module Thrift
|
|
|
224
252
|
|
|
225
253
|
def read_binary
|
|
226
254
|
size = read_i32
|
|
227
|
-
|
|
255
|
+
if size >= 0
|
|
256
|
+
trans.read_all(size)
|
|
257
|
+
else
|
|
258
|
+
raise ProtocolException.new(ProtocolException::NEGATIVE_SIZE, 'Negative size')
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def read_uuid
|
|
263
|
+
UUID.uuid_from_bytes(trans.read_all(16))
|
|
228
264
|
end
|
|
229
|
-
|
|
265
|
+
|
|
230
266
|
def to_s
|
|
231
267
|
"binary(#{super.to_s})"
|
|
232
268
|
end
|
|
269
|
+
|
|
270
|
+
private
|
|
271
|
+
|
|
272
|
+
def write_i32_size(size)
|
|
273
|
+
raise 'nil argument not allowed!' if size.nil?
|
|
274
|
+
raise ::TypeError, 'integer argument expected' unless size.is_a?(Integer)
|
|
275
|
+
raise RangeError if size < 0 || size > I32_MAX
|
|
276
|
+
trans.write([size].pack('N'))
|
|
277
|
+
end
|
|
233
278
|
end
|
|
234
279
|
|
|
235
280
|
class BinaryProtocolFactory < BaseProtocolFactory
|
|
236
281
|
def get_protocol(trans)
|
|
237
282
|
return Thrift::BinaryProtocol.new(trans)
|
|
238
283
|
end
|
|
239
|
-
|
|
284
|
+
|
|
240
285
|
def to_s
|
|
241
286
|
"binary"
|
|
242
287
|
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
#
|
|
2
3
|
# Licensed to the Apache Software Foundation (ASF) under one
|
|
3
4
|
# or more contributor license agreements. See the NOTICE file
|
|
4
5
|
# distributed with this work for additional information
|
|
@@ -6,20 +7,20 @@
|
|
|
6
7
|
# to you under the Apache License, Version 2.0 (the
|
|
7
8
|
# "License"); you may not use this file except in compliance
|
|
8
9
|
# with the License. You may obtain a copy of the License at
|
|
9
|
-
#
|
|
10
|
+
#
|
|
10
11
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
-
#
|
|
12
|
+
#
|
|
12
13
|
# Unless required by applicable law or agreed to in writing,
|
|
13
14
|
# software distributed under the License is distributed on an
|
|
14
15
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
15
16
|
# KIND, either express or implied. See the License for the
|
|
16
17
|
# specific language governing permissions and limitations
|
|
17
18
|
# under the License.
|
|
18
|
-
#
|
|
19
|
+
#
|
|
19
20
|
|
|
20
21
|
=begin
|
|
21
22
|
The only change required for a transport to support BinaryProtocolAccelerated is to implement 2 methods:
|
|
22
|
-
* borrow(size), which takes an optional argument and returns atleast _size_ bytes from the transport,
|
|
23
|
+
* borrow(size), which takes an optional argument and returns atleast _size_ bytes from the transport,
|
|
23
24
|
or the default buffer size if no argument is given
|
|
24
25
|
* consume!(size), which removes size bytes from the front of the buffer
|
|
25
26
|
|