stomp 1.4.4 → 1.4.5

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 (74) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +13 -0
  3. data/README.md +96 -100
  4. data/examples/EXAMPLES.md +251 -0
  5. data/examples/amqdurasub.rb +14 -17
  6. data/examples/artemis/cliwaiter_not_reliable.rb +12 -5
  7. data/examples/artemis/{cliwaiter_reliable.rb → cliwaiter_reliable_hb.rb} +24 -23
  8. data/examples/client_conndisc.rb +66 -0
  9. data/examples/client_putget.rb +94 -0
  10. data/examples/conn_conndisc.rb +102 -0
  11. data/examples/conn_putget.rb +124 -0
  12. data/examples/contrib.sh +2 -3
  13. data/examples/contributors.rb +26 -14
  14. data/examples/examplogger.rb +1 -1
  15. data/examples/{consumer.rb → historical/consumer.rb} +0 -0
  16. data/examples/{publisher.rb → historical/publisher.rb} +0 -0
  17. data/examples/{topic_consumer.rb → historical/topic_consumer.rb} +0 -0
  18. data/examples/{topic_publisher.rb → historical/topic_publisher.rb} +0 -0
  19. data/examples/logexamp.rb +23 -14
  20. data/examples/putget_file.rb +79 -0
  21. data/examples/{putget11_rh1.rb → putget_rephdrs.rb} +16 -15
  22. data/examples/ssl/SSL.md +189 -0
  23. data/examples/{ssl_ctxoptions.rb → ssl/misc/ssl_ctxoptions.rb} +23 -14
  24. data/examples/ssl/misc/ssl_newparm.rb +53 -0
  25. data/examples/ssl/misc/ssl_ucx_default_ciphers.rb +54 -0
  26. data/examples/ssl/ssl_common.rb +96 -0
  27. data/examples/ssl/sslexall.sh +17 -0
  28. data/examples/{ssl_uc1.rb → ssl/uc1/ssl_uc1.rb} +15 -11
  29. data/examples/ssl/uc1/ssl_uc1_ciphers.rb +60 -0
  30. data/examples/{ssl_uc2.rb → ssl/uc2/ssl_uc2.rb} +17 -10
  31. data/examples/ssl/uc2/ssl_uc2_ciphers.rb +67 -0
  32. data/examples/{ssl_uc3.rb → ssl/uc3/ssl_uc3.rb} +15 -16
  33. data/examples/ssl/uc3/ssl_uc3_ciphers.rb +65 -0
  34. data/examples/{ssl_uc4.rb → ssl/uc4/ssl_uc4.rb} +15 -15
  35. data/examples/ssl/uc4/ssl_uc4_ciphers.rb +66 -0
  36. data/examples/stomp_common.rb +97 -0
  37. data/lib/connection/netio.rb +83 -37
  38. data/lib/connection/utf8.rb +0 -7
  39. data/lib/connection/utils.rb +4 -1
  40. data/lib/stomp/client.rb +5 -1
  41. data/lib/stomp/connection.rb +25 -15
  42. data/lib/stomp/constants.rb +109 -0
  43. data/lib/stomp/errors.rb +11 -0
  44. data/lib/stomp/sslparams.rb +3 -4
  45. data/lib/stomp/version.rb +2 -2
  46. data/stomp.gemspec +31 -37
  47. data/test/test_anonymous.rb +4 -0
  48. data/test/test_client.rb +2 -0
  49. data/test/test_connection.rb +4 -0
  50. data/test/test_connection1p.rb +2 -4
  51. data/test/test_helper.rb +11 -0
  52. metadata +30 -36
  53. data/examples/artemis/artlogger.rb +0 -41
  54. data/examples/client11_ex1.rb +0 -89
  55. data/examples/client11_putget1.rb +0 -71
  56. data/examples/conn11_ex1.rb +0 -112
  57. data/examples/conn11_ex2.rb +0 -87
  58. data/examples/conn11_hb1.rb +0 -57
  59. data/examples/consume_file.rb +0 -63
  60. data/examples/get11conn_ex1.rb +0 -117
  61. data/examples/get11conn_ex2.rb +0 -77
  62. data/examples/lflogger.rb +0 -316
  63. data/examples/logexamp_ssl.rb +0 -81
  64. data/examples/publish_file.rb +0 -76
  65. data/examples/publish_file_conn.rb +0 -75
  66. data/examples/put11conn_ex1.rb +0 -56
  67. data/examples/ssl_common.rb +0 -73
  68. data/examples/ssl_newparm.rb +0 -43
  69. data/examples/ssl_uc1_ciphers.rb +0 -53
  70. data/examples/ssl_uc2_ciphers.rb +0 -60
  71. data/examples/ssl_uc3_ciphers.rb +0 -64
  72. data/examples/ssl_uc4_ciphers.rb +0 -65
  73. data/examples/ssl_ucx_default_ciphers.rb +0 -41
  74. data/examples/stomp11_common.rb +0 -54
