stomp 1.3.2 → 1.3.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -13,7 +13,8 @@ module Stomp
13
13
  return false unless params.is_a?(Hash)
14
14
 
15
15
  @parameters = params
16
- @parameters[:reliable] = true
16
+ # Do not override user choice of false.
17
+ @parameters[:reliable] = true unless @parameters[:reliable] == false
17
18
 
18
19
  true
19
20
  end
@@ -87,14 +88,28 @@ module Stomp
87
88
  hosts
88
89
  end
89
90
 
90
- # A very basic check of required arguments.
91
+ # A sanity check of required arguments.
91
92
  def check_arguments!()
92
- first_host = @parameters && @parameters[:hosts] && @parameters[:hosts].first
93
-
94
- raise ArgumentError if first_host.nil?
95
- raise ArgumentError if first_host[:host].nil? || first_host[:host].empty?
96
- raise ArgumentError if first_host[:port].nil? || first_host[:port] == '' || first_host[:port] < 1 || first_host[:port] > 65535
93
+ raise ArgumentError.new("missing :hosts parameter") unless @parameters[:hosts]
94
+ raise ArgumentError.new("invalid :hosts type") unless @parameters[:hosts].is_a?(Array)
95
+ @parameters[:hosts].each do |hv|
96
+ # Validate port requested
97
+ raise ArgumentError.new("empty :port value in #{hv.inspect}") if hv[:port] == ''
98
+ unless hv[:port].nil?
99
+ tpv = hv[:port].to_i
100
+ raise ArgumentError.new("invalid :port value=#{tpv} from #{hv.inspect}") if tpv < 1 || tpv > 65535
101
+ end
102
+ # Validate host requested (no validation here. if nil or '', localhost will
103
+ # be used in #Connection.)
104
+ end
97
105
  raise ArgumentError unless @parameters[:reliable].is_a?(TrueClass) || @parameters[:reliable].is_a?(FalseClass)
106
+ #
107
+ if @parameters[:reliable] && @start_timeout > 0
108
+ warn "WARN detected :reliable == true and :start_timeout > 0"
109
+ warn "WARN this may cause incorrect fail-over behavior"
110
+ warn "WARN use :start_timeout => 0 to correct"
111
+ warn "WARN !! :start_timeout default will change to 0 in the next release"
112
+ end
98
113
  end
99
114
 
100
115
  # filter_options returns a new Hash of filtered options.
@@ -171,7 +171,7 @@ module Stomp
171
171
  end
172
172
  end
173
173
  _wire_write(used_socket,"")
174
- used_socket.write body
174
+ used_socket.write body unless body == ''
175
175
  used_socket.write "\0"
176
176
  used_socket.flush if autoflush
177
177
 
@@ -306,6 +306,10 @@ module Stomp
306
306
  lp = log_params.clone
307
307
  lp[:ssl_exception] = ex
308
308
  slog(:on_ssl_connectfail, lp)
309
+ if ssl
310
+ # shut down the TCP socket - we just failed to do the SSL handshake in time
311
+ ssl.close
312
+ end
309
313
  #
310
314
  raise # Reraise
311
315
  end
@@ -81,11 +81,10 @@ module Stomp
81
81
  parse_failover_url(login) ||
82
82
  parse_positional_params(login, passcode, host, port, reliable)
83
83
 
84
- check_arguments!()
85
-
86
84
  @logger = @parameters[:logger] ||= Stomp::NullLogger.new
85
+ @start_timeout = @parameters[:start_timeout] || 10.0
86
+ check_arguments!()
87
87
 
88
- @start_timeout = @parameters[:start_timeout] || 10
89
88
  begin
