thrift 0.9.1 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +6 -14
  2. data/{README → README.md} +0 -0
  3. data/ext/binary_protocol_accelerated.c +12 -12
  4. data/ext/compact_protocol.c +4 -2
  5. data/ext/constants.h +3 -0
  6. data/ext/extconf.rb +3 -1
  7. data/ext/memory_buffer.c +1 -1
  8. data/ext/strlcpy.h +7 -3
  9. data/ext/struct.c +27 -4
  10. data/ext/thrift_native.c +6 -0
  11. data/lib/thrift.rb +8 -5
  12. data/lib/thrift/client.rb +13 -4
  13. data/lib/thrift/multiplexed_processor.rb +76 -0
  14. data/lib/thrift/processor.rb +24 -6
  15. data/lib/thrift/protocol/base_protocol.rb +13 -3
  16. data/lib/thrift/protocol/binary_protocol.rb +8 -1
  17. data/lib/thrift/protocol/binary_protocol_accelerated.rb +8 -0
  18. data/lib/thrift/protocol/compact_protocol.rb +10 -1
  19. data/lib/thrift/protocol/json_protocol.rb +23 -6
  20. data/lib/thrift/protocol/multiplexed_protocol.rb +44 -0
  21. data/lib/thrift/protocol/protocol_decorator.rb +194 -0
  22. data/lib/thrift/server/base_server.rb +8 -2
  23. data/lib/thrift/server/simple_server.rb +5 -1
  24. data/lib/thrift/server/thread_pool_server.rb +5 -1
  25. data/lib/thrift/server/threaded_server.rb +5 -1
  26. data/lib/thrift/transport/base_server_transport.rb +1 -1
  27. data/lib/thrift/transport/base_transport.rb +8 -0
  28. data/lib/thrift/transport/buffered_transport.rb +9 -1
  29. data/lib/thrift/transport/framed_transport.rb +9 -1
  30. data/lib/thrift/transport/http_client_transport.rb +5 -0
  31. data/lib/thrift/transport/io_stream_transport.rb +4 -1
  32. data/lib/thrift/transport/memory_buffer_transport.rb +4 -0
  33. data/lib/thrift/transport/server_socket.rb +6 -1
  34. data/lib/thrift/transport/socket.rb +21 -17
  35. data/lib/thrift/transport/ssl_server_socket.rb +41 -0
  36. data/lib/thrift/transport/ssl_socket.rb +51 -0
  37. data/lib/thrift/transport/unix_server_socket.rb +5 -1
  38. data/lib/thrift/transport/unix_socket.rb +5 -1
  39. data/lib/thrift/union.rb +3 -6
  40. data/spec/BaseService.thrift +27 -0
  41. data/spec/ExtendedService.thrift +25 -0
  42. data/spec/Referenced.thrift +44 -0
  43. data/spec/ThriftNamespacedSpec.thrift +53 -0
  44. data/spec/base_protocol_spec.rb +79 -71
  45. data/spec/base_transport_spec.rb +155 -117
  46. data/spec/binary_protocol_accelerated_spec.rb +6 -2
  47. data/spec/binary_protocol_spec.rb +16 -8
  48. data/spec/binary_protocol_spec_shared.rb +75 -72
  49. data/spec/bytes_spec.rb +38 -38
  50. data/spec/client_spec.rb +41 -42
  51. data/spec/compact_protocol_spec.rb +32 -17
  52. data/spec/exception_spec.rb +54 -54
  53. data/spec/flat_spec.rb +62 -0
  54. data/spec/http_client_spec.rb +52 -33
  55. data/spec/json_protocol_spec.rb +170 -131
  56. data/spec/namespaced_spec.rb +67 -0
  57. data/spec/nonblocking_server_spec.rb +16 -16
  58. data/spec/processor_spec.rb +26 -26
  59. data/spec/serializer_spec.rb +20 -20
  60. data/spec/server_socket_spec.rb +27 -22
  61. data/spec/server_spec.rb +91 -51
  62. data/spec/socket_spec.rb +23 -16
  63. data/spec/socket_spec_shared.rb +31 -31
  64. data/spec/spec_helper.rb +4 -1
  65. data/spec/ssl_server_socket_spec.rb +34 -0
  66. data/spec/ssl_socket_spec.rb +78 -0
  67. data/spec/struct_nested_containers_spec.rb +24 -24
  68. data/spec/struct_spec.rb +120 -120
  69. data/spec/thin_http_server_spec.rb +19 -18
  70. data/spec/types_spec.rb +56 -53
  71. data/spec/union_spec.rb +51 -40
  72. data/spec/unix_socket_spec.rb +43 -34
  73. metadata +189 -123
  74. data/CHANGELOG +0 -1