@@ -4,12 +4,15 @@
4
4
  # Reference: https://github.com/stompgem/stomp/wiki/extended-ssl-overview
5
5
  #
6
6
  if Kernel.respond_to?(:require_relative)
7
- require_relative("./ssl_common")
7
+ require_relative("../ssl_common")
8
+ require_relative("../../stomp_common")
8
9
  else
9
10
  $LOAD_PATH << File.dirname(__FILE__)
10
- require "ssl_common"
11
+ require "../ssl_common"
12
+ require("../../stomp_common")
11
13
  end
12
14
  include SSLCommon
15
+ include Stomp1xCommon
13
16
  #
14
17
  # == SSL Use Case 3 - server *does* authenticate client, client does *not* authenticate server
15
18
  #
@@ -29,23 +32,25 @@ class ExampleSSL3
29
32
  # Initialize.
30
33
  def initialize
31
34
  # Change the following as needed.
32
- @host = ENV['STOMP_HOST'] ? ENV['STOMP_HOST'] : "localhost"
35
+ @host = host()
36
+ # It is very likely that you will have to specify your specific port number.
37
+ # 61612 is currently my AMQ local port number for ssl client auth is required.
33
38
  @port = ENV['STOMP_PORT'] ? ENV['STOMP_PORT'].to_i : 61612
34
39
  end
35
40
  # Run example.
36
41
  def run
37
- puts "Connect host: #{@host}, port: #{@port}"
42
+ puts "SSLUC3 Connect host: #{@host}, port: #{@port}"
38
43
 
39
44
  # Possibly change the cert file(s) name(s) here.
40
45
  ssl_opts = Stomp::SSLParams.new(
41
- :key_file => "#{cli_loc()}/#{pck()}", # the client's private key, private data
46
+ :key_file => "#{cli_loc()}/#{cli_key()}", # the client's private key, private data
42
47
  :cert_file => "#{cli_loc()}/#{cli_cert()}", # the client's signed certificate
43
48
  :fsck => true # Check that the files exist first
44
49
  )
45
-
50
+ puts "SSLOPTS: #{ssl_opts.inspect}"
46
51
  #
47
52
  hash = { :hosts => [
48
- {:login => 'guest', :passcode => 'guest', :host => @host, :port => @port, :ssl => ssl_opts},
53
+ {:login => login(), :passcode => passcode(), :host => @host, :port => @port, :ssl => ssl_opts},
49
54
  ],
50
55
  :reliable => false, # YMMV, to test this in a sane manner
51
56
  }
@@ -54,18 +59,12 @@ class ExampleSSL3
54
59
  c = Stomp::Connection.new(hash)
55
60
  puts "Connect completed"
56
61
  puts "SSL Verify Result: #{ssl_opts.verify_result}"
57
- # puts "SSL Peer Certificate:\n#{ssl_opts.peer_cert}"
58
- c.disconnect
62
+ puts "SSL Peer Certificate:\n#{ssl_opts.peer_cert}" if showPeerCert()
63
+ c.disconnect()
59
64
  end
60
65
 
61
- private
62
-
63
- def pck()
64
- "client.key"
65
- end
66
-
67
66
  end
68
67
  #
69
- e = ExampleSSL3.new
68
+ e = ExampleSSL3.new()
70
69
  e.run