90
89
  timeout(@start_timeout) {
91
90
  create_error_handler
@@ -192,6 +192,8 @@ module Stomp
192
192
  # Begin starts a transaction, and requires a name for the transaction
193
193
  def begin(name, headers = {})
194
194
  raise Stomp::Error::NoCurrentConnection if @closed_check && closed?
195
+ raise Stomp::Error::ProtocolErrorEmptyHeaderKey if headers.has_key?("")
196
+ raise Stomp::Error::ProtocolErrorEmptyHeaderValue if @protocol == Stomp::SPL_10 && headers.has_value?("")
195
197
  headers = headers.symbolize_keys
196
198
  headers[:transaction] = name
197
199
  _headerCheck(headers)
@@ -205,6 +207,8 @@ module Stomp
205
207
  # Behavior is protocol level dependent, see the specifications or comments below.
206
208
  def ack(message_id, headers = {})
207
209
  raise Stomp::Error::NoCurrentConnection if @closed_check && closed?
210
+ raise Stomp::Error::ProtocolErrorEmptyHeaderKey if headers.has_key?("")
211
+ raise Stomp::Error::ProtocolErrorEmptyHeaderValue if @protocol == Stomp::SPL_10 && headers.has_value?("")
208
212
  raise Stomp::Error::MessageIDRequiredError if message_id.nil? || message_id == ""
209
213
  headers = headers.symbolize_keys
210
214
 
@@ -234,6 +238,7 @@ module Stomp
234
238
  def nack(message_id, headers = {})
235
239
  raise Stomp::Error::NoCurrentConnection if @closed_check && closed?
236
240
  raise Stomp::Error::UnsupportedProtocolError if @protocol == Stomp::SPL_10
241
+ raise Stomp::Error::ProtocolErrorEmptyHeaderKey if headers.has_key?("")
237
242
  raise Stomp::Error::MessageIDRequiredError if message_id.nil? || message_id == ""
238
243
  headers = headers.symbolize_keys
239
244
  case @protocol
@@ -257,6 +262,8 @@ module Stomp
257
262
  # Commit commits a transaction by name.
258
263
  def commit(name, headers = {})
259
264
  raise Stomp::Error::NoCurrentConnection if @closed_check && closed?
265
+ raise Stomp::Error::ProtocolErrorEmptyHeaderKey if headers.has_key?("")
266
+ raise Stomp::Error::ProtocolErrorEmptyHeaderValue if @protocol == Stomp::SPL_10 && headers.has_value?("")
260
267
  headers = headers.symbolize_keys
261
268
  headers[:transaction] = name
262
269
  _headerCheck(headers)
@@ -267,6 +274,8 @@ module Stomp
267
274
  # Abort aborts a transaction by name.
268
275
  def abort(name, headers = {})
269
276
  raise Stomp::Error::NoCurrentConnection if @closed_check && closed?
277
+ raise Stomp::Error::ProtocolErrorEmptyHeaderKey if headers.has_key?("")
278
+ raise Stomp::Error::ProtocolErrorEmptyHeaderValue if @protocol == Stomp::SPL_10 && headers.has_value?("")
270
279
  headers = headers.symbolize_keys
271
280
  headers[:transaction] = name
272
281
  _headerCheck(headers)
@@ -278,6 +287,8 @@ module Stomp
278
287
  # For Stomp 1.1+ a session unique subscription ID is also required.
279
288
  def subscribe(name, headers = {}, subId = nil)
280
289
  raise Stomp::Error::NoCurrentConnection if @closed_check && closed?
290
+ raise Stomp::Error::ProtocolErrorEmptyHeaderKey if headers.has_key?("")
291
+ raise Stomp::Error::ProtocolErrorEmptyHeaderValue if @protocol == Stomp::SPL_10 && headers.has_value?("")
281
292
  headers = headers.symbolize_keys
282
293
  headers[:destination] = name
283
294
  if @protocol >= Stomp::SPL_11
@@ -301,6 +312,8 @@ module Stomp
301
312
  # For Stomp 1.1+ a session unique subscription ID is also required.
302
313
  def unsubscribe(dest, headers = {}, subId = nil)
303
314
  raise Stomp::Error::NoCurrentConnection if @closed_check && closed?
315
+ raise Stomp::Error::ProtocolErrorEmptyHeaderKey if headers.has_key?("")
316
+ raise Stomp::Error::ProtocolErrorEmptyHeaderValue if @protocol == Stomp::SPL_10 && headers.has_value?("")
304
317
  headers = headers.symbolize_keys
305
318
  headers[:destination] = dest
306
319
  if @protocol >= Stomp::SPL_11
@@ -321,6 +334,8 @@ module Stomp
321
334
  # Accepts a transaction header ( :transaction => 'some_transaction_id' ).
322
335
  def publish(destination, message, headers = {})
323
336
  raise Stomp::Error::NoCurrentConnection if @closed_check && closed?
337
+ raise Stomp::Error::ProtocolErrorEmptyHeaderKey if headers.has_key?("")
338
+ raise Stomp::Error::ProtocolErrorEmptyHeaderValue if @protocol == Stomp::SPL_10 && headers.has_value?("")
324
339
  headers = headers.symbolize_keys
325
340
  headers[:destination] = destination
326
341
  _headerCheck(headers)
@@ -379,6 +394,8 @@ module Stomp
379
394
  # will be received.
380
395
  def disconnect(headers = {})
381
396
  raise Stomp::Error::NoCurrentConnection if @closed_check && closed?
397
+ raise Stomp::Error::ProtocolErrorEmptyHeaderKey if headers.has_key?("")
398
+ raise Stomp::Error::ProtocolErrorEmptyHeaderValue if @protocol == Stomp::SPL_10 && headers.has_value?("")
382
399
  headers = headers.symbolize_keys
383
400
  _headerCheck(headers)
384
401
  if @protocol >= Stomp::SPL_11
@@ -71,6 +71,23 @@ module Stomp
71
71
  end
72
72
  end
73
73
 
74
+ # ProtocolErrorEmptyHeaderKey is raised if:
75
+ # * Any header key is empty ("")
76
+ class ProtocolErrorEmptyHeaderKey < RuntimeError
77
+ def message
78
+ "Empty header key"
79
+ end
80
+ end
81
+
82
+ # ProtocolErrorEmptyHeaderValue is raised if:
83
+ # * Any header value is empty ("") *and*
84
+ # * Connection protocol level == 1.0
85
+ class ProtocolErrorEmptyHeaderValue < RuntimeError
86
+ def message
87
+ "Empty header value, STOMP 1.0"
88
+ end
89
+ end
90
+
74
91
  # ProtocolError11p - base class of 1.1 CONNECT errors
75
92
  class ProtocolError11p < RuntimeError
76
93
  def message
@@ -85,6 +85,9 @@ module Stomp
85
85
  end
86
86
  end
87
87
 
88
+ raise Stomp::Error::ProtocolErrorEmptyHeaderKey if self.headers.has_key?("")
89
+ raise Stomp::Error::ProtocolErrorEmptyHeaderValue if (!protocol11p) && self.headers.has_value?("")
90
+
88
91
  body_length = -1
89
92
 
90
93
  if self.headers['content-length']
@@ -6,7 +6,7 @@ module Stomp
6
6
  module Version #:nodoc: all
7
7
  MAJOR = 1
8
8
  MINOR = 3
9
- PATCH = 2
9
+ PATCH = 3
10
10
  STRING = "#{MAJOR}.#{MINOR}.#{PATCH}"
11
11
  end
12
12
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{stomp}
8
- s.version = "1.3.2"
8
+ s.version = "1.3.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Brian McCallister", "Marius Mathiesen", "Thiago Morello", "Guy M. Allard"]
12
- s.date = %q{2013-12-08}
12
+ s.date = %q{2014-08-10}
13
13
  s.description = %q{Ruby client for the Stomp messaging protocol. Note that this gem is no longer supported on rubyforge.}