@@ -17,25 +17,36 @@
17
17
  # under the License.
18
18
  #
19
19
 
20
+ require 'logger'
21
+
20
22
  module Thrift
21
23
  module Processor
22
- def initialize(handler)
24
+ def initialize(handler, logger=nil)
23
25
  @handler = handler
26
+ if logger.nil?
27
+ @logger = Logger.new(STDERR)
28
+ @logger.level = Logger::WARN
29
+ else
30
+ @logger = logger
31
+ end
24
32
  end
25
33
 
26
34
  def process(iprot, oprot)
27
35
  name, type, seqid = iprot.read_message_begin
28
36
  if respond_to?("process_#{name}")
29
- send("process_#{name}", seqid, iprot, oprot)
37
+ begin
38
+ send("process_#{name}", seqid, iprot, oprot)
39
+ rescue => e
40
+ x = ApplicationException.new(ApplicationException::INTERNAL_ERROR, 'Internal error')
41
+ @logger.debug "Internal error : #{e.message}\n#{e.backtrace.join("\n")}"
42
+ write_error(x, oprot, name, seqid)
43
+ end
30
44
  true
31
45
  else
32
46
  iprot.skip(Types::STRUCT)
33
47
  iprot.read_message_end
34
48
  x = ApplicationException.new(ApplicationException::UNKNOWN_METHOD, 'Unknown function '+name)
35
- oprot.write_message_begin(name, MessageTypes::EXCEPTION, seqid)
36
- x.write(oprot)
37
- oprot.write_message_end
38
- oprot.trans.flush
49
+ write_error(x, oprot, name, seqid)
39
50
  false
40
51
  end
41
52
  end
@@ -53,5 +64,12 @@ module Thrift
53
64
  oprot.write_message_end
54
65
  oprot.trans.flush
55
66
  end
67
+
68
+ def write_error(err, oprot, name, seqid)
69
+ oprot.write_message_begin(name, MessageTypes::EXCEPTION, seqid)
70
+ err.write(oprot)
71
+ oprot.write_message_end
72
+ oprot.trans.flush
73
+ end
56
74
  end
57
75
  end
@@ -28,6 +28,8 @@ module Thrift
28
28
  NEGATIVE_SIZE = 2
29
29
  SIZE_LIMIT = 3
30
30
  BAD_VERSION = 4
31
+ NOT_IMPLEMENTED = 5
32
+ DEPTH_LIMIT = 6
31
33
 
32
34
  attr_reader :type
33
35
 
@@ -321,8 +323,6 @@ module Thrift
321
323
 
322
324
  def skip(type)
323
325
  case type
324
- when Types::STOP
325
- nil
326
326
  when Types::BOOL
327
327
  read_bool
328
328
  when Types::BYTE
@@ -365,13 +365,23 @@ module Thrift
365
365
  skip(etype)
366
366
  end
367
367
  read_list_end
368
+ else
369
+ raise ProtocolException.new(ProtocolException::INVALID_DATA, 'Invalid data')
368
370
  end
369
371
  end
372
+
373
+ def to_s
374
+ "#{trans.to_s}"
375
+ end
370
376
  end
371
377
 
372
378
  class BaseProtocolFactory