71
70
 
@@ -0,0 +1,65 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ #
4
+ # Reference: https://github.com/stompgem/stomp/wiki/extended-ssl-overview
5
+ #
6
+ if Kernel.respond_to?(:require_relative)
7
+ require_relative("../ssl_common")
8
+ require_relative("../../stomp_common")
9
+ else
10
+ $LOAD_PATH << File.dirname(__FILE__)
11
+ require "../ssl_common"
12
+ require("../../stomp_common")
13
+ end
14
+ include SSLCommon
15
+ include Stomp1xCommon
16
+ #
17
+ # == SSL Use Case 3 - User Supplied Ciphers
18
+ #
19
+ # If you need your own ciphers list, this is how.
20
+ # Stomp's default list will work in many cases. If you need to use this, you
21
+ # will know it because SSL connect will fail. In that case, determining
22
+ # _what_ should be in the list is your responsibility.
23
+ #
24
+ class ExampleSSL3C
25
+ # Initialize.
26
+ def initialize # Change the following as needed.
27
+ @host = host()
28
+ # It is very likely that you will have to specify your specific port number.
29
+ # 61612 is currently my AMQ local port number for ssl client auth is required.
30
+ @port = ENV['STOMP_PORT'] ? ENV['STOMP_PORT'].to_i : 61612
31
+ end
32
+ # Run example.
33
+ def run
34
+ puts "SSLUC3C Connect host: #{@host}, port: #{@port}"
35
+ #
36
+ # SSL Use Case 3
37
+ #
38
+ # Possibly change the cert file(s) name(s) here.
39
+ ssl_opts = Stomp::SSLParams.new(
40
+ :key_file => "#{cli_loc()}/#{cli_key()}", # the client's private key, private data
41
+ :cert_file => "#{cli_loc()}/#{cli_cert()}", # the client's signed certificate
42
+ :ciphers => ciphers_list(), # The cipher list
43
+ :fsck => true # Check that the files exist first
44
+ )
45
+ #
46
+ puts "SSLOPTS: #{ssl_opts.inspect}"
47
+ hash = { :hosts => [
48
+ {:login => login(), :passcode => passcode(), :host => @host, :port => @port, :ssl => ssl_opts},
49
+ ],
50
+ :reliable => false, # YMMV, to test this in a sane manner
51
+ }
52
+ #
53
+ puts "Connect starts, SSL Use Case 3"
54
+ c = Stomp::Connection.new(hash)
55
+ puts "Connect completed"
56
+ puts "SSL Verify Result: #{ssl_opts.verify_result}"
57
+ puts "SSL Peer Certificate:\n#{ssl_opts.peer_cert}" if showPeerCert()
58
+ c.disconnect()
59
+ end
60
+
61
+ end
62
+ #
63
+ e = ExampleSSL3C.new()
64
+ e.run
65
+
@@ -4,12 +4,15 @@
4
4
  # Reference: https://github.com/stompgem/stomp/wiki/extended-ssl-overview
5
5
  #
6
6
  if Kernel.respond_to?(:require_relative)
7
- require_relative("./ssl_common")
7
+ require_relative("../ssl_common")
8
+ require_relative("../../stomp_common")
8
9
  else
9
10
  $LOAD_PATH << File.dirname(__FILE__)
10
- require "ssl_common"
11
+ require "../ssl_common"
12
+ require("../../stomp_common")
11
13
  end
12
14
  include SSLCommon
15
+ include Stomp1xCommon
13
16
  #
14
17
  # == SSL Use Case 4 - server *does* authenticate client, client *does* authenticate server
15
18
  #
@@ -29,23 +32,26 @@ class ExampleSSL4
29
32
  # Initialize.
30
33
  def initialize
31
34
  # Change the following as needed.
32
- @host = ENV['STOMP_HOST'] ? ENV['STOMP_HOST'] : "localhost"
35
+ @host = host()
36
+ # It is very likely that you will have to specify your specific port number.
37
+ # 61612 is currently my AMQ local port number for ssl client auth is required.
33
38
  @port = ENV['STOMP_PORT'] ? ENV['STOMP_PORT'].to_i : 61612
