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.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +235 -17
  3. data/benchmark/benchmark.rb +23 -8
  4. data/benchmark/client.rb +50 -6
  5. data/benchmark/server.rb +46 -7
  6. data/benchmark/thin_server.rb +2 -0
  7. data/ext/binary_protocol_accelerated.c +154 -42
  8. data/ext/bytes.c +14 -0
  9. data/ext/compact_protocol.c +138 -45
  10. data/ext/constants.h +12 -0
  11. data/ext/extconf.rb +17 -8
  12. data/ext/memory_buffer.c +44 -7
  13. data/ext/protocol.c +29 -0
  14. data/ext/protocol.h +35 -0
  15. data/ext/struct.c +48 -17
  16. data/ext/thrift_native.c +28 -3
  17. data/lib/thrift/bytes.rb +70 -100
  18. data/lib/thrift/client.rb +54 -13
  19. data/lib/thrift/exceptions.rb +6 -5
  20. data/lib/thrift/multiplexed_processor.rb +20 -10
  21. data/lib/thrift/processor.rb +7 -6
  22. data/lib/thrift/protocol/base_protocol.rb +52 -21
  23. data/lib/thrift/protocol/binary_protocol.rb +65 -20
  24. data/lib/thrift/protocol/binary_protocol_accelerated.rb +6 -5
  25. data/lib/thrift/protocol/compact_protocol.rb +76 -41
  26. data/lib/thrift/protocol/header_protocol.rb +321 -0
  27. data/lib/thrift/protocol/json_protocol.rb +44 -27
  28. data/lib/thrift/protocol/multiplexed_protocol.rb +6 -5
  29. data/lib/thrift/protocol/protocol_decorator.rb +13 -4
  30. data/lib/thrift/serializer/deserializer.rb +6 -5
  31. data/lib/thrift/serializer/serializer.rb +5 -5
  32. data/lib/thrift/server/base_server.rb +5 -4
  33. data/lib/thrift/server/mongrel_http_server.rb +7 -6
  34. data/lib/thrift/server/nonblocking_server.rb +35 -9
  35. data/lib/thrift/server/simple_server.rb +13 -5
  36. data/lib/thrift/server/thin_http_server.rb +4 -3
  37. data/lib/thrift/server/thread_pool_server.rb +7 -6
  38. data/lib/thrift/server/threaded_server.rb +13 -5
  39. data/lib/thrift/struct.rb +12 -11
  40. data/lib/thrift/struct_union.rb +14 -9
  41. data/lib/thrift/thrift_native.rb +3 -2
  42. data/lib/thrift/transport/base_server_transport.rb +8 -5
  43. data/lib/thrift/transport/base_transport.rb +18 -14
  44. data/lib/thrift/transport/buffered_transport.rb +7 -6
  45. data/lib/thrift/transport/framed_transport.rb +8 -7
  46. data/lib/thrift/transport/header_transport.rb +562 -0
  47. data/lib/thrift/transport/http_client_transport.rb +2 -1
  48. data/lib/thrift/transport/io_stream_transport.rb +4 -3
  49. data/lib/thrift/transport/memory_buffer_transport.rb +13 -6
  50. data/lib/thrift/transport/server_socket.rb +14 -8
  51. data/lib/thrift/transport/socket.rb +126 -60
  52. data/lib/thrift/transport/ssl_server_socket.rb +4 -3
  53. data/lib/thrift/transport/ssl_socket.rb +45 -13
  54. data/lib/thrift/transport/unix_server_socket.rb +9 -5
  55. data/lib/thrift/transport/unix_socket.rb +7 -6
  56. data/lib/thrift/types.rb +10 -6
  57. data/lib/thrift/union.rb +15 -8
  58. data/lib/thrift/uuid.rb +50 -0
  59. data/lib/thrift.rb +4 -1
  60. data/spec/ThriftSpec.thrift +21 -1
  61. data/spec/base_protocol_spec.rb +21 -2
  62. data/spec/base_transport_spec.rb +48 -8
  63. data/spec/binary_protocol_accelerated_spec.rb +1 -0
  64. data/spec/binary_protocol_spec.rb +1 -2
  65. data/spec/binary_protocol_spec_shared.rb +206 -155
  66. data/spec/bytes_spec.rb +71 -114
  67. data/spec/client_spec.rb +86 -19
  68. data/spec/compact_protocol_spec.rb +153 -16
  69. data/spec/constants_demo_spec.rb +102 -0
  70. data/spec/exception_spec.rb +1 -1
  71. data/spec/flat_spec.rb +1 -0
  72. data/spec/header_protocol_spec.rb +476 -0
  73. data/spec/header_transport_spec.rb +431 -0
  74. data/spec/http_client_spec.rb +5 -6
  75. data/spec/json_protocol_spec.rb +69 -47
  76. data/spec/multiplexed_processor_spec.rb +75 -0
  77. data/spec/namespaced_spec.rb +1 -1
  78. data/spec/nonblocking_server_spec.rb +174 -8
  79. data/spec/processor_spec.rb +1 -1
  80. data/spec/recursion_depth_spec.rb +223 -0
  81. data/spec/serializer_spec.rb +1 -1
  82. data/spec/server_socket_spec.rb +38 -1
  83. data/spec/server_spec.rb +60 -9
  84. data/spec/socket_spec.rb +119 -13
  85. data/spec/socket_spec_shared.rb +73 -9
  86. data/spec/spec_helper.rb +2 -1
  87. data/spec/ssl_server_socket_spec.rb +52 -1
  88. data/spec/ssl_socket_spec.rb +181 -11
  89. data/spec/struct_nested_containers_spec.rb +2 -2
  90. data/spec/struct_spec.rb +114 -9
  91. data/spec/support/header_protocol_helper.rb +55 -0
  92. data/spec/thin_http_server_spec.rb +4 -18
  93. data/spec/types_spec.rb +26 -26
  94. data/spec/union_spec.rb +70 -11
  95. data/spec/unix_socket_spec.rb +17 -2
  96. data/spec/uuid_validation_spec.rb +239 -0
  97. data/test/fuzz/Makefile +779 -0
  98. data/test/fuzz/Makefile.am +173 -0
  99. data/test/fuzz/Makefile.in +775 -0
  100. data/test/fuzz/README.md +149 -0
  101. data/test/fuzz/fuzz_common.rb +96 -0
  102. data/{lib/thrift/core_ext.rb → test/fuzz/fuzz_parse_binary_protocol.rb} +4 -4
  103. data/{lib/thrift/core_ext/fixnum.rb → test/fuzz/fuzz_parse_binary_protocol_accelerated.rb} +7 -13
  104. data/test/fuzz/fuzz_parse_binary_protocol_accelerated_harness.rb +23 -0
  105. data/test/fuzz/fuzz_parse_binary_protocol_harness.rb +23 -0
  106. data/test/fuzz/fuzz_parse_compact_protocol.rb +23 -0
  107. data/test/fuzz/fuzz_parse_compact_protocol_harness.rb +23 -0
  108. data/test/fuzz/fuzz_parse_json_protocol.rb +23 -0
  109. data/test/fuzz/fuzz_parse_json_protocol_harness.rb +23 -0
  110. data/test/fuzz/fuzz_roundtrip_binary_protocol.rb +23 -0
  111. data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated.rb +23 -0
  112. data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated_harness.rb +23 -0
  113. data/test/fuzz/fuzz_roundtrip_binary_protocol_harness.rb +23 -0
  114. data/test/fuzz/fuzz_roundtrip_compact_protocol.rb +23 -0
  115. data/test/fuzz/fuzz_roundtrip_compact_protocol_harness.rb +23 -0
  116. data/test/fuzz/fuzz_roundtrip_json_protocol.rb +23 -0
  117. data/test/fuzz/fuzz_roundtrip_json_protocol_harness.rb +23 -0
  118. data/test/fuzz/fuzz_tracer.rb +29 -0
  119. metadata +105 -70