373
379
  def get_protocol(trans)
374
380
  raise NotImplementedError
375
381
  end
382
+
383
+ def to_s
384
+ "base"
385
+ end
376
386
  end
377
- end
387
+ end
@@ -226,12 +226,19 @@ module Thrift
226
226
  size = read_i32
227
227
  trans.read_all(size)
228
228
  end
229
-
229
+
230
+ def to_s
231
+ "binary(#{super.to_s})"
232
+ end
230
233
  end
231
234
 
232
235
  class BinaryProtocolFactory < BaseProtocolFactory
233
236
  def get_protocol(trans)
234
237
  return Thrift::BinaryProtocol.new(trans)
235
238
  end
239
+
240
+ def to_s
241
+ "binary"
242
+ end
236
243
  end
237
244
  end
@@ -35,5 +35,13 @@ module Thrift
35
35
  BinaryProtocol.new(trans)
36
36
  end
37
37
  end
38
+
39
+ def to_s
40
+ if (defined? BinaryProtocolAccelerated)
41
+ "binary-accel"
42
+ else
43
+ "binary"
44
+ end
45
+ end
38
46
  end
39
47
  end
@@ -24,6 +24,7 @@ module Thrift
24
24
  VERSION = 1
25
25
  VERSION_MASK = 0x1f
26
26
  TYPE_MASK = 0xE0
27
+ TYPE_BITS = 0x07
27
28
  TYPE_SHIFT_AMOUNT = 5
28
29
 
29
30
  TSTOP = ["", Types::STOP, 0]
@@ -231,7 +232,7 @@ module Thrift
231
232
  raise ProtocolException.new("Expected version #{VERSION} but got #{version}");
232
233
  end
233
234
 
234
- type = (version_and_type >> TYPE_SHIFT_AMOUNT) & 0x03
235
+ type = (version_and_type >> TYPE_SHIFT_AMOUNT) & TYPE_BITS
235
236
  seqid = read_varint32()
236
237
  messageName = read_string()
237
238
  [messageName, type, seqid]
@@ -344,6 +345,10 @@ module Thrift
344
345
  size = read_varint32()
345
346
  trans.read_all(size)
346
347
  end
348
+
349
+ def to_s
350
+ "compact(#{super.to_s})"
351
+ end
347
352
 
348
353
  private
349
354
 
@@ -430,5 +435,9 @@ module Thrift
430
435
  def get_protocol(trans)
431
436
  CompactProtocol.new(trans)
432
437
  end
438
+
439
+ def to_s
440
+ "compact"
441
+ end
433
442
  end
434
443
  end
@@ -18,6 +18,7 @@
18
18
  # under the License.
19
19
  #
20
20
 
21
+ require 'base64'
21
22
 
22
23
  module Thrift
23
24
  class LookaheadReader
@@ -310,7 +311,7 @@ module Thrift
310
311
  def write_json_base64(str)
311
312
  @context.write(trans)
312
313
  trans.write(@@kJSONStringDelimiter)
313
- write_json_string([str].pack("m"))
314
+ trans.write(Base64.strict_encode64(str))
314
315
  trans.write(@@kJSONStringDelimiter)
315
316
  end
316
317
 
@@ -332,7 +333,7 @@ module Thrift
332
333
  # "NaN" or "Infinity" or "-Infinity".
333
334
  def write_json_double(num)
334
335
  @context.write(trans)
335
- # Normalize output of boost::lexical_cast for NaNs and Infinities
336
+ # Normalize output of thrift::to_string for NaNs and Infinities
336
337
  special = false;
337
338
  if (num.nan?)
338
339
  special = true;
@@ -507,13 +508,13 @@ module Thrift
507
508
  def read_json_string(skipContext = false)
508
509
  # This string's characters must match up with the elements in escape_char_vals.
509
510
  # I don't have '/' on this list even though it appears on www.json.org --
510
- # it is not in the RFC
511
- escape_chars = "\"\\bfnrt"
511
+ # it is not in the RFC -> it is. See RFC 4627
512
+ escape_chars = "\"\\/bfnrt"
512
513
 