14
14
  s.email = ["brianm@apache.org", "marius@stones.com", "morellon@gmail.com", "allard.guy.m@gmail.com"]
15
15
  s.executables = ["catstomp", "stompcat"]
@@ -640,6 +640,33 @@ class TestClient < Test::Unit::TestCase
640
640
  end
641
641
  end
642
642
 
643
+ # test issue99, OK values
644
+ def test_cli_iss99_ok
645
+ return unless host() == "localhost" && port() == 61613
646
+ @client.close
647
+ #
648
+ ok_vals = dflt_data_ok()
649
+ ok_vals.each do |hsv|
650
+ assert_nothing_raised {
651
+ cli = Stomp::Client.open(hsv)
652
+ cli.close
653
+ }
654
+ end
655
+ end
656
+
657
+ # test issue99, exception values
658
+ def test_cli_iss99_ex
659
+ return unless host() == "localhost" && port() == 61613
660
+ @client.close
661
+ #
662
+ ex_vals = dflt_data_ex()
663
+ ex_vals.each do |hsv|
664
+ assert_raise ArgumentError do
665
+ cli = Stomp::Client.open(hsv)
666
+ end
667
+ end
668
+ end
669
+
643
670
  private
644
671
  def message_text
645
672
  name = caller_method_name unless name
@@ -231,7 +231,7 @@ class TestConnection < Test::Unit::TestCase
231
231
 
232
232
  # Test that a connection frame is present.
233
233
  def test_connection_frame
