thrift 0.24.0 → 0.25.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 +107 -4
- data/ext/binary_protocol_accelerated.c +52 -17
- data/ext/compact_protocol.c +135 -70
- data/ext/constants.h +3 -0
- data/ext/extconf.rb +4 -4
- data/ext/macros.h +11 -0
- data/ext/memory_buffer.c +35 -17
- data/ext/struct.c +185 -64
- data/ext/thrift_native.c +6 -0
- data/lib/thrift/bytes.rb +2 -2
- data/lib/thrift/client.rb +31 -22
- data/lib/thrift/exceptions.rb +10 -8
- data/lib/thrift/multiplexed_processor.rb +5 -6
- data/lib/thrift/processor.rb +24 -3
- data/lib/thrift/protocol/base_protocol.rb +53 -27
- data/lib/thrift/protocol/binary_protocol.rb +54 -40
- data/lib/thrift/protocol/binary_protocol_accelerated.rb +6 -2
- data/lib/thrift/protocol/compact_protocol.rb +193 -88
- data/lib/thrift/protocol/header_protocol.rb +14 -3
- data/lib/thrift/protocol/json_protocol.rb +146 -104
- data/lib/thrift/protocol/multiplexed_protocol.rb +2 -3
- data/lib/thrift/protocol/protocol_decorator.rb +5 -2
- data/lib/thrift/serializer/serializer.rb +6 -0
- data/lib/thrift/server/base_server.rb +10 -2
- data/lib/thrift/server/nonblocking_server.rb +49 -26
- data/lib/thrift/server/rack_application.rb +69 -0
- data/lib/thrift/server/simple_server.rb +27 -23
- data/lib/thrift/server/thin_http_server.rb +20 -44
- data/lib/thrift/server/thread_pool_server.rb +20 -17
- data/lib/thrift/server/threaded_server.rb +22 -26
- data/lib/thrift/struct.rb +33 -18
- data/lib/thrift/struct_union.rb +36 -30
- data/lib/thrift/transport/base_transport.rb +23 -5
- data/lib/thrift/transport/buffered_transport.rb +4 -4
- data/lib/thrift/transport/framed_transport.rb +32 -7
- data/lib/thrift/transport/header_transport.rb +130 -50
- data/lib/thrift/transport/http_client_transport.rb +27 -14
- data/lib/thrift/transport/io_stream_transport.rb +2 -1
- data/lib/thrift/transport/memory_buffer_transport.rb +8 -10
- data/lib/thrift/transport/server_socket.rb +4 -5
- data/lib/thrift/transport/socket.rb +20 -22
- data/lib/thrift/transport/ssl_server_socket.rb +64 -4
- data/lib/thrift/transport/ssl_socket.rb +32 -5
- data/lib/thrift/transport/unix_server_socket.rb +1 -1
- data/lib/thrift/transport/unix_socket.rb +4 -6
- data/lib/thrift/types.rb +22 -22
- data/lib/thrift/union.rb +20 -11
- data/lib/thrift/uuid.rb +8 -8
- data/lib/thrift.rb +39 -39
- metadata +5 -230
- data/benchmark/Benchmark.thrift +0 -24
- data/benchmark/benchmark.rb +0 -286
- data/benchmark/client.rb +0 -118
- data/benchmark/server.rb +0 -121
- data/benchmark/thin_server.rb +0 -46
- data/lib/thrift/server/mongrel_http_server.rb +0 -61
- data/spec/BaseService.thrift +0 -27
- data/spec/ExtendedService.thrift +0 -25
- data/spec/Referenced.thrift +0 -44
- data/spec/ThriftNamespacedSpec.thrift +0 -53
- data/spec/ThriftSpec.thrift +0 -203
- data/spec/base_protocol_spec.rb +0 -244
- data/spec/base_transport_spec.rb +0 -428
- data/spec/binary_protocol_accelerated_spec.rb +0 -47
- data/spec/binary_protocol_spec.rb +0 -73
- data/spec/binary_protocol_spec_shared.rb +0 -509
- data/spec/bytes_spec.rb +0 -117
- data/spec/client_spec.rb +0 -167
- data/spec/compact_protocol_spec.rb +0 -295
- data/spec/constants_demo_spec.rb +0 -102
- data/spec/exception_spec.rb +0 -141
- data/spec/flat_spec.rb +0 -63
- data/spec/header_protocol_spec.rb +0 -476
- data/spec/header_transport_spec.rb +0 -431
- data/spec/http_client_spec.rb +0 -160
- data/spec/json_protocol_spec.rb +0 -574
- data/spec/multiplexed_processor_spec.rb +0 -75
- data/spec/namespaced_spec.rb +0 -67
- data/spec/nonblocking_server_spec.rb +0 -429
- data/spec/processor_spec.rb +0 -80
- data/spec/recursion_depth_spec.rb +0 -223
- data/spec/serializer_spec.rb +0 -67
- data/spec/server_socket_spec.rb +0 -121
- data/spec/server_spec.rb +0 -238
- data/spec/socket_spec.rb +0 -174
- data/spec/socket_spec_shared.rb +0 -168
- data/spec/spec_helper.rb +0 -70
- data/spec/ssl_server_socket_spec.rb +0 -85
- data/spec/ssl_socket_spec.rb +0 -248
- data/spec/struct_nested_containers_spec.rb +0 -191
- data/spec/struct_spec.rb +0 -398
- data/spec/support/header_protocol_helper.rb +0 -55
- data/spec/thin_http_server_spec.rb +0 -127
- data/spec/types_spec.rb +0 -118
- data/spec/union_spec.rb +0 -273
- data/spec/unix_socket_spec.rb +0 -131
- data/spec/uuid_validation_spec.rb +0 -239
- data/test/fuzz/Makefile +0 -779
- data/test/fuzz/Makefile.am +0 -173
- data/test/fuzz/Makefile.in +0 -775
- data/test/fuzz/README.md +0 -149
- data/test/fuzz/fuzz_common.rb +0 -96
- data/test/fuzz/fuzz_parse_binary_protocol.rb +0 -23
- data/test/fuzz/fuzz_parse_binary_protocol_accelerated.rb +0 -23
- data/test/fuzz/fuzz_parse_binary_protocol_accelerated_harness.rb +0 -23
- data/test/fuzz/fuzz_parse_binary_protocol_harness.rb +0 -23
- data/test/fuzz/fuzz_parse_compact_protocol.rb +0 -23
- data/test/fuzz/fuzz_parse_compact_protocol_harness.rb +0 -23
- data/test/fuzz/fuzz_parse_json_protocol.rb +0 -23
- data/test/fuzz/fuzz_parse_json_protocol_harness.rb +0 -23
- data/test/fuzz/fuzz_roundtrip_binary_protocol.rb +0 -23
- data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated.rb +0 -23
- data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated_harness.rb +0 -23
- data/test/fuzz/fuzz_roundtrip_binary_protocol_harness.rb +0 -23
- data/test/fuzz/fuzz_roundtrip_compact_protocol.rb +0 -23
- data/test/fuzz/fuzz_roundtrip_compact_protocol_harness.rb +0 -23
- data/test/fuzz/fuzz_roundtrip_json_protocol.rb +0 -23
- data/test/fuzz/fuzz_roundtrip_json_protocol_harness.rb +0 -23
- data/test/fuzz/fuzz_tracer.rb +0 -29
|
@@ -34,7 +34,7 @@ module Thrift
|
|
|
34
34
|
@data = @trans.read(1)
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
@data
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
def peek
|
|
@@ -42,7 +42,7 @@ module Thrift
|
|
|
42
42
|
@data = @trans.read(1)
|
|
43
43
|
end
|
|
44
44
|
@hasData = true
|
|
45
|
-
|
|
45
|
+
@data
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
|
|
@@ -51,7 +51,7 @@ module Thrift
|
|
|
51
51
|
# implementations
|
|
52
52
|
#
|
|
53
53
|
class JSONContext
|
|
54
|
-
@@kJSONElemSeparator =
|
|
54
|
+
@@kJSONElemSeparator = ","
|
|
55
55
|
#
|
|
56
56
|
# Write context data to the trans. Default is to do nothing.
|
|
57
57
|
#
|
|
@@ -69,13 +69,13 @@ module Thrift
|
|
|
69
69
|
# Default behavior is to return false.
|
|
70
70
|
#
|
|
71
71
|
def escapeNum
|
|
72
|
-
|
|
72
|
+
false
|
|
73
73
|
end
|
|
74
74
|
end
|
|
75
75
|
|
|
76
76
|
# Context class for object member key-value pairs
|
|
77
77
|
class JSONPairContext < JSONContext
|
|
78
|
-
@@kJSONPairSeparator =
|
|
78
|
+
@@kJSONPairSeparator = ":"
|
|
79
79
|
|
|
80
80
|
def initialize
|
|
81
81
|
@first = true
|
|
@@ -83,7 +83,7 @@ module Thrift
|
|
|
83
83
|
end
|
|
84
84
|
|
|
85
85
|
def write(trans)
|
|
86
|
-
if
|
|
86
|
+
if @first
|
|
87
87
|
@first = false
|
|
88
88
|
@colon = true
|
|
89
89
|
else
|
|
@@ -93,7 +93,7 @@ module Thrift
|
|
|
93
93
|
end
|
|
94
94
|
|
|
95
95
|
def read(reader)
|
|
96
|
-
if
|
|
96
|
+
if @first
|
|
97
97
|
@first = false
|
|
98
98
|
@colon = true
|
|
99
99
|
else
|
|
@@ -105,19 +105,18 @@ module Thrift
|
|
|
105
105
|
|
|
106
106
|
# Numbers must be turned into strings if they are the key part of a pair
|
|
107
107
|
def escapeNum
|
|
108
|
-
|
|
108
|
+
@colon
|
|
109
109
|
end
|
|
110
110
|
end
|
|
111
111
|
|
|
112
112
|
# Context class for lists
|
|
113
113
|
class JSONListContext < JSONContext
|
|
114
|
-
|
|
115
114
|
def initialize
|
|
116
115
|
@first = true
|
|
117
116
|
end
|
|
118
117
|
|
|
119
118
|
def write(trans)
|
|
120
|
-
if
|
|
119
|
+
if @first
|
|
121
120
|
@first = false
|
|
122
121
|
else
|
|
123
122
|
trans.write(@@kJSONElemSeparator)
|
|
@@ -125,7 +124,7 @@ module Thrift
|
|
|
125
124
|
end
|
|
126
125
|
|
|
127
126
|
def read(reader)
|
|
128
|
-
if
|
|
127
|
+
if @first
|
|
129
128
|
@first = false
|
|
130
129
|
else
|
|
131
130
|
JsonProtocol::read_syntax_char(reader, @@kJSONElemSeparator)
|
|
@@ -134,13 +133,14 @@ module Thrift
|
|
|
134
133
|
end
|
|
135
134
|
|
|
136
135
|
class JsonProtocol < BaseProtocol
|
|
136
|
+
attr_reader :max_string_size
|
|
137
137
|
|
|
138
|
-
@@kJSONObjectStart =
|
|
139
|
-
@@kJSONObjectEnd =
|
|
140
|
-
@@kJSONArrayStart =
|
|
141
|
-
@@kJSONArrayEnd =
|
|
138
|
+
@@kJSONObjectStart = "{"
|
|
139
|
+
@@kJSONObjectEnd = "}"
|
|
140
|
+
@@kJSONArrayStart = "["
|
|
141
|
+
@@kJSONArrayEnd = "]"
|
|
142
142
|
@@kJSONNewline = '\n'
|
|
143
|
-
@@kJSONBackslash =
|
|
143
|
+
@@kJSONBackslash = "\\"
|
|
144
144
|
@@kJSONStringDelimiter = '"'
|
|
145
145
|
|
|
146
146
|
@@kThriftVersion1 = 1
|
|
@@ -149,8 +149,10 @@ module Thrift
|
|
|
149
149
|
@@kThriftInfinity = "Infinity"
|
|
150
150
|
@@kThriftNegativeInfinity = "-Infinity"
|
|
151
151
|
|
|
152
|
-
def initialize(trans)
|
|
152
|
+
def initialize(trans, max_string_size: DEFAULT_MAX_STRING_SIZE)
|
|
153
|
+
BaseProtocol.validate_max_string_size(max_string_size)
|
|
153
154
|
super(trans)
|
|
155
|
+
@max_string_size = max_string_size
|
|
154
156
|
@context = JSONContext.new
|
|
155
157
|
@contexts = Array.new
|
|
156
158
|
@reader = LookaheadReader.new(trans)
|
|
@@ -183,42 +185,27 @@ module Thrift
|
|
|
183
185
|
when Types::UUID
|
|
184
186
|
"uid"
|
|
185
187
|
else
|
|
186
|
-
raise
|
|
188
|
+
raise ProtocolException.new(ProtocolException::INVALID_DATA, "Unknown type id: #{id}")
|
|
187
189
|
end
|
|
188
190
|
end
|
|
189
191
|
|
|
190
192
|
def get_type_id_for_type_name(name)
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
result = Types::STRING
|
|
205
|
-
elsif (name == "rec")
|
|
206
|
-
result = Types::STRUCT
|
|
207
|
-
elsif (name == "map")
|
|
208
|
-
result = Types::MAP
|
|
209
|
-
elsif (name == "set")
|
|
210
|
-
result = Types::SET
|
|
211
|
-
elsif (name == "lst")
|
|
212
|
-
result = Types::LIST
|
|
213
|
-
elsif (name == "uid")
|
|
214
|
-
result = Types::UUID
|
|
193
|
+
case name
|
|
194
|
+
when "tf" then Types::BOOL
|
|
195
|
+
when "i8" then Types::BYTE
|
|
196
|
+
when "i16" then Types::I16
|
|
197
|
+
when "i32" then Types::I32
|
|
198
|
+
when "i64" then Types::I64
|
|
199
|
+
when "dbl" then Types::DOUBLE
|
|
200
|
+
when "str" then Types::STRING
|
|
201
|
+
when "rec" then Types::STRUCT
|
|
202
|
+
when "map" then Types::MAP
|
|
203
|
+
when "set" then Types::SET
|
|
204
|
+
when "lst" then Types::LIST
|
|
205
|
+
when "uid" then Types::UUID
|
|
215
206
|
else
|
|
216
|
-
|
|
217
|
-
end
|
|
218
|
-
if (result == Types::STOP)
|
|
219
|
-
raise NotImplementedError
|
|
207
|
+
raise ProtocolException.new(ProtocolException::INVALID_DATA, "Unknown type name: #{name.inspect}")
|
|
220
208
|
end
|
|
221
|
-
return result
|
|
222
209
|
end
|
|
223
210
|
|
|
224
211
|
# Static helper functions
|
|
@@ -228,17 +215,17 @@ module Thrift
|
|
|
228
215
|
def self.read_syntax_char(reader, ch)
|
|
229
216
|
ch2 = reader.read
|
|
230
217
|
if (ch2 != ch)
|
|
231
|
-
raise ProtocolException.new(ProtocolException::INVALID_DATA, "Expected
|
|
218
|
+
raise ProtocolException.new(ProtocolException::INVALID_DATA, "Expected '#{ch}' got '#{ch2}'.")
|
|
232
219
|
end
|
|
233
220
|
end
|
|
234
221
|
|
|
235
|
-
|
|
222
|
+
# Return true if the character ch is in [-+0-9.Ee]; false otherwise
|
|
236
223
|
def is_json_numeric(ch)
|
|
237
224
|
case ch
|
|
238
|
-
when
|
|
239
|
-
|
|
225
|
+
when "+", "-", ".", "0".."9", "E", "e"
|
|
226
|
+
true
|
|
240
227
|
else
|
|
241
|
-
|
|
228
|
+
false
|
|
242
229
|
end
|
|
243
230
|
end
|
|
244
231
|
|
|
@@ -258,7 +245,7 @@ module Thrift
|
|
|
258
245
|
if (ch_value.kind_of? String)
|
|
259
246
|
ch_value = ch.bytes.first
|
|
260
247
|
end
|
|
261
|
-
trans.write(ch_value.to_s(16).rjust(4,
|
|
248
|
+
trans.write(ch_value.to_s(16).rjust(4, "0"))
|
|
262
249
|
end
|
|
263
250
|
|
|
264
251
|
# Write the character ch as part of a JSON string, escaping as appropriate.
|
|
@@ -268,10 +255,10 @@ module Thrift
|
|
|
268
255
|
# 1 : just output index
|
|
269
256
|
# <other> : escape using "\<other>" notation
|
|
270
257
|
kJSONCharTable = [
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
258
|
+
# 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
|
259
|
+
0, 0, 0, 0, 0, 0, 0, 0, "b", "t", "n", 0, "f", "r", 0, 0, # 0
|
|
260
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 1
|
|
261
|
+
1, 1, '"', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, # 2
|
|
275
262
|
]
|
|
276
263
|
|
|
277
264
|
ch_value = ch[0]
|
|
@@ -301,9 +288,10 @@ module Thrift
|
|
|
301
288
|
|
|
302
289
|
# Write out the contents of the string str as a JSON string, escaping characters as appropriate.
|
|
303
290
|
def write_json_string(str)
|
|
291
|
+
str = normalize_json_string(str)
|
|
304
292
|
@context.write(trans)
|
|
305
293
|
trans.write(@@kJSONStringDelimiter)
|
|
306
|
-
str.
|
|
294
|
+
str.each_char do |ch|
|
|
307
295
|
write_json_char(ch)
|
|
308
296
|
end
|
|
309
297
|
trans.write(@@kJSONStringDelimiter)
|
|
@@ -314,7 +302,7 @@ module Thrift
|
|
|
314
302
|
def write_json_base64(str)
|
|
315
303
|
@context.write(trans)
|
|
316
304
|
trans.write(@@kJSONStringDelimiter)
|
|
317
|
-
trans.write([str].pack(
|
|
305
|
+
trans.write([str].pack("m0"))
|
|
318
306
|
trans.write(@@kJSONStringDelimiter)
|
|
319
307
|
end
|
|
320
308
|
|
|
@@ -323,11 +311,11 @@ module Thrift
|
|
|
323
311
|
def write_json_integer(num)
|
|
324
312
|
@context.write(trans)
|
|
325
313
|
escapeNum = @context.escapeNum
|
|
326
|
-
if
|
|
314
|
+
if escapeNum
|
|
327
315
|
trans.write(@@kJSONStringDelimiter)
|
|
328
316
|
end
|
|
329
317
|
trans.write(num.to_s);
|
|
330
|
-
if
|
|
318
|
+
if escapeNum
|
|
331
319
|
trans.write(@@kJSONStringDelimiter)
|
|
332
320
|
end
|
|
333
321
|
end
|
|
@@ -338,10 +326,10 @@ module Thrift
|
|
|
338
326
|
@context.write(trans)
|
|
339
327
|
# Normalize output of thrift::to_string for NaNs and Infinities
|
|
340
328
|
special = false;
|
|
341
|
-
if
|
|
329
|
+
if num.nan?
|
|
342
330
|
special = true;
|
|
343
331
|
val = @@kThriftNan;
|
|
344
|
-
elsif
|
|
332
|
+
elsif num.infinite?
|
|
345
333
|
special = true;
|
|
346
334
|
val = @@kThriftInfinity;
|
|
347
335
|
if (num < 0.0)
|
|
@@ -352,11 +340,11 @@ module Thrift
|
|
|
352
340
|
end
|
|
353
341
|
|
|
354
342
|
escapeNum = special || @context.escapeNum
|
|
355
|
-
if
|
|
343
|
+
if escapeNum
|
|
356
344
|
trans.write(@@kJSONStringDelimiter)
|
|
357
345
|
end
|
|
358
346
|
trans.write(val)
|
|
359
|
-
if
|
|
347
|
+
if escapeNum
|
|
360
348
|
trans.write(@@kJSONStringDelimiter)
|
|
361
349
|
end
|
|
362
350
|
end
|
|
@@ -494,58 +482,65 @@ module Thrift
|
|
|
494
482
|
JsonProtocol::read_syntax_char(@reader, ch)
|
|
495
483
|
end
|
|
496
484
|
|
|
497
|
-
# Decodes the four hex parts of a JSON escaped string character and returns
|
|
498
|
-
# the character via out.
|
|
499
|
-
#
|
|
500
|
-
# Note - this only supports Unicode characters in the BMP (U+0000 to U+FFFF);
|
|
501
|
-
# characters above the BMP are encoded as two escape sequences (surrogate pairs),
|
|
502
|
-
# which is not yet implemented
|
|
503
485
|
def read_json_escape_char
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
486
|
+
code_unit = read_unicode_code_unit
|
|
487
|
+
|
|
488
|
+
if code_unit.between?(0xD800, 0xDBFF)
|
|
489
|
+
slash = @reader.read
|
|
490
|
+
marker = @reader.read
|
|
491
|
+
invalid_unicode!("Unpaired UTF-16 high surrogate") unless slash == "\\" && marker == "u"
|
|
492
|
+
|
|
493
|
+
low_surrogate = read_unicode_code_unit
|
|
494
|
+
invalid_unicode!("Unpaired UTF-16 high surrogate") unless low_surrogate.between?(0xDC00, 0xDFFF)
|
|
495
|
+
codepoint = 0x10000 + ((code_unit - 0xD800) << 10) + (low_surrogate - 0xDC00)
|
|
496
|
+
[codepoint].pack("U")
|
|
497
|
+
elsif code_unit.between?(0xDC00, 0xDFFF)
|
|
498
|
+
invalid_unicode!("Unpaired UTF-16 low surrogate")
|
|
499
|
+
else
|
|
500
|
+
[code_unit].pack("U")
|
|
501
|
+
end
|
|
502
|
+
rescue EOFError
|
|
503
|
+
invalid_unicode!("Incomplete Unicode escape")
|
|
509
504
|
end
|
|
510
505
|
|
|
511
506
|
# Decodes a JSON string, including unescaping, and returns the string via str
|
|
512
507
|
def read_json_string(skipContext = false)
|
|
513
508
|
# This string's characters must match up with the elements in escape_char_vals.
|
|
514
|
-
#
|
|
515
|
-
# it is not in the RFC -> it is. See RFC 4627
|
|
509
|
+
# JSON permits the optional solidus escape "\/"; see RFC 8259, section 7.
|
|
516
510
|
escape_chars = "\"\\/bfnrt"
|
|
517
511
|
|
|
518
512
|
# The elements of this array must match up with the sequence of characters in
|
|
519
513
|
# escape_chars
|
|
520
514
|
escape_char_vals = [
|
|
521
|
-
"\"", "\\", "
|
|
515
|
+
"\"", "\\", "/", "\b", "\f", "\n", "\r", "\t",
|
|
522
516
|
]
|
|
523
517
|
|
|
524
518
|
if !skipContext
|
|
525
519
|
@context.read(@reader)
|
|
526
520
|
end
|
|
527
521
|
read_json_syntax_char(@@kJSONStringDelimiter)
|
|
528
|
-
str =
|
|
529
|
-
while
|
|
522
|
+
str = Bytes.empty_byte_buffer
|
|
523
|
+
while true
|
|
530
524
|
ch = @reader.read
|
|
531
525
|
if (ch == @@kJSONStringDelimiter)
|
|
532
526
|
break
|
|
533
527
|
end
|
|
534
528
|
if (ch == @@kJSONBackslash)
|
|
535
529
|
ch = @reader.read
|
|
536
|
-
if (ch ==
|
|
530
|
+
if (ch == "u")
|
|
537
531
|
ch = read_json_escape_char
|
|
538
532
|
else
|
|
539
533
|
pos = escape_chars.index(ch);
|
|
540
|
-
if
|
|
541
|
-
raise ProtocolException.new(ProtocolException::INVALID_DATA, "Expected control char, got
|
|
534
|
+
if pos.nil? # not found
|
|
535
|
+
raise ProtocolException.new(ProtocolException::INVALID_DATA, "Expected control char, got '#{ch}'.")
|
|
542
536
|
end
|
|
543
537
|
ch = escape_char_vals[pos]
|
|
544
538
|
end
|
|
545
539
|
end
|
|
546
|
-
str << ch
|
|
540
|
+
str << Bytes.force_binary_encoding(ch)
|
|
541
|
+
check_string_size(str.bytesize)
|
|
547
542
|
end
|
|
548
|
-
|
|
543
|
+
decode_json_string(str)
|
|
549
544
|
end
|
|
550
545
|
|
|
551
546
|
# Reads a block of base64 characters, decoding it, and returns via str
|
|
@@ -555,32 +550,37 @@ module Thrift
|
|
|
555
550
|
if m != 0
|
|
556
551
|
# Add missing padding
|
|
557
552
|
(4 - m).times do
|
|
558
|
-
str +=
|
|
553
|
+
str += "="
|
|
559
554
|
end
|
|
560
555
|
end
|
|
561
|
-
|
|
556
|
+
begin
|
|
557
|
+
str.unpack1("m0")
|
|
558
|
+
rescue ArgumentError
|
|
559
|
+
raise ProtocolException.new(ProtocolException::INVALID_DATA, "Invalid Base64 data")
|
|
560
|
+
end
|
|
562
561
|
end
|
|
563
562
|
|
|
564
563
|
# Reads a sequence of characters, stopping at the first one that is not
|
|
565
564
|
# a valid JSON numeric character.
|
|
566
565
|
def read_json_numeric_chars
|
|
567
566
|
str = String.new(encoding: Encoding::UTF_8)
|
|
568
|
-
while
|
|
567
|
+
while true
|
|
569
568
|
ch = @reader.peek
|
|
570
|
-
if
|
|
569
|
+
if !is_json_numeric(ch)
|
|
571
570
|
break;
|
|
572
571
|
end
|
|
573
572
|
ch = @reader.read
|
|
574
573
|
str << ch
|
|
574
|
+
check_string_size(str.bytesize)
|
|
575
575
|
end
|
|
576
|
-
|
|
576
|
+
str
|
|
577
577
|
end
|
|
578
578
|
|
|
579
579
|
# Reads a sequence of characters and assembles them into a number,
|
|
580
580
|
# returning them via num
|
|
581
581
|
def read_json_integer
|
|
582
582
|
@context.read(@reader)
|
|
583
|
-
if
|
|
583
|
+
if @context.escapeNum
|
|
584
584
|
read_json_syntax_char(@@kJSONStringDelimiter)
|
|
585
585
|
end
|
|
586
586
|
str = read_json_numeric_chars
|
|
@@ -591,11 +591,11 @@ module Thrift
|
|
|
591
591
|
raise ProtocolException.new(ProtocolException::INVALID_DATA, "Expected numeric value; got \"#{str}\"")
|
|
592
592
|
end
|
|
593
593
|
|
|
594
|
-
if
|
|
594
|
+
if @context.escapeNum
|
|
595
595
|
read_json_syntax_char(@@kJSONStringDelimiter)
|
|
596
596
|
end
|
|
597
597
|
|
|
598
|
-
|
|
598
|
+
num
|
|
599
599
|
end
|
|
600
600
|
|
|
601
601
|
# Reads a JSON number or string and interprets it as a double.
|
|
@@ -606,13 +606,13 @@ module Thrift
|
|
|
606
606
|
str = read_json_string(true)
|
|
607
607
|
# Check for NaN, Infinity and -Infinity
|
|
608
608
|
if (str == @@kThriftNan)
|
|
609
|
-
num = (+1.0/0.0)/(+1.0/0.0)
|
|
609
|
+
num = (+1.0 / 0.0) / (+1.0 / 0.0)
|
|
610
610
|
elsif (str == @@kThriftInfinity)
|
|
611
|
-
num = +1.0/0.0
|
|
611
|
+
num = +1.0 / 0.0
|
|
612
612
|
elsif (str == @@kThriftNegativeInfinity)
|
|
613
|
-
num = -1.0/0.0
|
|
613
|
+
num = -1.0 / 0.0
|
|
614
614
|
else
|
|
615
|
-
if
|
|
615
|
+
if !@context.escapeNum
|
|
616
616
|
# Raise exception -- we should not be in a string in this case
|
|
617
617
|
raise ProtocolException.new(ProtocolException::INVALID_DATA, "Numeric data unexpectedly quoted")
|
|
618
618
|
end
|
|
@@ -623,7 +623,7 @@ module Thrift
|
|
|
623
623
|
end
|
|
624
624
|
end
|
|
625
625
|
else
|
|
626
|
-
if
|
|
626
|
+
if @context.escapeNum
|
|
627
627
|
# This will throw - we should have had a quote if escapeNum == true
|
|
628
628
|
read_json_syntax_char(@@kJSONStringDelimiter)
|
|
629
629
|
end
|
|
@@ -634,7 +634,7 @@ module Thrift
|
|
|
634
634
|
raise ProtocolException.new(ProtocolException::INVALID_DATA, "Expected numeric value; got \"#{str}\"")
|
|
635
635
|
end
|
|
636
636
|
end
|
|
637
|
-
|
|
637
|
+
num
|
|
638
638
|
end
|
|
639
639
|
|
|
640
640
|
def read_json_object_start
|
|
@@ -667,7 +667,7 @@ module Thrift
|
|
|
667
667
|
read_json_array_start
|
|
668
668
|
version = read_json_integer
|
|
669
669
|
if (version != @@kThriftVersion1)
|
|
670
|
-
raise ProtocolException.new(ProtocolException::BAD_VERSION,
|
|
670
|
+
raise ProtocolException.new(ProtocolException::BAD_VERSION, "Message contained bad version.")
|
|
671
671
|
end
|
|
672
672
|
name = read_json_string
|
|
673
673
|
message_type = read_json_integer
|
|
@@ -779,21 +779,63 @@ module Thrift
|
|
|
779
779
|
read_json_base64
|
|
780
780
|
end
|
|
781
781
|
|
|
782
|
+
def skip_string
|
|
783
|
+
read_string
|
|
784
|
+
end
|
|
785
|
+
|
|
782
786
|
def read_uuid
|
|
783
787
|
uuid = read_json_string
|
|
784
|
-
raise EOFError.new if uuid.length < 36
|
|
785
788
|
UUID.validate_uuid!(uuid)
|
|
786
789
|
uuid.tap(&:downcase!)
|
|
787
790
|
end
|
|
788
791
|
|
|
789
792
|
def to_s
|
|
790
|
-
"json(#{super
|
|
793
|
+
"json(#{super})"
|
|
794
|
+
end
|
|
795
|
+
|
|
796
|
+
private
|
|
797
|
+
|
|
798
|
+
def normalize_json_string(str)
|
|
799
|
+
utf8 = if str.encoding == Encoding::UTF_8
|
|
800
|
+
str
|
|
801
|
+
elsif str.encoding == Encoding::BINARY
|
|
802
|
+
str.ascii_only? ? str : str.dup.force_encoding(Encoding::UTF_8)
|
|
803
|
+
else
|
|
804
|
+
str.encode(Encoding::UTF_8)
|
|
805
|
+
end
|
|
806
|
+
invalid_unicode!("Invalid UTF-8 string") unless utf8.valid_encoding?
|
|
807
|
+
utf8
|
|
808
|
+
rescue EncodingError
|
|
809
|
+
invalid_unicode!("Invalid UTF-8 string")
|
|
810
|
+
end
|
|
811
|
+
|
|
812
|
+
def decode_json_string(bytes)
|
|
813
|
+
bytes.force_encoding(Encoding::UTF_8)
|
|
814
|
+
invalid_unicode!("Invalid UTF-8 string") unless bytes.valid_encoding?
|
|
815
|
+
bytes
|
|
816
|
+
end
|
|
817
|
+
|
|
818
|
+
def read_unicode_code_unit
|
|
819
|
+
hex = Bytes.empty_byte_buffer
|
|
820
|
+
4.times { hex << @reader.read }
|
|
821
|
+
invalid_unicode!("Invalid Unicode escape") unless hex.match?(/\A[0-9a-fA-F]{4}\z/)
|
|
822
|
+
hex.to_i(16)
|
|
823
|
+
rescue EOFError
|
|
824
|
+
invalid_unicode!("Incomplete Unicode escape")
|
|
825
|
+
end
|
|
826
|
+
|
|
827
|
+
def invalid_unicode!(message)
|
|
828
|
+
raise ProtocolException.new(ProtocolException::INVALID_DATA, message)
|
|
791
829
|
end
|
|
792
830
|
end
|
|
793
831
|
|
|
794
832
|
class JsonProtocolFactory < BaseProtocolFactory
|
|
833
|
+
def initialize(max_string_size: BaseProtocol::DEFAULT_MAX_STRING_SIZE)
|
|
834
|
+
@max_string_size = max_string_size
|
|
835
|
+
end
|
|
836
|
+
|
|
795
837
|
def get_protocol(trans)
|
|
796
|
-
|
|
838
|
+
Thrift::JsonProtocol.new(trans, max_string_size: @max_string_size)
|
|
797
839
|
end
|
|
798
840
|
|
|
799
841
|
def to_s
|
|
@@ -17,11 +17,10 @@
|
|
|
17
17
|
# specific language governing permissions and limitations
|
|
18
18
|
# under the License.
|
|
19
19
|
|
|
20
|
-
require
|
|
20
|
+
require "thrift/protocol/protocol_decorator"
|
|
21
21
|
|
|
22
22
|
module Thrift
|
|
23
23
|
class MultiplexedProtocol < BaseProtocol
|
|
24
|
-
|
|
25
24
|
include ProtocolDecorator
|
|
26
25
|
|
|
27
26
|
def initialize(protocol, service_name)
|
|
@@ -39,7 +38,7 @@ module Thrift
|
|
|
39
38
|
end
|
|
40
39
|
|
|
41
40
|
def to_s
|
|
42
|
-
"multiplexed(#{@
|
|
41
|
+
"multiplexed(#{@protocol})"
|
|
43
42
|
end
|
|
44
43
|
end
|
|
45
44
|
end
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
|
|
20
20
|
module Thrift
|
|
21
21
|
module ProtocolDecorator
|
|
22
|
-
|
|
23
22
|
def initialize(protocol)
|
|
24
23
|
@protocol = protocol
|
|
25
24
|
end
|
|
@@ -29,7 +28,7 @@ module Thrift
|
|
|
29
28
|
end
|
|
30
29
|
|
|
31
30
|
def write_message_begin(name, type, seqid)
|
|
32
|
-
@protocol.write_message_begin
|
|
31
|
+
@protocol.write_message_begin(name, type, seqid)
|
|
33
32
|
end
|
|
34
33
|
|
|
35
34
|
def write_message_end
|
|
@@ -196,6 +195,10 @@ module Thrift
|
|
|
196
195
|
@protocol.read_binary
|
|
197
196
|
end
|
|
198
197
|
|
|
198
|
+
def skip_string
|
|
199
|
+
@protocol.skip_string
|
|
200
|
+
end
|
|
201
|
+
|
|
199
202
|
def read_uuid
|
|
200
203
|
@protocol.read_uuid
|
|
201
204
|
end
|
|
@@ -21,14 +21,20 @@
|
|
|
21
21
|
module Thrift
|
|
22
22
|
class Serializer
|
|
23
23
|
def initialize(protocol_factory = BinaryProtocolFactory.new)
|
|
24
|
+
@protocol_factory = protocol_factory
|
|
24
25
|
@transport = MemoryBufferTransport.new
|
|
25
26
|
@protocol = protocol_factory.get_protocol(@transport)
|
|
26
27
|
end
|
|
27
28
|
|
|
28
29
|
def serialize(base)
|
|
29
30
|
@transport.reset_buffer
|
|
31
|
+
@protocol ||= @protocol_factory.get_protocol(@transport)
|
|
30
32
|
base.write(@protocol)
|
|
33
|
+
@protocol.trans.flush
|
|
31
34
|
@transport.read(@transport.available)
|
|
35
|
+
rescue
|
|
36
|
+
@protocol = nil
|
|
37
|
+
raise
|
|
32
38
|
end
|
|
33
39
|
end
|
|
34
40
|
end
|
|
@@ -18,13 +18,21 @@
|
|
|
18
18
|
# under the License.
|
|
19
19
|
#
|
|
20
20
|
|
|
21
|
+
require "logger"
|
|
22
|
+
|
|
21
23
|
module Thrift
|
|
22
24
|
class BaseServer
|
|
23
|
-
def initialize(processor, server_transport, transport_factory = nil, protocol_factory = nil)
|
|
25
|
+
def initialize(processor, server_transport, transport_factory = nil, protocol_factory = nil, logger: nil)
|
|
24
26
|
@processor = processor
|
|
25
27
|
@server_transport = server_transport
|
|
26
28
|
@transport_factory = transport_factory ? transport_factory : Thrift::BaseTransportFactory.new
|
|
27
29
|
@protocol_factory = protocol_factory ? protocol_factory : Thrift::BinaryProtocolFactory.new
|
|
30
|
+
if logger.nil?
|
|
31
|
+
@logger = Logger.new(STDERR)
|
|
32
|
+
@logger.level = Logger::WARN
|
|
33
|
+
else
|
|
34
|
+
@logger = logger
|
|
35
|
+
end
|
|
28
36
|
end
|
|
29
37
|
|
|
30
38
|
def serve
|
|
@@ -32,7 +40,7 @@ module Thrift
|
|
|
32
40
|
end
|
|
33
41
|
|
|
34
42
|
def to_s
|
|
35
|
-
"server(#{@protocol_factory
|
|
43
|
+
"server(#{@protocol_factory}(#{@transport_factory}(#{@server_transport})))"
|
|
36
44
|
end
|
|
37
45
|
end
|
|
38
46
|
end
|