34
39
  end
35
40
  # Run example.
36
41
  def run
37
- puts "Connect host: #{@host}, port: #{@port}"
42
+ puts "SSLUC4 Connect host: #{@host}, port: #{@port}"
38
43
 
39
44
  # Possibly change the cert file(s) name(s) here.
40
45
  ssl_opts = Stomp::SSLParams.new(
41
- :key_file => "#{cli_loc()}/#{pck()}", # the client's private key, private data
46
+ :key_file => "#{cli_loc()}/#{cli_key()}", # the client's private key, private data
42
47
  :cert_file => "#{cli_loc()}/#{cli_cert()}", # the client's signed certificate
43
48
  :ts_files => "#{ca_loc()}/#{ca_cert()}", # The CA's signed sertificate
44
49
  :fsck => true # Check that files exist first
45
50
  )
51
+ puts "SSLOPTS: #{ssl_opts.inspect}"
46
52
  #
47
53
  hash = { :hosts => [
48
- {:login => 'guest', :passcode => 'guest', :host => @host, :port => @port, :ssl => ssl_opts},
54
+ {:login => login(), :passcode => passcode(), :host => @host, :port => @port, :ssl => ssl_opts},
49
55
  ],
50
56
  :reliable => false, # YMMV, to test this in a sane manner
51
57
  }
@@ -54,18 +60,12 @@ class ExampleSSL4
54
60
  c = Stomp::Connection.new(hash)
55
61
  puts "Connect completed"
56
62
  puts "SSL Verify Result: #{ssl_opts.verify_result}"
57
- # puts "SSL Peer Certificate:\n#{ssl_opts.peer_cert}"
58
- c.disconnect
63
+ puts "SSL Peer Certificate:\n#{ssl_opts.peer_cert}" if showPeerCert()
64
+ c.disconnect()
59
65
  end
60
66
 
61
- private
62
-
63
- def pck()
64
- "client.key"
65
- end
66
-
67
67
  end
68
68
  #
69
- e = ExampleSSL4.new
69
+ e = ExampleSSL4.new()
70
70
  e.run
71
71
 
