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
@@ -0,0 +1,431 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Licensed to the Apache Software Foundation (ASF) under one
4
+ # or more contributor license agreements. See the NOTICE file
5
+ # distributed with this work for additional information
6
+ # regarding copyright ownership. The ASF licenses this file
7
+ # to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance
9
+ # with the License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing,
14
+ # software distributed under the License is distributed on an
15
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ # KIND, either express or implied. See the License for the
17
+ # specific language governing permissions and limitations
18
+ # under the License.
19
+ #
20
+
21
+ require 'spec_helper'
22
+ require_relative 'support/header_protocol_helper'
23
+
24
+ describe 'HeaderTransport' do
25
+ include HeaderProtocolHelper
26
+
27
+ describe Thrift::HeaderClientType do
28
+ it "should define client type constants" do
29
+ expect(Thrift::HeaderClientType::HEADERS).to eq(0x00)
30
+ expect(Thrift::HeaderClientType::FRAMED_BINARY).to eq(0x01)
31
+ expect(Thrift::HeaderClientType::UNFRAMED_BINARY).to eq(0x02)
32
+ expect(Thrift::HeaderClientType::FRAMED_COMPACT).to eq(0x03)
33
+ expect(Thrift::HeaderClientType::UNFRAMED_COMPACT).to eq(0x04)
34
+ end
35
+ end
36
+
37
+ describe Thrift::HeaderSubprotocolID do
38
+ it "should define protocol ID constants" do
39
+ expect(Thrift::HeaderSubprotocolID::BINARY).to eq(0x00)
40
+ expect(Thrift::HeaderSubprotocolID::COMPACT).to eq(0x02)
41
+ end
42
+ end
43
+
44
+ describe Thrift::HeaderTransformID do
45
+ it "should define transform ID constants" do
46
+ expect(Thrift::HeaderTransformID::ZLIB).to eq(0x01)
47
+ end
48
+ end
49
+
50
+ describe Thrift::HeaderTransport do
51
+ before(:each) do
52
+ @underlying = Thrift::MemoryBufferTransport.new
53
+ @trans = Thrift::HeaderTransport.new(@underlying)
54
+ end
55
+
56
+ it "should provide a to_s that describes the encapsulation" do
57
+ expect(@trans.to_s).to eq("header(memory)")
58
+ end
59
+
60
+ it "should pass through open?/open/close" do
61
+ mock_transport = double("Transport")
62
+ expect(mock_transport).to receive(:open?).and_return(true)
63
+ expect(mock_transport).to receive(:open).and_return(nil)
64
+ expect(mock_transport).to receive(:close).and_return(nil)
65
+
66
+ trans = Thrift::HeaderTransport.new(mock_transport)
67
+ expect(trans.open?).to be true
68
+ trans.open
69
+ trans.close
70
+ end
71
+
72
+ describe "header management" do
73
+ it "should allow setting and getting headers" do
74
+ @trans.set_header("key1", "value1")
75
+ @trans.set_header("key2", "value2")
76
+ # Headers aren't read until we receive data, so write and read back
77
+ expect(@trans.get_headers).to eq({})
78
+ end
79
+
80
+ it "should clear headers" do
81
+ @trans.set_header("key1", "value1")
82
+ @trans.clear_headers
83
+ # Write and flush to verify headers were cleared
84
+ @trans.write("test")
85
+ @trans.flush
86
+ end
87
+
88
+ it "should add transforms" do
89
+ expect { @trans.add_transform(Thrift::HeaderTransformID::ZLIB) }.not_to raise_error
90
+ end
91
+
92
+ it "should reject unknown transforms" do
93
+ expect { @trans.add_transform(999) }.to raise_error(Thrift::TransportException)
94
+ end
95
+ end
96
+
97
+ describe "write and flush" do
98
+ it "should buffer writes" do
99
+ @trans.write("hello")
100
+ @trans.write(" world")
101
+ expect(@underlying.available).to eq(0)
102
+ end
103
+
104
+ it "should write Header format on flush" do
105
+ @trans.write("test payload")
106
+ @trans.flush
107
+
108
+ # Read back the frame
109
+ data = @underlying.read(@underlying.available)
110
+
111
+ # Should have frame length (4 bytes) + header + payload
112
+ expect(data.bytesize).to be > 16
113
+
114
+ # First 4 bytes are frame length
115
+ frame_size = data[0, 4].unpack('N').first
116
+ expect(frame_size).to eq(data.bytesize - 4)
117
+
118
+ # Next 2 bytes should be header magic
119
+ magic = data[4, 2].unpack('n').first
120
+ expect(magic).to eq(Thrift::HeaderTransport::HEADER_MAGIC)
121
+ end
122
+
123
+ it "should include headers in frame" do
124
+ @trans.set_header("test-key", "test-value")
125
+ @trans.write("payload")
126
+ @trans.flush
127
+
128
+ # Read back and verify it's larger due to headers
129
+ data = @underlying.read(@underlying.available)
130
+ expect(data.bytesize).to be > 30 # Should include header key-value
131
+ end
132
+
133
+ it "should write the configured sequence id into the frame header" do
134
+ @trans.sequence_id = 456
135
+ @trans.write("payload")
136
+ @trans.flush
137
+
138
+ data = @underlying.read(@underlying.available)
139
+ expect(data[8, 4].unpack('N').first).to eq(456)
140
+ end
141
+
142
+ it "should apply ZLIB transform" do
143
+ @trans.add_transform(Thrift::HeaderTransformID::ZLIB)
144
+ original_payload = "a" * 1000 # Compressible data
145
+ @trans.write(original_payload)
146
+ @trans.flush
147
+
148
+ data = @underlying.read(@underlying.available)
149
+ # Compressed frame should be smaller than uncompressed
150
+ expect(data.bytesize).to be < original_payload.bytesize
151
+ end
152
+ end
153
+
154
+ describe "frame size limits" do
155
+ it "should reject payloads larger than max frame size" do
156
+ @trans.set_max_frame_size(4)
157
+ @trans.write("12345")
158
+ expect { @trans.flush }.to raise_error(Thrift::TransportException, /frame that is too large/)
159
+ end
160
+ end
161
+
162
+ describe "decompressed size limits" do
163
+ it "should accept a valid max_decompressed_size" do
164
+ expect { @trans.set_max_decompressed_size(1024) }.not_to raise_error
165
+ expect { @trans.set_max_decompressed_size(Thrift::HeaderTransport::MAX_FRAME_SIZE) }.not_to raise_error
166
+ end
167
+
168
+ it "should reject invalid max_decompressed_size" do
169
+ expect { @trans.set_max_decompressed_size(0) }.to raise_error(ArgumentError)
170
+ expect { @trans.set_max_decompressed_size(-1) }.to raise_error(ArgumentError)
171
+ expect { @trans.set_max_decompressed_size(Thrift::HeaderTransport::MAX_FRAME_SIZE + 1) }.to raise_error(ArgumentError)
172
+ end
173
+
174
+ it "should decompress ZLIB payload within the limit" do
175
+ write_buf = Thrift::MemoryBufferTransport.new
176
+ writer = Thrift::HeaderTransport.new(write_buf)
177
+ writer.add_transform(Thrift::HeaderTransformID::ZLIB)
178
+ writer.write("A" * 1_000)
179
+ writer.flush
180
+
181
+ written_data = write_buf.read(write_buf.available)
182
+ read_trans = Thrift::HeaderTransport.new(Thrift::MemoryBufferTransport.new(written_data))
183
+ read_trans.set_max_decompressed_size(2_000)
184
+
185
+ expect(read_trans.read(1_000)).to eq("A" * 1_000)
186
+ end
187
+
188
+ it "should raise SIZE_LIMIT TransportException when decompressed output exceeds the limit" do
189
+ write_buf = Thrift::MemoryBufferTransport.new
190
+ writer = Thrift::HeaderTransport.new(write_buf)
191
+ writer.add_transform(Thrift::HeaderTransformID::ZLIB)
192
+ writer.write("A" * 10_000)
193
+ writer.flush
194
+
195
+ written_data = write_buf.read(write_buf.available)
196
+ read_trans = Thrift::HeaderTransport.new(Thrift::MemoryBufferTransport.new(written_data))
197
+ read_trans.set_max_decompressed_size(100)
198
+
199
+ expect { read_trans.read(1) }.to raise_error(Thrift::TransportException) do |e|
200
+ expect(e.type).to eq(Thrift::TransportException::SIZE_LIMIT)
201
+ expect(e.message).to match(/limit/)
202
+ end
203
+ end
204
+ end
205
+
206
+ describe "read and frame detection" do
207
+ it "should detect Header format" do
208
+ # Write a Header frame
209
+ @trans.write("test data")
210
+ @trans.flush
211
+
212
+ # Reset for reading
213
+ written_data = @underlying.read(@underlying.available)
214
+ read_transport = Thrift::MemoryBufferTransport.new(written_data)
215
+ read_trans = Thrift::HeaderTransport.new(read_transport)
216
+
217
+ result = read_trans.read(9)
218
+ expect(result).to eq("test data")
219
+ end
220
+
221
+ it "should detect framed binary protocol" do
222
+ # Create a framed binary message
223
+ payload = [Thrift::BinaryProtocol::VERSION_1 | Thrift::MessageTypes::CALL].pack('N')
224
+ payload << "test"
225
+ frame = [payload.bytesize].pack('N') + payload
226
+
227
+ read_transport = Thrift::MemoryBufferTransport.new(frame)
228
+ read_trans = Thrift::HeaderTransport.new(read_transport)
229
+
230
+ result = read_trans.read(payload.bytesize)
231
+ expect(result).to eq(payload)
232
+ end
233
+
234
+ it "should detect unframed binary protocol" do
235
+ # Create an unframed binary message (version word first)
236
+ message = [Thrift::BinaryProtocol::VERSION_1 | Thrift::MessageTypes::CALL].pack('N')
237
+ message << "test"
238
+
239
+ read_transport = Thrift::MemoryBufferTransport.new(message)
240
+ read_trans = Thrift::HeaderTransport.new(read_transport)
241
+
242
+ result = read_trans.read(message.bytesize)
243
+ expect(result).to eq(message)
244
+ end
245
+
246
+ it "should read headers from Header frame" do
247
+ # Write with headers
248
+ @trans.set_header("request-id", "12345")
249
+ @trans.write("payload")
250
+ @trans.flush
251
+
252
+ # Read back
253
+ written_data = @underlying.read(@underlying.available)
254
+ read_transport = Thrift::MemoryBufferTransport.new(written_data)
255
+ read_trans = Thrift::HeaderTransport.new(read_transport)
256
+
257
+ read_trans.read(7)
258
+ headers = read_trans.get_headers
259
+ expect(headers["request-id"]).to eq("12345")
260
+ end
261
+
262
+ it "should decode signed sequence ids from Header frames" do
263
+ @trans.sequence_id = -2147483648
264
+ @trans.write("payload")
265
+ @trans.flush
266
+
267
+ written_data = @underlying.read(@underlying.available)
268
+ read_transport = Thrift::MemoryBufferTransport.new(written_data)
269
+ read_trans = Thrift::HeaderTransport.new(read_transport)
270
+
271
+ expect(read_trans.read(7)).to eq("payload")
272
+ expect(read_trans.sequence_id).to eq(-2147483648)
273
+ end
274
+
275
+ it "should decompress ZLIB payload" do
276
+ # Write with ZLIB
277
+ @trans.add_transform(Thrift::HeaderTransformID::ZLIB)
278
+ original = "hello world this is a test"
279
+ @trans.write(original)
280
+ @trans.flush
281
+
282
+ # Read back
283
+ written_data = @underlying.read(@underlying.available)
284
+ read_transport = Thrift::MemoryBufferTransport.new(written_data)
285
+ read_trans = Thrift::HeaderTransport.new(read_transport)
286
+
287
+ result = read_trans.read(original.bytesize)
288
+ expect(result).to eq(original)
289
+ end
290
+ end
291
+
292
+ describe "header parsing protections" do
293
+ it "should reject unreasonable header sizes" do
294
+ frame = build_header_frame("", Thrift::Bytes.empty_byte_buffer, header_words: 16_384)
295
+ read_transport = Thrift::MemoryBufferTransport.new(frame)
296
+ read_trans = Thrift::HeaderTransport.new(read_transport)
297
+
298
+ expect { read_trans.read(1) }.to raise_error(Thrift::TransportException, /Header size is unreasonable/)
299
+ end
300
+
301
+ it "should reject header frames that are too small" do
302
+ frame = Thrift::Bytes.empty_byte_buffer
303
+ frame << [9].pack('N')
304
+ frame << [Thrift::HeaderTransport::HEADER_MAGIC].pack('n')
305
+ frame << [0].pack('n')
306
+ frame << [0].pack('N')
307
+ frame << [0].pack('n')
308
+ read_transport = Thrift::MemoryBufferTransport.new(frame)
309
+ read_trans = Thrift::HeaderTransport.new(read_transport)
310
+
311
+ expect { read_trans.read(1) }.to raise_error(Thrift::TransportException, /frame is too small/)
312
+ end
313
+
314
+ it "should reject varints that cross header boundary" do
315
+ header_data = [0x80, 0x80, 0x80, 0x80].pack('C*')
316
+ frame = build_header_frame(header_data)
317
+ read_transport = Thrift::MemoryBufferTransport.new(frame)
318
+ read_trans = Thrift::HeaderTransport.new(read_transport)
319
+
320
+ expect { read_trans.read(1) }.to raise_error(Thrift::TransportException, /header boundary/)
321
+ end
322
+
323
+ it "should reject strings that exceed header boundary" do
324
+ header_data = +""
325
+ header_data << varint32(Thrift::HeaderSubprotocolID::BINARY)
326
+ header_data << varint32(0)
327
+ header_data << varint32(Thrift::HeaderInfoType::KEY_VALUE)
328
+ header_data << varint32(1)
329
+ header_data << varint32(10)
330
+ header_data << "a"
331
+
332
+ frame = build_header_frame(header_data)
333
+ read_transport = Thrift::MemoryBufferTransport.new(frame)
334
+ read_trans = Thrift::HeaderTransport.new(read_transport)
335
+
336
+ expect { read_trans.read(1) }.to raise_error(Thrift::TransportException, /Info header length exceeds header size/)
337
+ end
338
+ end
339
+
340
+ describe "round-trip" do
341
+ it "should handle complete write-read cycle" do
342
+ # Write
343
+ @trans.set_header("trace-id", "abc123")
344
+ @trans.write("hello world")
345
+ @trans.flush
346
+
347
+ # Read
348
+ written_data = @underlying.read(@underlying.available)
349
+ read_transport = Thrift::MemoryBufferTransport.new(written_data)
350
+ read_trans = Thrift::HeaderTransport.new(read_transport)
351
+
352
+ result = read_trans.read(11)
353
+ expect(result).to eq("hello world")
354
+ expect(read_trans.get_headers["trace-id"]).to eq("abc123")
355
+ end
356
+
357
+ it "should handle multiple headers" do
358
+ @trans.set_header("header1", "value1")
359
+ @trans.set_header("header2", "value2")
360
+ @trans.set_header("header3", "value3")
361
+ @trans.write("data")
362
+ @trans.flush
363
+
364
+ written_data = @underlying.read(@underlying.available)
365
+ read_transport = Thrift::MemoryBufferTransport.new(written_data)
366
+ read_trans = Thrift::HeaderTransport.new(read_transport)
367
+
368
+ read_trans.read(4)
369
+ headers = read_trans.get_headers
370
+ expect(headers["header1"]).to eq("value1")
371
+ expect(headers["header2"]).to eq("value2")
372
+ expect(headers["header3"]).to eq("value3")
373
+ end
374
+
375
+ it "should handle ZLIB compression round-trip" do
376
+ @trans.add_transform(Thrift::HeaderTransformID::ZLIB)
377
+ @trans.set_header("compressed", "true")
378
+ original = "x" * 500
379
+ @trans.write(original)
380
+ @trans.flush
381
+
382
+ written_data = @underlying.read(@underlying.available)
383
+ read_transport = Thrift::MemoryBufferTransport.new(written_data)
384
+ read_trans = Thrift::HeaderTransport.new(read_transport)
385
+
386
+ result = read_trans.read(500)
387
+ expect(result).to eq(original)
388
+ expect(read_trans.get_headers["compressed"]).to eq("true")
389
+ end
390
+ end
391
+
392
+ describe "client type restrictions" do
393
+ it "should reject disallowed client types" do
394
+ # Only allow HEADERS
395
+ allowed = [Thrift::HeaderClientType::HEADERS]
396
+
397
+ # Create framed binary message
398
+ payload = [Thrift::BinaryProtocol::VERSION_1 | Thrift::MessageTypes::CALL].pack('N')
399
+ frame = [payload.bytesize].pack('N') + payload
400
+
401
+ read_transport = Thrift::MemoryBufferTransport.new(frame)
402
+ read_trans = Thrift::HeaderTransport.new(read_transport, allowed)
403
+
404
+ expect { read_trans.read(4) }.to raise_error(Thrift::TransportException)
405
+ end
406
+ end
407
+ end
408
+
409
+ describe Thrift::HeaderTransportFactory do
410
+ it "should wrap transport in HeaderTransport" do
411
+ mock_transport = double("Transport")
412
+ factory = Thrift::HeaderTransportFactory.new
413
+ result = factory.get_transport(mock_transport)
414
+ expect(result).to be_a(Thrift::HeaderTransport)
415
+ end
416
+
417
+ it "should provide a reasonable to_s" do
418
+ expect(Thrift::HeaderTransportFactory.new.to_s).to eq("header")
419
+ end
420
+
421
+ it "should pass allowed_client_types to transport" do
422
+ allowed = [Thrift::HeaderClientType::HEADERS]
423
+ factory = Thrift::HeaderTransportFactory.new(allowed)
424
+
425
+ mock_transport = Thrift::MemoryBufferTransport.new
426
+ result = factory.get_transport(mock_transport)
427
+
428
+ expect(result).to be_a(Thrift::HeaderTransport)
429
+ end
430
+ end
431
+ 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,12 +21,11 @@
20
21
  require 'spec_helper'