234
- assert_not_nil @conn.connection_frame
234
+ assert_not_nil @conn.connection_frame
235
235
  end
236
236
 
237
237
  # Test messages with multiple line ends.
@@ -519,5 +519,107 @@ class TestConnection < Test::Unit::TestCase
519
519
  end
520
520
  end
521
521
 
522
+ # Test that methods detect an empty header key.
523
+ def test_empty_header_key
524
+ #
525
+ bad_headers = {"a" => "11", "" => "emptykey", :c => "ccc"}
526
+ #
527
+ assert_raise Stomp::Error::ProtocolErrorEmptyHeaderKey do
528
+ @conn.ack("dummy_data", bad_headers)
529
+ end
530
+ #
531
+ assert_raise Stomp::Error::ProtocolErrorEmptyHeaderKey do
532
+ @conn.nack("dummy_data", bad_headers)
533
+ end if @conn.protocol != Stomp::SPL_10
534
+ #
535
+ assert_raise Stomp::Error::ProtocolErrorEmptyHeaderKey do
536
+ @conn.begin("dummy_data", bad_headers)
537
+ end
538
+ #
539
+ assert_raise Stomp::Error::ProtocolErrorEmptyHeaderKey do
540
+ @conn.commit("dummy_data", bad_headers)
541
+ end
542
+ #
543
+ assert_raise Stomp::Error::ProtocolErrorEmptyHeaderKey do
544
+ @conn.abort("dummy_data", bad_headers)
545
+ end
546
+ #
547
+ assert_raise Stomp::Error::ProtocolErrorEmptyHeaderKey do
548
+ @conn.subscribe("dummy_data", bad_headers)
549
+ end
550
+ #
551
+ assert_raise Stomp::Error::ProtocolErrorEmptyHeaderKey do
552
+ @conn.unsubscribe("dummy_data", bad_headers)
553
+ end
554
+ #
555
+ assert_raise Stomp::Error::ProtocolErrorEmptyHeaderKey do
556
+ @conn.publish("dummy_data","dummy_data", bad_headers)
557
+ end
558
+ #
559
+ assert_raise Stomp::Error::ProtocolErrorEmptyHeaderKey do
560
+ @conn.disconnect(bad_headers)
561
+ end
562
+ end
563
+
564
+ # Test that methods detect an empty header value.
565
+ # STOMP 1.0 only.
566
+ def test_empty_header_value
567
+ if @conn.protocol != Stomp::SPL_10
568
+ assert true
569
+ return
570
+ end
571
+ #
572
+ bad_headers = {"a" => "11", "hdra" => "", :c => "ccc"}
573
+ #
574
+ assert_raise Stomp::Error::ProtocolErrorEmptyHeaderValue do
575
+ @conn.ack("dummy_data", bad_headers)
576
+ end
577
+ #
578
+ assert_raise Stomp::Error::ProtocolErrorEmptyHeaderValue do
579
+ @conn.nack("dummy_data", bad_headers)
580
+ end if @conn.protocol != Stomp::SPL_10
581
+ #
582
+ assert_raise Stomp::Error::ProtocolErrorEmptyHeaderValue do
583
+ @conn.begin("dummy_data", bad_headers)
584
+ end
585
+ #
586
+ assert_raise Stomp::Error::ProtocolErrorEmptyHeaderValue do
587
+ @conn.commit("dummy_data", bad_headers)
588
+ end
589
+ #
590
+ assert_raise Stomp::Error::ProtocolErrorEmptyHeaderValue do
591
+ @conn.abort("dummy_data", bad_headers)
592
+ end
593
+ #
594
+ assert_raise Stomp::Error::ProtocolErrorEmptyHeaderValue do
595
+ @conn.subscribe("dummy_data", bad_headers)
596
+ end
597
+ #
598
+ assert_raise Stomp::Error::ProtocolErrorEmptyHeaderValue do
599
+ @conn.unsubscribe("dummy_data", bad_headers)
600
+ end
601
+ #
602
+ assert_raise Stomp::Error::ProtocolErrorEmptyHeaderValue do
603
+ @conn.publish("dummy_data","dummy_data", bad_headers)
604
+ end
605
+ #
606
+ assert_raise Stomp::Error::ProtocolErrorEmptyHeaderValue do
607
+ @conn.disconnect(bad_headers)
608
+ end
609
+ end
610
+
611
+ # test issue99, OK values
612
+ def test_con_iss99_ok
613
+ return unless host() == "localhost" && port() == 61613
614
+ #
615
+ ok_vals = dflt_data_ok()
616
+ ok_vals.each do |hsv|
617
+ assert_nothing_raised {
618
+ conn = Stomp::Connection.new(hsv)
619
+ conn.disconnect
620
+ }
621
+ end
622
+ end
623
+
522
624
  end