@@ -0,0 +1,66 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ #
4
+ # Reference: https://github.com/stompgem/stomp/wiki/extended-ssl-overview
5
+ #
6
+ if Kernel.respond_to?(:require_relative)
7
+ require_relative("../ssl_common")
8
+ require_relative("../../stomp_common")
9
+ else
10
+ $LOAD_PATH << File.dirname(__FILE__)
11
+ require "../ssl_common"
12
+ require("../../stomp_common")
13
+ end
14
+ include SSLCommon
15
+ include Stomp1xCommon
16
+ #
17
+ # == SSL Use Case 4 - User Supplied Ciphers
18
+ #
19
+ # If you need your own ciphers list, this is how.
20
+ # Stomp's default list will work in many cases. If you need to use this, you
21
+ # will know it because SSL connect will fail. In that case, determining
22
+ # _what_ should be in the list is your responsibility.
23
+ #
24
+ class ExampleSSL4C
25
+ # Initialize.
26
+ def initialize # Change the following as needed.
27
+ @host = host()
28
+ # It is very likely that you will have to specify your specific port number.
29
+ # 61612 is currently my AMQ local port number for ssl client auth is required.
30
+ @port = ENV['STOMP_PORT'] ? ENV['STOMP_PORT'].to_i : 61612
31
+ end
32
+ # Run example.
33
+ def run
34
+ puts "SSLUC4C Connect host: #{@host}, port: #{@port}"
35
+ #
36
+ # SSL Use Case 4
37
+ #
38
+ # Possibly change the cert file(s) name(s) here.
39
+ ssl_opts = Stomp::SSLParams.new(
40
+ :key_file => "#{cli_loc()}/#{cli_key()}", # the client's private key, private data
41
+ :cert_file => "#{cli_loc()}/#{cli_cert()}", # the client's signed certificate
42
+ :ts_files => "#{ca_loc()}/#{ca_cert()}", # The CA's signed sertificate
43
+ :ciphers => ciphers_list(), # The cipher list
44
+ :fsck => true # Check that files exist first
45
+ )
46
+ puts "SSLOPTS: #{ssl_opts.inspect}"
47
+ #
48
+ hash = { :hosts => [
49
+ {:login => login(), :passcode => passcode(), :host => @host, :port => @port, :ssl => ssl_opts},
50
+ ],
51
+ :reliable => false, # YMMV, to test this in a sane manner
52
+ }
53
+ #
54
+ puts "Connect starts, SSL Use Case 4"
55
+ c = Stomp::Connection.new(hash)
56
+ puts "Connect completed"
57
+ puts "SSL Verify Result: #{ssl_opts.verify_result}"
58
+ puts "SSL Peer Certificate:\n#{ssl_opts.peer_cert}" if showPeerCert()
59
+ c.disconnect()
60
+ end
61
+
62
+ end
63
+ #
64
+ e = ExampleSSL4C.new()
65
+ e.run
66
+
@@ -0,0 +1,97 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ #
4
+ # Common Stomp 1.x code.
5
+ #
6
+ require "rubygems" if RUBY_VERSION < "1.9"
7
+ require "stomp"
8
+ #
9
+ module Stomp1xCommon
10
+ # User id
11
+ def login()
12
+ ENV['STOMP_LOGIN'] || 'guest'
13
+ end
14
+ # Password
15
+ def passcode()
16
+ ENV['STOMP_PASSCODE'] || 'guest'
17
+ end
18
+ # Server host
19
+ def host()
20
+ ENV['STOMP_HOST'] || "localhost" # The connect host name
21
+ end
22
+ # Server port
23
+ def port()
24
+ (ENV['STOMP_PORT'] || 61613).to_i # !! The author runs AMQ listening here
25
+ end
26
+ # Required vhost name
27
+ def virt_host()
28
+ ENV['STOMP_VHOST'] || "localhost" # The 1.1 virtual host name
29
+ end
30
+ # Protocol level
31
+ def protocol()
32
+ ENV['STOMP_PROTOCOL'] || "1.2" # The default protocol level
33
+ end
34
+ # Heartbeats
35
+ def heartbeats()
36
+ ENV['STOMP_HEARTBEATS'] || nil
37
+ end
38
+ # Destination
39
+ def dest()
40
+ ENV['STOMP_DEST'] || "/queue/#{Time.now.to_f}"
41
+ end
42
+
43
+ # Create a 1.x commection
44
+ def get_connection()
45
+ conn_hdrs = {"accept-version" => protocol(),
46
+ "host" => virt_host(), # the vhost
47
+ }
48
+ if heartbeats()
49
+ conn_hdrs['heart-beat'] = heartbeats()
50
+ end
51
+
52
+ conn_hash = { :hosts => [
53
+ {:login => login(), :passcode => passcode(), :host => host(), :port => port(),
54
+ :ssl => usessl()},
55
+ ],
56
+ :connect_headers => conn_hdrs,
57
+ }
58
+ conn = Stomp::Connection.new(conn_hash)
59
+ end
60
+
61
+ # Create a 1.x client
62
+ def get_client()
63
+ conn_hdrs = {"accept-version" => protocol(),
64
+ "host" => virt_host(), # the vhost
65
+ }
66
+ if heartbeats()
67
+ conn_hdrs['heart-beat'] = heartbeats()
68
+ end
69
+
70
+ conn_hash = { :hosts => [
71
+ {:login => login(), :passcode => passcode(), :host => host(), :port => port(),
72
+ :ssl => usessl()},
73
+ ],
74
+ :connect_headers => conn_hdrs,
75
+ }
76
+ conn = Stomp::Client.new(conn_hash)
77
+ end
78
+
79
+ # Number of messages
80
+ def nmsgs()
81
+ (ENV['STOMP_NMSGS'] || 1).to_i # Number of messages
82
+ end
83
+
84
+ # Include "suppress-content-length' header
85
+ def suppresscl()
86
+ ENV['STOMP_SUPPRESS_CL']
87
+ end
88
+
89
+ # Use SSL or not
90
+ def usessl()
91
+ if ENV['STOMP_SSL']
92
+ return true
93
+ end
94
+ return false
95
+ end
96
+ end
97
+
@@ -23,13 +23,19 @@ module Stomp
23
23
  private