data/lib/thrift/struct.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,33 +7,33 @@
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 'set'
21
22
 
22
23
  module Thrift
23
24
  module Struct
24
- def initialize(d={}, &block)
25
+ def initialize(d = {}, &block)
25
26
  # get a copy of the default values to work on, removing defaults in favor of arguments
26
27
  fields_with_defaults = fields_with_default_values.dup
27
-
28
- # check if the defaults is empty, or if there are no parameters for this
28
+
29
+ # check if the defaults is empty, or if there are no parameters for this
29
30
  # instantiation, and if so, don't bother overriding defaults.
30
31
  unless fields_with_defaults.empty? || d.empty?
31
32
  d.each_key do |name|
32
33
  fields_with_defaults.delete(name.to_s)
33
34
  end
34
35
  end
35
-
36
+
36
37
  # assign all the user-specified arguments
37
38
  unless d.empty?
38
39
  d.each do |name, value|
@@ -43,14 +44,14 @@ module Thrift
43
44
  instance_variable_set("@#{name}", value)
44
45
  end
45
46
  end
46
-
47
+
47
48
  # assign all the default values
48
49
  unless fields_with_defaults.empty?
49
50
  fields_with_defaults.each do |name, default_value|
50
51
  instance_variable_set("@#{name}", (default_value.dup rescue default_value))