523
625
 
@@ -184,5 +184,58 @@ module TestBase
184
184
  jr = defined?(RUBY_ENGINE) && RUBY_ENGINE =~ /jruby/ ? true : false
185
185
  end
186
186
 
187
+ # OK Data For Default Tests
188
+ def dflt_data_ok()
189
+ [
190
+ #
191
+ { :hosts => [
192
+ {:login => 'guest', :passcode => 'guest', :host => "localhost", :port => 61613, :ssl => false},
193
+ ],
194
+ :reliable => false,
195
+ },
196
+ #
197
+ { :hosts => [
198
+ {:login => 'guest', :passcode => 'guest', :ssl => false},
199
+ ],
200
+ :reliable => false,
201
+ },
202
+ #
203
+ { :hosts => [
204
+ {:login => 'guest', :passcode => 'guest', :port => 61613, :ssl => false},
205
+ ],
206
+ :reliable => false,
207
+ },
208
+ #
209
+ { :hosts => [
210
+ {:login => 'guest', :passcode => 'guest', :host => "localhost" , :ssl => false},
211
+ ],
212
+ :reliable => false,
213
+ },
214
+ #
215
+ { :hosts => [
216
+ {:login => 'guest', :passcode => 'guest', :host => '' , :ssl => false},
217
+ ],
218
+ :reliable => false,
219
+ },
220
+ ]
221
+ end
222
+
223
+ # Exception Data For Default Tests
224
+ def dflt_data_ex()
225
+ [
226
+ {},
227
+ {:hosts => 123},
228
+ { :hosts => [
229
+ {:login => 'guest', :passcode => 'guest', :host => "localhost", :port => '' , :ssl => false},
230
+ ],
231
+ :reliable => false,
232
+ },
233
+ { :hosts => [
234
+ {:login => 'guest', :passcode => 'guest', :host => "localhost", :port => -1 , :ssl => false},
235
+ ],
236
+ :reliable => false,
237
+ },
238
+ ]
239
+ end
187
240
  end
188
241
 
@@ -172,5 +172,37 @@ class TestMessage < Test::Unit::TestCase
172
172
  assert_equal "val1", bframe.headers["h2"][2], "Expected val1"
173
173
  end
174
174
 
175
+ # Test headers with empty key / value
176
+ def test_0060_hdr_ekv
177
+ #
178
+ amsg = "MESSAGE\n" +
179
+ "h1:val1\n" +
180
+ ":val3\n" +
181
+ "h2:val2\n" +
182
+ "\n" +
183
+ "payload" +
184
+ "\0\n"
185
+ assert_raise Stomp::Error::ProtocolErrorEmptyHeaderKey do
186
+ aframe = Stomp::Message.new(amsg, false)
187
+ end
188
+ assert_raise Stomp::Error::ProtocolErrorEmptyHeaderKey do
189
+ aframe = Stomp::Message.new(amsg, true)
190
+ end
191
+ #
192
+ amsg = "MESSAGE\n" +
193
+ "h1:val1\n" +
194
+ "h2:val3\n" +
195
+ "h3:\n" +
196
+ "\n" +
197
+ "payload" +
198
+ "\0\n"
199
+ assert_raise Stomp::Error::ProtocolErrorEmptyHeaderValue do
200
+ aframe = Stomp::Message.new(amsg, false)
201
+ end
202
+ assert_nothing_raised {
203
+ aframe = Stomp::Message.new(amsg, true)
204
+ }
205
+ end
206
+
175
207
  end
176
208
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stomp
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 29
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 3
9
- - 2
10
- version: 1.3.2
9
+ - 3
10
+ version: 1.3.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Brian McCallister
@@ -18,7 +18,7 @@ autorequire:
18
18
  bindir: bin
19
19
  cert_chain: []
20
20
 
21
- date: 2013-12-08 00:00:00 -05:00
21
+ date: 2014-08-10 00:00:00 -04:00
22
22
  default_executable:
23
23
  dependencies:
24
24
  - !ruby/object:Gem::Dependency