24
24
 
25
25
  # Really read from the wire.
26
- def _receive(read_socket, connread = false)
27
- # p [ "ioscheck", @iosto, connread ]
26
+ def _receive(read_socket, connread = false, noiosel = false)
27
+
28
+ # p [ "ioscheck", @iosto, connread, noiosel, @nto_cmd_read ]
28
29
  # _dump_callstack()
29
- # drdbg = true
30
- drdbg = false
30
+ drdbg = ENV['DRDBG'] ? true : false
31
+
31
32
  @read_semaphore.synchronize do
33
+ p [ "_receive_lock", Thread::current() ] if drdbg
32
34
  line = nil
35
+
36
+ # =====
37
+ # Read COMMAND (frame name)
38
+ # =====
33
39
  if connread
34
40
  begin
35
41
  Timeout::timeout(@connread_timeout, Stomp::Error::ConnectReadTimeout) do
@@ -42,65 +48,79 @@ module Stomp
42
48
  raise ex
43
49
  end
44
50
  else
45
- p [ "CONR01" ] if drdbg
51
+ p [ "_receive_COMMAND" ] if drdbg
46
52
  _dump_callstack() if drdbg
47
53
  line = _init_line_read(read_socket)
48
54
  end
49
55
  #
50
- p [ "nilcheck", line.nil? ] if drdbg
56
+ p [ "_receive_nilcheck", line.nil? ] if drdbg
51
57
  return nil if line.nil?
52
58
  #An extra \n at the beginning of the frame, possibly not caught by is_ready?
53
59
  line = '' if line == "\n"
54
60
  if line == HAND_SHAKE_DATA
55
61
  raise Stomp::Error::HandShakeDetectedError
56
62
  end
57
- p [ "wiredatain_01A", line, Time.now ] if drdbg
63
+
64
+ # Check for a valid frame name from the server.
65
+ frname = line.chomp
66
+ p [ "_receive_frame_name_check", frname ] if drdbg
67
+ unless SERVER_FRAMES[frname]
68
+ sfex = Stomp::Error::ServerFrameNameError.new(frname)
69
+ raise sfex
70
+ end
71
+
72
+ p [ "_receive_norm_lend", line, Time.now ] if drdbg
58
73
  line = _normalize_line_end(line) if @protocol >= Stomp::SPL_12
59
- p [ "wiredatain_01B", line, Time.now ] if drdbg
60
- # Reads the beginning of the message until it runs into a empty line
74
+
75
+ # =====
76
+ # Read Headers (if any)
77
+ # =====
78
+ # Reads the headers until it runs into a empty line
79
+ p [ "_receive_start_headers", line, Time.now ] if drdbg
61
80
  message_header = ''
62
81
  begin
63
82
  message_header += line
64
- p [ "wiredatain_02A", line, Time.now ] if drdbg
65
- unless connread || @ssl
83
+ unless connread || noiosel || @nto_cmd_read
66
84
  raise Stomp::Error::ReceiveTimeout unless IO.select([read_socket], nil, nil, @iosto)
67
85
  end
68
- p [ "wiredatain_02B", line, Time.now ] if drdbg
86
+ p [ "_receive_next_header", line, Time.now ] if drdbg
69
87
  line = _interruptible_gets(read_socket)
70
- p [ "wiredatain_02C", line ] if drdbg
71
- raise if line.nil?
88
+ p [ "_receive_normle_header", line ] if drdbg
89
+ raise Stomp::Error::StompServerError if line.nil?
72
90
  line = _normalize_line_end(line) if @protocol >= Stomp::SPL_12
73
- p [ "wiredatain_02D", line ] if drdbg
74
91
  end until line =~ /^\s?\n$/
75
- p [ "wiredatain_03A" ] if drdbg
92
+ p [ "_receive_end_headers" ] if drdbg
76
93
  # Checks if it includes content_length header
77
94
  content_length = message_header.match(/content-length\s?:\s?(\d+)\s?\n/)