513
514
  # The elements of this array must match up with the sequence of characters in
514
515
  # escape_chars
515
516
  escape_char_vals = [
516
- '"', '\\', '\b', '\f', '\n', '\r', '\t',
517
+ "\"", "\\", "\/", "\b", "\f", "\n", "\r", "\t",
517
518
  ]
518
519
 
519
520
  if !skipContext
@@ -546,7 +547,15 @@ module Thrift
546
547
 
547
548
  # Reads a block of base64 characters, decoding it, and returns via str
548
549
  def read_json_base64
549
- read_json_string.unpack("m")[0]
550
+ str = read_json_string
551
+ m = str.length % 4
552
+ if m != 0
553
+ # Add missing padding
554
+ (4 - m).times do
555
+ str += '='
556
+ end
557
+ end
558
+ Base64.strict_decode64(str)
550
559
  end
551
560
 
552
561
  # Reads a sequence of characters, stopping at the first one that is not
@@ -759,11 +768,19 @@ module Thrift
759
768
  def read_binary
760
769
  read_json_base64
761
770
  end
771
+
772
+ def to_s
773
+ "json(#{super.to_s})"
774
+ end
762
775
  end
763
776
 
764
777
  class JsonProtocolFactory < BaseProtocolFactory
765
778
  def get_protocol(trans)
766
779
  return Thrift::JsonProtocol.new(trans)
767
780
  end
781
+
782
+ def to_s
783
+ "json"
784
+ end
768
785
  end
769
786
  end