51
52
  end
52
53
  end
53
-
54
+
54
55
  yield self if block_given?
55
56
  end
56
57
 
@@ -67,7 +68,7 @@ module Thrift
67
68
  end
68
69
  fields_with_default_values
69
70
  end
70
-
71
+
71
72
  def inspect(skip_optional_nulls = true)
72
73
  fields = []
73
74
  each_field do |fid, field_info|
@@ -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
@@ -55,6 +56,7 @@ module Thrift
55
56
  value.read(iprot)
56
57
  when Types::MAP
57
58
  key_type, val_type, size = iprot.read_map_begin
59
+ raise ProtocolException.new(ProtocolException::NEGATIVE_SIZE, 'Negative size') unless size >= 0
58
60
  # Skip the map contents if the declared key or value types don't match the expected ones.
59
61
  if (size != 0 && (key_type != field[:key][:type] || val_type != field[:value][:type]))
60
62
  size.times do
@@ -73,6 +75,7 @@ module Thrift
73
75
  iprot.read_map_end
74
76
  when Types::LIST
75
77
  e_type, size = iprot.read_list_begin
78
+ raise ProtocolException.new(ProtocolException::NEGATIVE_SIZE, 'Negative size') unless size >= 0
76
79
  # Skip the list contents if the declared element type doesn't match the expected one.
77
80
  if (e_type != field[:element][:type])
78
81
  size.times do
@@ -80,13 +83,15 @@ module Thrift
80
83
  end
81
84
  value = nil
82
85
  else
83
- value = Array.new(size) do |n|
84
- read_field(iprot, field_info(field[:element]))
86
+ value = []
87
+ size.times do
88
+ value << read_field(iprot, field_info(field[:element]))
85
89
  end
86
90
  end
87
91
  iprot.read_list_end
88
92
  when Types::SET
89
93
  e_type, size = iprot.read_set_begin
94
+ raise ProtocolException.new(ProtocolException::NEGATIVE_SIZE, 'Negative size') unless size >= 0
90
95
  # Skip the set contents if the declared element type doesn't match the expected one.
91
96
  if (e_type != field[:element][:type])
92
97
  size.times do
@@ -159,7 +164,7 @@ module Thrift
159
164
  def inspect_field(value, field_info)
160
165
  if enum_class = field_info[:enum_class]
161
166
  "#{enum_class.const_get(:VALUE_MAP)[value]} (#{value})"
162
- elsif value.is_a? Hash
167
+ elsif value.is_a? Hash
163
168
  if field_info[:type] == Types::MAP
164
169
  map_buf = []
165
170
  value.each do |k, v|
@@ -180,13 +185,13 @@ module Thrift
180
185
  value.inspect
181
186
  end
182
187
  end
183
-
188
+
184
189
  def inspect_collection(collection, field_info)
185
190
  buf = []
186
191
  collection.each do |k|
187
192
  buf << inspect_field(k, field_info[:element])
188
193
  end
189
- "[" + buf.join(", ") + "]"
194
+ "[" + buf.join(", ") + "]"
190
195
  end
191
196
  end
192
- end
197
+ end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  #
2
3
  # Licensed to the Apache Software Foundation (ASF) under one
3
4
  # or more contributor license agreements. See the NOTICE file
@@ -20,5 +21,5 @@
20
21
  begin
21
22
  require "thrift_native"
22
23
  rescue LoadError
23
- puts "Unable to load thrift_native extension. Defaulting to pure Ruby libraries."
24
- end
24
+ warn "Unable to load thrift_native extension. Defaulting to pure Ruby libraries."
25
+ end
@@ -1,5 +1,6 @@
1
1
  # encoding: ascii-8bit