21
22
 
22
23
  describe 'Thrift::HTTPClientTransport' do
23
-
24
24
  describe Thrift::HTTPClientTransport do
25
25
  before(:each) do
26
26
  @client = Thrift::HTTPClientTransport.new("http://my.domain.com/path/to/service?param=value")
27
27
  end
28
-
28
+
29
29
  it "should provide a reasonable to_s" do
30
30
  @client.to_s == "http://my.domain.com/path/to/service?param=value"
31
31
  end
@@ -84,7 +84,7 @@ describe 'Thrift::HTTPClientTransport' do
84
84
  end
85
85
  end
86
86
 
87
- @client.flush rescue
87
+ @client.flush rescue
88
88
  expect(@client.instance_variable_get(:@outbuf)).to eq(Thrift::Bytes.empty_byte_buffer)
89
89
  end
90
90
 
@@ -105,7 +105,6 @@ describe 'Thrift::HTTPClientTransport' do
105
105
 
106
106
  expect { @client.flush }.to raise_error(Thrift::TransportException)
107
107
  end
108
-
109
108
  end
110
109
 
111
110
  describe 'ssl enabled' do
@@ -124,7 +123,7 @@ describe 'Thrift::HTTPClientTransport' do
124
123
  expect(http).to receive(:use_ssl=).with(true)
125
124
  expect(http).to receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
126
125
  expect(http).to receive(:post).with(@service_path, "test",
127
- "Content-Type" => "application/x-thrift") do
126
+ {"Content-Type" => "application/x-thrift"}) do
128
127
  double("Net::HTTPOK").tap do |response|
129
128
  expect(response).to receive(:body).and_return "data"
130
129
  expect(response).to receive(:code).and_return "200"
@@ -146,7 +145,7 @@ describe 'Thrift::HTTPClientTransport' do
146
145
  expect(http).to receive(:use_ssl=).with(true)
147
146
  expect(http).to receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
148
147
  expect(http).to receive(:post).with(@service_path, "test",
149
- "Content-Type" => "application/x-thrift") do
148
+ {"Content-Type" => "application/x-thrift"}) do
150
149
  double("Net::HTTPOK").tap do |response|
151
150
  expect(response).to receive(:body).and_return "data"
152
151
  expect(response).to receive(:code).and_return "200"