78
95
  message_body = ''
79
96
 
80
- p [ "wiredatain_03B", content_length ] if drdbg
97
+ # =====
98
+ # Read message body (if any)
99
+ # =====
100
+ p [ "_receive_start_body", content_length ] if drdbg
81
101
  # If content_length is present, read the specified amount of bytes
82
102
  if content_length
83
- unless connread || @ssl
103
+ unless connread || noiosel
84
104
  raise Stomp::Error::ReceiveTimeout unless IO.select([read_socket], nil, nil, @iosto)
85
105
  end
86
- p [ "CL01" ] if drdbg
106
+ p [ "_receive_have_content_length" ] if drdbg
87
107
  message_body = read_socket.read content_length[1].to_i
88
- unless connread || @ssl
108
+ unless connread || noiosel
89
109
  raise Stomp::Error::ReceiveTimeout unless IO.select([read_socket], nil, nil, @iosto)
90
110
  end
91
111
  raise Stomp::Error::InvalidMessageLength unless parse_char(read_socket.getc) == "\0"
92
112
  # Else read the rest of the message until the first \0
93
113
  else
94
- unless connread || @ssl
114
+ unless connread || noiosel
95
115
  raise Stomp::Error::ReceiveTimeout unless IO.select([read_socket], nil, nil, @iosto)
96
116
  end
97
- p [ "NOCL01" ] if drdbg
117
+ p [ "no_content_length" ] if drdbg
98
118
  message_body = read_socket.readline("\0")
99
119
  message_body.chop!
100
120
  end
101
121
 
102
- p [ "wiredatain_04" ] if drdbg
103
- # If the buffer isn't empty, reads trailing new lines.
122
+ # =====
123
+ # If the buffer isn't empty, reads/drains trailing new lines.
104
124
  #
105
125
  # Note: experiments with JRuby seem to show that socket.ready? never
106
126
  # returns true. It appears that in cases where Ruby returns true
@@ -111,12 +131,13 @@ module Stomp
111
131
  # is read. Do _not_ leave them on the wire and attempt to drain them
112
132
  # at the start of the next read. Attempting to do that breaks the
113
133
  # asynchronous nature of the 'poll' method.
114
- p [ "wiredatain_05_prep", "isr", _is_ready?(read_socket) ] if drdbg
134
+ # =====
135
+ p [ "_receive_start_drain_loop", "isr", _is_ready?(read_socket) ] if drdbg
115
136
  while _is_ready?(read_socket)
116
- unless connread || @ssl
137
+ unless connread || noiosel
117
138
  raise Stomp::Error::ReceiveTimeout unless IO.select([read_socket], nil, nil, @iosto)
118
139
  end
119
- p [ "WHIR01" ] if drdbg
140
+ p [ "_receive_next_drain" ] if drdbg
120
141
  last_char = read_socket.getc
121
142
  break unless last_char
122
143
  if parse_char(last_char) != "\n"
@@ -124,19 +145,24 @@ module Stomp
124
145
  break
125
146
  end
126
147
  end
127
- p [ "wiredatain_05A" ] if drdbg
148
+
149
+ # =====
150
+ # Complete receive processing
151
+ # =====
152
+ p [ "_receive_hb_update" ] if drdbg
128
153
  if @protocol >= Stomp::SPL_11
129
154
  @lr = Time.now.to_f if @hbr
130
155
  end
131
156
  # Adds the excluded \n and \0 and tries to create a new message with it
132
- p [ "wiredatain_05B" ] if drdbg
157
+ p [ "_receive_new_message" ] if drdbg
133
158
  msg = Message.new(message_header + "\n" + message_body + "\0", @protocol >= Stomp::SPL_11)
134
- p [ "wiredatain_06", msg.command, msg.headers ] if drdbg
159
+ p [ "_receive_decode_headers", msg.command, msg.headers ] if drdbg
135
160
  #
136
161
  if @protocol >= Stomp::SPL_11 && msg.command != Stomp::CMD_CONNECTED
137
162
  msg.headers = _decodeHeaders(msg.headers)
138
163
  end