2
- #
2
+ # frozen_string_literal: true
3
+ #
3
4
  # Licensed to the Apache Software Foundation (ASF) under one
4
5
  # or more contributor license agreements. See the NOTICE file
5
6
  # distributed with this work for additional information
@@ -7,19 +8,21 @@
7
8
  # to you under the Apache License, Version 2.0 (the
8
9
  # "License"); you may not use this file except in compliance
9
10
  # with the License. You may obtain a copy of the License at
10
- #
11
+ #
11
12
  # http://www.apache.org/licenses/LICENSE-2.0
12
- #
13
+ #
13
14
  # Unless required by applicable law or agreed to in writing,
14
15
  # software distributed under the License is distributed on an
15
16
  # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
17
  # KIND, either express or implied. See the License for the
17
18
  # specific language governing permissions and limitations
18
19
  # under the License.
19
- #
20
+ #
20
21
 
21
22
  module Thrift
22
23
  class BaseServerTransport
24
+ DEFAULT_CLIENT_TIMEOUT = 5
25
+
23
26
  def listen
24
27
  raise NotImplementedError
25
28
  end
@@ -27,7 +30,7 @@ module Thrift
27
30
  def accept
28
31
  raise NotImplementedError
29
32
  end
30
-
33
+
31
34
  def close; nil; end
32
35
 
33
36
  def closed?
@@ -1,5 +1,6 @@
1
1
  # encoding: ascii-8bit
2
- #
2
+ # frozen_string_literal: true
3
+ #
3
4
  # Licensed to the Apache Software Foundation (ASF) under one
4
5
  # or more contributor license agreements. See the NOTICE file
5
6
  # distributed with this work for additional information
@@ -7,16 +8,16 @@
7
8
  # to you under the Apache License, Version 2.0 (the
8
9
  # "License"); you may not use this file except in compliance
9
10
  # with the License. You may obtain a copy of the License at
10
- #
11
+ #
11
12
  # http://www.apache.org/licenses/LICENSE-2.0
12
- #
13
+ #
13
14
  # Unless required by applicable law or agreed to in writing,
14
15
  # software distributed under the License is distributed on an
15
16
  # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
17
  # KIND, either express or implied. See the License for the
17
18
  # specific language governing permissions and limitations
18
19
  # under the License.
19
- #
20
+ #
20
21
 
21
22
  module Thrift
22
23
  class TransportException < Exception
@@ -25,10 +26,12 @@ module Thrift
25
26
  ALREADY_OPEN = 2
26
27
  TIMED_OUT = 3
27
28
  END_OF_FILE = 4
29
+ NEGATIVE_SIZE = 5
30
+ SIZE_LIMIT = 6
28
31
 
29
32
  attr_reader :type
30
33
 
31
- def initialize(type=UNKNOWN, message=nil)
34
+ def initialize(type = UNKNOWN, message = nil)
32
35
  super(message)
33
36
  @type = type
34
37
  end
@@ -48,12 +51,12 @@ module Thrift
48
51
 
49
52
  class BaseTransport
50
53
  def open?; end
51
-
54
+
52
55
  def open; end
53
56
 
54
57
  def close; end
55
58
 
56
- # Reads a number of bytes from the transports. In Ruby 1.9+, the String returned will have a BINARY (aka ASCII8BIT) encoding.
59
+ # Reads a number of bytes from the transports. The String returned will have a BINARY (aka ASCII-8BIT) encoding.
57
60
  #
58
61
  # sz - The number of bytes to read from the transport.
59
62
  #
@@ -62,7 +65,7 @@ module Thrift
62
65
  raise NotImplementedError
63
66
  end
64
67
 
65
- # Returns an unsigned byte as a Fixnum in the range (0..255).
68
+ # Returns an unsigned byte as a Integer in the range (0..255).
66
69
  def read_byte
67
70
  buf = read_all(1)
68
71
  return Bytes.get_string_byte(buf, 0)
@@ -80,17 +83,18 @@ module Thrift
80
83
  end
81
84
 
82
85
  def read_all(size)
83
- return Bytes.empty_byte_buffer if size <= 0
84
- buf = read(size)
86
+ raise TransportException.new(TransportException::NEGATIVE_SIZE, 'Negative size') unless size >= 0
87
+ return Bytes.empty_byte_buffer if size == 0
88
+ buf = Bytes.force_binary_encoding(read(size))
85
89
  while (buf.length < size)