@@ -0,0 +1,44 @@
1
+ #
2
+ # Licensed to the Apache Software Foundation (ASF) under one
3
+ # or more contributor license agreements. See the NOTICE file
4
+ # distributed with this work for additional information
5
+ # regarding copyright ownership. The ASF licenses this file
6
+ # to you under the Apache License, Version 2.0 (the
7
+ # "License"); you may not use this file except in compliance
8
+ # with the License. You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing,
13
+ # software distributed under the License is distributed on an
14
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ # KIND, either express or implied. See the License for the
16
+ # specific language governing permissions and limitations
17
+ # under the License.
18
+
19
+ require 'thrift/protocol/protocol_decorator'
20
+
21
+ module Thrift
22
+ class MultiplexedProtocol < BaseProtocol
23
+
24
+ include ProtocolDecorator
25
+
26
+ def initialize(protocol, service_name)
27
+ super(protocol)
28
+ @service_name = service_name
29
+ end
30
+
31
+ def write_message_begin(name, type, seqid)
32
+ case type
33
+ when MessageTypes::CALL, MessageTypes::ONEWAY
34
+ @protocol.write_message_begin("#{@service_name}:#{name}", type, seqid)
35
+ else
36
+ @protocol.write_message_begin(name, type, seqid)
37
+ end
38
+ end
39
+
40
+ def to_s
41
+ "multiplexed(#{@service_name=@protocol.to_s})"
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,194 @@
1
+ #
2
+ # Licensed to the Apache Software Foundation (ASF) under one
3
+ # or more contributor license agreements. See the NOTICE file
4
+ # distributed with this work for additional information
5
+ # regarding copyright ownership. The ASF licenses this file
6
+ # to you under the Apache License, Version 2.0 (the
7
+ # "License"); you may not use this file except in compliance
8
+ # with the License. You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing,
13
+ # software distributed under the License is distributed on an
14
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ # KIND, either express or implied. See the License for the
16
+ # specific language governing permissions and limitations
17
+ # under the License.
18
+
19
+ module Thrift
20
+ module ProtocolDecorator
21
+
22
+ def initialize(protocol)
23
+ @protocol = protocol
24
+ end
25
+
26
+ def trans
27
+ @protocol.trans
28
+ end
29
+
30
+ def write_message_begin(name, type, seqid)
31
+ @protocol.write_message_begin
32
+ end
33
+
34
+ def write_message_end
35
+ @protocol.write_message_end
36
+ end
37
+
38
+ def write_struct_begin(name)
39
+ @protocol.write_struct_begin(name)
40
+ end
41
+
42
+ def write_struct_end
43
+ @protocol.write_struct_end
44
+ end
45
+
46
+ def write_field_begin(name, type, id)
47
+ @protocol.write_field_begin(name, type, id)
48
+ end
49
+
50
+ def write_field_end
51
+ @protocol.write_field_end
52
+ end
53
+
54
+ def write_field_stop
55
+ @protocol.write_field_stop
56
+ end
57
+
58
+ def write_map_begin(ktype, vtype, size)
59
+ @protocol.write_map_begin(ktype, vtype, size)
60
+ end
61
+
62
+ def write_map_end
63
+ @protocol.write_map_end
64
+ end
65
+
66
+ def write_list_begin(etype, size)
67
+ @protocol.write_list_begin(etype, size)
68
+ end
69
+
70
+ def write_list_end
71
+ @protocol.write_list_end
72
+ end
73
+
74
+ def write_set_begin(etype, size)
75
+ @protocol.write_set_begin(etype, size)
76
+ end
77
+
78
+ def write_set_end
79
+ @protocol.write_set_end
80
+ end
81
+
82
+ def write_bool(bool)
83
+ @protocol.write_bool(bool)
84
+ end
85
+
86
+ def write_byte(byte)
87
+ @protocol.write_byte(byte)
88
+ end
89
+
90
+ def write_i16(i16)
91
+ @protocol.write_i16(i16)
92
+ end
93
+
94
+ def write_i32(i32)
95
+ @protocol.write_i32(i32)
96
+ end
97
+
98
+ def write_i64(i64)
99
+ @protocol.write_i64(i64)
100
+ end
101
+
102
+ def write_double(dub)
103
+ @protocol.write_double(dub)
104
+ end
105
+
106
+ def write_string(str)
107
+ @protocol.write_string(str)
108
+ end
109
+
110
+ def write_binary(buf)
111
+ @protocol.write_binary(buf)
112
+ end
113
+
114
+ def read_message_begin
115
+ @protocol.read_message_begin
116
+ end
117
+
118
+ def read_message_end
119
+ @protocol.read_message_end
120
+ end
121
+
122
+ def read_struct_begin
123
+ @protocol.read_struct_begin
124
+ end
125
+
126
+ def read_struct_end
127
+ @protocol.read_struct_end
128
+ end
129
+
130
+ def read_field_begin
131
+ @protocol.read_field_begin
132
+ end
133
+
134
+ def read_field_end
135
+ @protocol.read_field_end
136
+ end
137
+
138
+ def read_map_begin
139
+ @protocol.read_map_begin
140
+ end
141
+
142
+ def read_map_end
143
+ @protocol.read_map_end
144
+ end
145
+
146
+ def read_list_begin
147
+ @protocol.read_list_begin
148
+ end
149
+
150
+ def read_list_end
151
+ @protocol.read_list_end
152
+ end
153
+
154
+ def read_set_begin
155
+ @protocol.read_set_begin
156
+ end
157
+
158
+ def read_set_end
159
+ @protocol.read_set_end
160
+ end
161
+
162
+ def read_bool
163
+ @protocol.read_bool
164
+ end
165
+
166
+ def read_byte
167
+ @protocol.read_byte
168
+ end
169
+
170
+ def read_i16
171
+ @protocol.read_i16
172
+ end
173
+
174
+ def read_i32
175
+ @protocol.read_i32
176
+ end
177
+
178
+ def read_i64
179
+ @protocol.read_i64
180
+ end
181
+
182
+ def read_double
183
+ @protocol.read_double
184
+ end
185
+
186
+ def read_string
187
+ @protocol.read_string
188
+ end
189
+
190
+ def read_binary
191
+ @protocol.read_binary
192
+ end
193
+ end
194
+ end