139
- p [ "wiredatain_99", msg.command, msg.headers ] if drdbg
164
+ p [ "_receive_ends", msg.command, msg.headers ] if drdbg
165
+ p [ "_receive_UNlock", Thread::current() ] if drdbg
140
166
  msg
141
167
  end
142
168
  end
@@ -175,6 +201,7 @@ module Stomp
175
201
 
176
202
  # transmit logically puts a Message on the wire.
177
203
  def transmit(command, headers = {}, body = '')
204
+ # p [ "XMIT01", command, headers ]
178
205
  # The transmit may fail so we may need to retry.
179
206
  while true
180
207
  begin
@@ -199,7 +226,7 @@ module Stomp
199
226
 
200
227
  # _transmit is the real wire write logic.
201
228
  def _transmit(used_socket, command, headers = {}, body = '')
202
-
229
+ dtrdbg = ENV['DTRDBG'] ? true : false
203
230
  # p [ "wirewrite" ]
204
231
  # _dump_callstack()
205
232
 
@@ -207,6 +234,7 @@ module Stomp
207
234
  headers = _encodeHeaders(headers)
208
235
  end
209
236
  @transmit_semaphore.synchronize do
237
+ p [ "_transmit_lock", Thread::current() ] if dtrdbg
210
238
  # Handle nil body
211
239
  body = '' if body.nil?
212
240
  # The content-length should be expressed in bytes.
@@ -250,20 +278,32 @@ module Stomp
250
278
  if @protocol >= Stomp::SPL_11
251
279
  @ls = Time.now.to_f if @hbs
252
280
  end
253
-
281
+ p [ "_transmit_UNlock", Thread::current() ] if dtrdbg
254
282
  end
255
283
  end
256
284
 
257
285
  # Use CRLF if protocol is >= 1.2, and the client requested CRLF
258
286
  def _wire_write(sock, data)
259
287
  # p [ "debug_01", @protocol, @usecrlf ]
288
+ dwrdbg = ENV['DWRDBG'] ? true : false
260
289
  if @protocol >= Stomp::SPL_12 && @usecrlf
261
290
  wiredata = "#{data}#{Stomp::CR}#{Stomp::LF}"
262
291
  # p [ "wiredataout_01:", wiredata ]
263
292
  sock.write(wiredata)
264
293
  else
265
- # p [ "wiredataout_02:", "#{data}\n" ]
266
- sock.puts data
294
+ p [ "_wire_write_begin:", "#{data}" ] if dwrdbg
295
+ if @jruby && @ssl
296
+ p [ "_wire_write_jrbeg:" ] if dwrdbg
297
+ # Same results for all of these write methods.
298
+ # sock.puts data
299
+ # sock.print "#{data}\n"
300
+ # sock.syswrite "#{data}\n"
301
+ sock.write "#{data}\n"
302
+ p [ "_wire_write_jrend:" ] if dwrdbg
303
+ else
304
+ sock.puts data
305
+ end
306
+ p [ "_wire_write_end:" ] if dwrdbg
267
307
  end
268
308
  end
269
309
 
@@ -376,8 +416,12 @@ module Stomp
376
416
  end
377
417
  end
378
418
  def ssl.ready?
379
- ! @rbuffer.empty? || @io.ready?
419
+ @ssl_ready_lock ||= Mutex.new
420
+ @ssl_ready_lock.synchronize do
421
+ ! @rbuffer.empty? || @io.ready?
422
+ end
380
423
  end
424
+
381
425
  if @ssl != true
382
426
  # Pass back results if possible
383
427
  if RUBY_VERSION =~ /1\.8\.[56]/
@@ -454,7 +498,9 @@ module Stomp
454
498
  else
455
499
  _transmit(used_socket, Stomp::CMD_CONNECT, headers)
456
500
  end
457
- @connection_frame = _receive(used_socket, true)
501
+ connread = true
502
+ noiosel = false
503
+ @connection_frame = _receive(used_socket, connread, noiosel)
458
504
  _post_connect
459
505
  @disconnect_receipt = nil
460
506
  @session = @connection_frame.headers["session"] if @connection_frame