stomp 1.3.2 → 1.3.3

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.
@@ -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