86
90
  chunk = read(size - buf.length)
87
91
  buf << chunk
88
92
  end
89
-
93
+
90
94
  buf
91
95
  end
92
96
 
93
- # Writes the byte buffer to the transport. In Ruby 1.9+, the buffer will be forced into BINARY encoding.
97
+ # Writes the byte buffer to the transport. The buffer will be forced into BINARY encoding.
94
98
  #
95
99
  # buf - A String acting as a byte buffer.
96
100
  #
@@ -104,12 +108,12 @@ module Thrift
104
108
  "base"
105
109
  end
106
110
  end
107
-
111
+
108
112
  class BaseTransportFactory
109
113
  def get_transport(trans)
110
114
  return trans
111
115
  end
112
-
116
+
113
117
  def to_s
114
118
  "base"
115
119
  end
@@ -1,5 +1,6 @@
1
1
  # encoding: ascii-8bit
2
- #
2
+ # frozen_string_literal: true
3
+ #
3
4
  # Licensed to the Apache Software Foundation (ASF) under one
4
5
  # or more contributor license agreements. See the NOTICE file
5
6
  # distributed with this work for additional information
@@ -7,9 +8,9 @@
7
8
  # to you under the Apache License, Version 2.0 (the
8
9
  # "License"); you may not use this file except in compliance
9
10
  # with the License. You may obtain a copy of the License at
10
- #
11
+ #
11
12
  # http://www.apache.org/licenses/LICENSE-2.0
12
- #
13
+ #
13
14
  # Unless required by applicable law or agreed to in writing,
14
15
  # software distributed under the License is distributed on an
15
16
  # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -21,7 +22,7 @@
21
22
  module Thrift
22
23
  class BufferedTransport < BaseTransport
23
24
  DEFAULT_BUFFER = 4096
24
-
25
+
25
26
  def initialize(transport)
26
27
  @transport = transport
27
28
  @wbuf = Bytes.empty_byte_buffer
@@ -101,7 +102,7 @@ module Thrift
101
102
  @transport.write(@wbuf)
102
103
  @wbuf = Bytes.empty_byte_buffer
103
104
  end
104
-
105
+
105
106
  @transport.flush
106
107
  end
107
108
 
@@ -114,7 +115,7 @@ module Thrift
114
115
  def get_transport(transport)
115
116
  return BufferedTransport.new(transport)
116
117
  end
117
-
118
+
118
119
  def to_s
119
120
  "buffered"
120
121
  end
@@ -1,5 +1,6 @@
1
1
  # encoding: ascii-8bit
2
- #
2
+ # frozen_string_literal: true
3
+ #
3
4
  # Licensed to the Apache Software Foundation (ASF) under one
4
5
  # or more contributor license agreements. See the NOTICE file
5
6
  # distributed with this work for additional information
@@ -7,9 +8,9 @@
7
8
  # to you under the Apache License, Version 2.0 (the
8
9
  # "License"); you may not use this file except in compliance
9
10
  # with the License. You may obtain a copy of the License at
10
- #
11
+ #
11
12
  # http://www.apache.org/licenses/LICENSE-2.0
12
- #
13
+ #
13
14
  # Unless required by applicable law or agreed to in writing,
14
15
  # software distributed under the License is distributed on an
15
16
  # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -20,13 +21,13 @@
20
21
 
21
22
  module Thrift
22
23
  class FramedTransport < BaseTransport
23
- def initialize(transport, read=true, write=true)
24
+ def initialize(transport, read = true, write = true)
24
25
  @transport = transport
25
26
  @rbuf = Bytes.empty_byte_buffer
26
27
  @wbuf = Bytes.empty_byte_buffer
27
28
  @read = read
28
29
  @write = write
29
- @index = 0
30
+ @index = 0
30
31
  end
31
32
 
32
33
  def open?
@@ -77,7 +78,7 @@ module Thrift
77
78
  i
78
79
  end
79
80
 
80
- def write(buf, sz=nil)
81
+ def write(buf, sz = nil)
81
82
  return @transport.write(buf) unless @write
82
83
 
83
84
  buf = Bytes.force_binary_encoding(buf)
@@ -117,7 +118,7 @@ module Thrift
117
118
  def get_transport(transport)
118
119
  return FramedTransport.new(transport)
119
120
  end
120
-
121
+
121
122
  def to_s
122
123
  "framed"
123
124
  end