bunny 0.8.0 → 0.9.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. data/.gitignore +7 -1
  2. data/.travis.yml +14 -4
  3. data/ChangeLog.md +72 -0
  4. data/Gemfile +17 -11
  5. data/README.md +82 -0
  6. data/bunny.gemspec +6 -13
  7. data/examples/connection/heartbeat.rb +17 -0
  8. data/lib/bunny.rb +40 -56
  9. data/lib/bunny/channel.rb +615 -19
  10. data/lib/bunny/channel_id_allocator.rb +59 -0
  11. data/lib/bunny/compatibility.rb +24 -0
  12. data/lib/bunny/concurrent/condition.rb +63 -0
  13. data/lib/bunny/consumer.rb +42 -26
  14. data/lib/bunny/consumer_tag_generator.rb +22 -0
  15. data/lib/bunny/consumer_work_pool.rb +67 -0
  16. data/lib/bunny/exceptions.rb +128 -0
  17. data/lib/bunny/exchange.rb +131 -136
  18. data/lib/bunny/framing.rb +53 -0
  19. data/lib/bunny/heartbeat_sender.rb +59 -0
  20. data/lib/bunny/main_loop.rb +70 -0
  21. data/lib/bunny/message_metadata.rb +126 -0
  22. data/lib/bunny/queue.rb +102 -275
  23. data/lib/bunny/session.rb +478 -0
  24. data/lib/bunny/socket.rb +44 -0
  25. data/lib/bunny/system_timer.rb +9 -9
  26. data/lib/bunny/transport.rb +179 -0
  27. data/lib/bunny/version.rb +1 -1
  28. data/spec/compatibility/queue_declare_spec.rb +40 -0
  29. data/spec/higher_level_api/integration/basic_ack_spec.rb +54 -0
  30. data/spec/higher_level_api/integration/basic_consume_spec.rb +51 -0
  31. data/spec/higher_level_api/integration/basic_get_spec.rb +47 -0
  32. data/spec/higher_level_api/integration/basic_nack_spec.rb +39 -0
  33. data/spec/higher_level_api/integration/basic_publish_spec.rb +105 -0
  34. data/spec/higher_level_api/integration/basic_qos_spec.rb +32 -0
  35. data/spec/higher_level_api/integration/basic_recover_spec.rb +18 -0
  36. data/spec/higher_level_api/integration/basic_reject_spec.rb +53 -0
  37. data/spec/higher_level_api/integration/basic_return_spec.rb +33 -0
  38. data/spec/higher_level_api/integration/channel_close_spec.rb +29 -0
  39. data/spec/higher_level_api/integration/channel_flow_spec.rb +24 -0
  40. data/spec/higher_level_api/integration/channel_open_spec.rb +57 -0
  41. data/spec/higher_level_api/integration/channel_open_stress_spec.rb +22 -0
  42. data/spec/higher_level_api/integration/confirm_select_spec.rb +19 -0
  43. data/spec/higher_level_api/integration/connection_spec.rb +340 -0
  44. data/spec/higher_level_api/integration/exchange_bind_spec.rb +31 -0
  45. data/spec/higher_level_api/integration/exchange_declare_spec.rb +183 -0
  46. data/spec/higher_level_api/integration/exchange_delete_spec.rb +37 -0
  47. data/spec/higher_level_api/integration/exchange_unbind_spec.rb +40 -0
  48. data/spec/higher_level_api/integration/queue_bind_spec.rb +109 -0
  49. data/spec/higher_level_api/integration/queue_declare_spec.rb +129 -0
  50. data/spec/higher_level_api/integration/queue_delete_spec.rb +38 -0
  51. data/spec/higher_level_api/integration/queue_purge_spec.rb +30 -0
  52. data/spec/higher_level_api/integration/queue_unbind_spec.rb +33 -0
  53. data/spec/higher_level_api/integration/tx_commit_spec.rb +21 -0
  54. data/spec/higher_level_api/integration/tx_rollback_spec.rb +21 -0
  55. data/spec/lower_level_api/integration/basic_cancel_spec.rb +57 -0
  56. data/spec/lower_level_api/integration/basic_consume_spec.rb +100 -0
  57. data/spec/spec_helper.rb +64 -0
  58. data/spec/unit/bunny_spec.rb +15 -0
  59. data/spec/unit/concurrent/condition_spec.rb +66 -0
  60. metadata +135 -93
  61. data/CHANGELOG +0 -21
  62. data/README.textile +0 -76
  63. data/Rakefile +0 -14
  64. data/examples/simple.rb +0 -32
  65. data/examples/simple_ack.rb +0 -35
  66. data/examples/simple_consumer.rb +0 -55
  67. data/examples/simple_fanout.rb +0 -41
  68. data/examples/simple_headers.rb +0 -42
  69. data/examples/simple_publisher.rb +0 -29
  70. data/examples/simple_topic.rb +0 -61
  71. data/ext/amqp-0.9.1.json +0 -389
  72. data/ext/config.yml +0 -4
  73. data/ext/qparser.rb +0 -426
  74. data/lib/bunny/client.rb +0 -370
  75. data/lib/bunny/subscription.rb +0 -92
  76. data/lib/qrack/amq-client-url.rb +0 -165
  77. data/lib/qrack/channel.rb +0 -20
  78. data/lib/qrack/client.rb +0 -247
  79. data/lib/qrack/errors.rb +0 -5
  80. data/lib/qrack/protocol/protocol.rb +0 -135
  81. data/lib/qrack/protocol/spec.rb +0 -525
  82. data/lib/qrack/qrack.rb +0 -20
  83. data/lib/qrack/queue.rb +0 -40
  84. data/lib/qrack/subscription.rb +0 -152
  85. data/lib/qrack/transport/buffer.rb +0 -305
  86. data/lib/qrack/transport/frame.rb +0 -102
  87. data/spec/spec_09/amqp_url_spec.rb +0 -19
  88. data/spec/spec_09/bunny_spec.rb +0 -76
  89. data/spec/spec_09/connection_spec.rb +0 -34
  90. data/spec/spec_09/exchange_spec.rb +0 -173
  91. data/spec/spec_09/queue_spec.rb +0 -240
@@ -1,92 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Bunny
4
-
5
- # Asks the server to start a "consumer", which is a transient request for messages from a specific
6
- # queue. Consumers last as long as the channel they were created on, or until the client cancels them
7
- # with an @unsubscribe@. Every time a message reaches the queue it is passed to the @blk@ for
8
- # processing. If error occurs, {Bunny::ProtocolError} is raised.
9
- #
10
- # @option opts [String] :consumer_tag
11
- # Specifies the identifier for the consumer. The consumer tag is
12
- # local to a connection, so two clients can use the same consumer tags.
13
- # If this option is not specified a server generated name is used.
14
- #
15
- # @option opts [Boolean] :ack (false)
16
- # If set to @false@, the server does not expect an acknowledgement message
17
- # from the client. If set to @true, the server expects an acknowledgement
18
- # message from the client and will re-queue the message if it does not
19
- # receive one within a time specified by the server.
20
- #
21
- # @option opts [Boolean] :exclusive (false)
22
- # Request exclusive consumer access, meaning only this consumer can access the queue.
23
- #
24
- # @option opts [Boolean] :nowait (false)
25
- # Ignored by Bunny, always @false@.
26
- #
27
- # @option opts [Numeric] :timeout
28
- # The subscribe loop will continue to wait for messages
29
- # until terminated (Ctrl-C or kill command) or this timeout interval is reached.
30
- #
31
- # @option opts [Integer] :message_max
32
- # When the required number of messages is processed subscribe loop is exited.
33
- #
34
- # @option opts [IO] :cancellator (nil)
35
- # A cancellator can be used to for cancelling the subscribe loop from another
36
- # thread or from a signal handler. Whenever Bunny notices that this IO object has
37
- # become readable, the subscribe loop will be exited after the current message
38
- # has been processed.
39
- #
40
- # h2. Operation
41
- #
42
- # Passes a hash of message information to the block, if one has been supplied. The hash contains
43
- # :header, :payload and :delivery_details. The structure of the data is as follows -
44
- #
45
- # :header has instance variables -
46
- # @klass
47
- # @size
48
- # @weight
49
- # @properties is a hash containing -
50
- # :content_type
51
- # :delivery_mode
52
- # :priority
53
- #
54
- # :payload contains the message contents
55
- #
56
- # :delivery details is a hash containing -
57
- # :consumer_tag
58
- # :delivery_tag
59
- # :redelivered
60
- # :exchange
61
- # :routing_key
62
- #
63
- # If the :timeout option is specified then the subscription will automatically
64
- # cease if the given number of seconds passes with no message arriving.
65
- #
66
- # @example
67
- # my_queue.subscribe(timeout: 5) { |msg| puts msg[:payload] }
68
- # my_queue.subscribe(message_max: 10, ack: true) { |msg| puts msg[:payload] }
69
- class Subscription < Bunny::Consumer
70
-
71
- def setup_consumer
72
- subscription_options = {
73
- :deprecated_ticket => 0,
74
- :queue => queue.name,
75
- :consumer_tag => consumer_tag,
76
- :no_ack => !ack,
77
- :exclusive => exclusive,
78
- :nowait => false
79
- }.merge(@opts)
80
-
81
- client.send_frame(Qrack::Protocol::Basic::Consume.new(subscription_options))
82
-
83
- method = client.next_method
84
-
85
- client.check_response(method, Qrack::Protocol::Basic::ConsumeOk, "Error subscribing to queue #{queue.name}, got #{method}")
86
-
87
- @consumer_tag = method.consumer_tag
88
- end
89
-
90
- end
91
-
92
- end
@@ -1,165 +0,0 @@
1
- # encoding: utf-8
2
-
3
- ################################################################
4
- # DO NOT EDIT THIS FILE ! #
5
- # The file comes from https://github.com/ruby-amqp/amq-client, #
6
- # it's located in lib/amq/client/settings.rb, so if you want #
7
- # to make some changes, please do them in the amq-client repo. #
8
- ################################################################
9
-
10
- # TODO: When we start to work on porting Bunny on AMQ Client,
11
- # this file will become obsolete.
12
-
13
- require "uri"
14
-
15
- module AMQ
16
- module Client
17
- # @see AMQ::Client::Settings.configure
18
- module Settings
19
- # @private
20
- AMQP_PORTS = {"amqp" => 5672, "amqps" => 5671}.freeze
21
-
22
- # @private
23
- AMQPS = "amqps".freeze
24
-
25
- # Default connection settings used by AMQ clients
26
- #
27
- # @see AMQ::Client::Settings.configure
28
- def self.default
29
- @default ||= {
30
- # server
31
- :host => "127.0.0.1",
32
- :port => AMQ::Protocol::DEFAULT_PORT,
33
-
34
- # login
35
- :user => "guest",
36
- :pass => "guest",
37
- :vhost => "/",
38
-
39
- # connection timeout
40
- :timeout => nil,
41
-
42
- # logging
43
- :logging => false,
44
-
45
- # ssl
46
- :ssl => false,
47
-
48
- # broker
49
- # if you want to load broker-specific extensions
50
- :broker => nil,
51
-
52
- :frame_max => 131072
53
- }
54
- end
55
-
56
-
57
- def self.client_properties
58
- @client_properties ||= {
59
- :platform => ::RUBY_DESCRIPTION,
60
- :product => "AMQ Client",
61
- :information => "http://github.com/ruby-amqp/amq-client",
62
- :version => AMQ::Client::VERSION
63
- }
64
- end
65
-
66
-
67
- # Merges given configuration parameters with defaults and returns
68
- # the result.
69
- #
70
- # @param [Hash] Configuration parameters to use.
71
- #
72
- # @option settings [String] :host ("127.0.0.1") Hostname AMQ broker runs on.
73
- # @option settings [String] :port (5672) Port AMQ broker listens on.
74
- # @option settings [String] :vhost ("/") Virtual host to use.
75
- # @option settings [String] :user ("guest") Username to use for authentication.
76
- # @option settings [String] :pass ("guest") Password to use for authentication.
77
- # @option settings [String] :ssl (false) Should be use TLS (SSL) for connection?
78
- # @option settings [String] :timeout (nil) Connection timeout.
79
- # @option settings [String] :logging (false) Turns logging on or off.
80
- # @option settings [String] :broker (nil) Broker name (use if you intend to use broker-specific features).
81
- # @option settings [Fixnum] :frame_max (131072) Maximum frame size to use. If broker cannot support frames this large, broker's maximum value will be used instead.
82
- #
83
- # @return [Hash] Merged configuration parameters.
84
- def self.configure(settings = nil)
85
- case settings
86
- when Hash then
87
- if username = settings.delete(:username)
88
- settings[:user] ||= username
89
- end
90
-
91
- if password = settings.delete(:password)
92
- settings[:pass] ||= password
93
- end
94
-
95
-
96
- self.default.merge(settings)
97
- when String then
98
- settings = self.parse_amqp_url(settings)
99
- self.default.merge(settings)
100
- when NilClass then
101
- self.default
102
- end
103
- end
104
-
105
- # Parses AMQP connection URI and returns its components as a hash.
106
- #
107
- # h2. vhost naming schemes
108
- #
109
- # It is convenient to be able to specify the AMQP connection
110
- # parameters as a URI string, and various "amqp" URI schemes
111
- # exist. Unfortunately, there is no standard for these URIs, so
112
- # while the schemes share the basic idea, they differ in some
113
- # details. This implementation aims to encourage URIs that work
114
- # as widely as possible.
115
- #
116
- # The URI scheme should be "amqp", or "amqps" if SSL is required.
117
- #
118
- # The host, port, username and password are represented in the
119
- # authority component of the URI in the same way as in http URIs.
120
- #
121
- # The vhost is obtained from the first segment of the path, with the
122
- # leading slash removed. The path should contain only a single
123
- # segment (i.e, the only slash in it should be the leading one).
124
- # If the vhost is to include slashes or other reserved URI
125
- # characters, these should be percent-escaped.
126
- #
127
- # @example How vhost is parsed
128
- #
129
- # AMQ::Client::Settings.parse_amqp_url("amqp://dev.rabbitmq.com") # => vhost is nil, so default (/) will be used
130
- # AMQ::Client::Settings.parse_amqp_url("amqp://dev.rabbitmq.com/") # => vhost is an empty string
131
- # AMQ::Client::Settings.parse_amqp_url("amqp://dev.rabbitmq.com/%2Fvault") # => vhost is /vault
132
- # AMQ::Client::Settings.parse_amqp_url("amqp://dev.rabbitmq.com/production") # => vhost is production
133
- # AMQ::Client::Settings.parse_amqp_url("amqp://dev.rabbitmq.com/a.b.c") # => vhost is a.b.c
134
- # AMQ::Client::Settings.parse_amqp_url("amqp://dev.rabbitmq.com/foo/bar") # => ArgumentError
135
- #
136
- #
137
- # @param [String] connection_string AMQP connection URI, à la JDBC connection string. For example: amqp://bus.megacorp.internal:5877.
138
- # @return [Hash] Connection parameters (:username, :password, :vhost, :host, :port, :ssl)
139
- #
140
- # @raise [ArgumentError] When connection URI schema is not amqp or amqps, or the path contains multiple segments
141
- #
142
- # @see http://bit.ly/ks8MXK Connecting to The Broker documentation guide
143
- # @api public
144
- def self.parse_amqp_url(connection_string)
145
- uri = URI.parse(connection_string)
146
- raise ArgumentError.new("Connection URI must use amqp or amqps schema (example: amqp://bus.megacorp.internal:5766), learn more at http://bit.ly/ks8MXK") unless %w{amqp amqps}.include?(uri.scheme)
147
-
148
- opts = {}
149
-
150
- opts[:scheme] = uri.scheme
151
- opts[:user] = URI.unescape(uri.user) if uri.user
152
- opts[:pass] = URI.unescape(uri.password) if uri.password
153
- opts[:host] = uri.host if uri.host
154
- opts[:port] = uri.port || AMQ::Client::Settings::AMQP_PORTS[uri.scheme]
155
- opts[:ssl] = uri.scheme == AMQ::Client::Settings::AMQPS
156
- if uri.path =~ %r{^/(.*)}
157
- raise ArgumentError.new("#{uri} has multiple-segment path; please percent-encode any slashes in the vhost name (e.g. /production => %2Fproduction). Learn more at http://bit.ly/amqp-gem-and-connection-uris") if $1.index('/')
158
- opts[:vhost] = URI.unescape($1)
159
- end
160
-
161
- opts
162
- end
163
- end
164
- end
165
- end
@@ -1,20 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Qrack
4
- # Channel ancestor class
5
- class Channel
6
-
7
- attr_accessor :number, :active, :frame_buffer
8
- attr_reader :client
9
-
10
- def initialize(client)
11
- @frame_buffer = []
12
- @client = client
13
- @number = client.channels.size
14
- @active = false
15
- client.channels[@number] = self
16
- end
17
-
18
- end
19
-
20
- end
@@ -1,247 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require "qrack/amq-client-url"
4
-
5
- module Qrack
6
-
7
- class ClientTimeout < Timeout::Error; end
8
- class ConnectionTimeout < Timeout::Error; end
9
- class FrameTimeout < Timeout::Error; end
10
-
11
- # Client ancestor class
12
- class Client
13
-
14
- CONNECT_TIMEOUT = 5.0
15
- RETRY_DELAY = 10.0
16
-
17
- attr_reader :status, :host, :vhost, :port, :logging, :spec, :heartbeat, :last_method
18
- attr_accessor :channel, :logfile, :exchanges, :queues, :channels, :message_in, :message_out, :connecting
19
-
20
-
21
- def initialize(connection_string_or_opts = Hash.new, opts = Hash.new)
22
- opts = case connection_string_or_opts
23
- when String then
24
- AMQ::Client::Settings.parse_amqp_url(connection_string_or_opts)
25
- when Hash then
26
- connection_string_or_opts
27
- else
28
- Hash.new
29
- end.merge(opts)
30
-
31
- @host = opts[:host] || 'localhost'
32
- @port = opts[:port] || (opts[:ssl] ? Qrack::Protocol::SSL_PORT : Qrack::Protocol::PORT)
33
- @user = opts[:user] || 'guest'
34
- @pass = opts[:pass] || 'guest'
35
- @vhost = opts[:vhost] || '/'
36
- @logfile = opts[:logfile] || nil
37
- @logging = opts[:logging] || false
38
- @ssl = opts[:ssl] || false
39
- @ssl_cert = opts[:ssl_cert] || nil
40
- @ssl_key = opts[:ssl_key] || nil
41
- @ssl_cert_string = opts[:ssl_cert_string] || nil
42
- @ssl_key_string = opts[:ssl_key_string] || nil
43
- @verify_ssl = opts[:verify_ssl].nil? || opts[:verify_ssl]
44
- @status = :not_connected
45
- @frame_max = opts[:frame_max] || 131072
46
- @channel_max = opts[:channel_max] || 0
47
- @heartbeat = opts[:heartbeat] || 0
48
- @connect_timeout = opts[:connect_timeout] || CONNECT_TIMEOUT
49
- @read_write_timeout = opts[:socket_timeout]
50
- @read_write_timeout = nil if @read_write_timeout == 0
51
- @disconnect_timeout = @read_write_timeout || @connect_timeout
52
- @logger = nil
53
- create_logger if @logging
54
- @message_in = false
55
- @message_out = false
56
- @last_method = nil
57
- @connecting = false
58
- @channels ||= []
59
- # Create channel 0
60
- @channel = create_channel()
61
- @exchanges ||= {}
62
- @queues ||= {}
63
- end
64
-
65
-
66
- # Closes all active communication channels and connection. If an error occurs a @Bunny::ProtocolError@ is raised. If successful, @Client.status@ is set to @:not_connected@.
67
-
68
- # @return [Symbol] @:not_connected@ if successful.
69
- def close
70
- return if @socket.nil? || @socket.closed?
71
-
72
- # Close all active channels
73
- channels.each do |c|
74
- Bunny::Timer::timeout(@disconnect_timeout) { c.close } if c.open?
75
- end
76
-
77
- # Close connection to AMQP server
78
- Bunny::Timer::timeout(@disconnect_timeout) { close_connection }
79
-
80
- rescue Exception
81
- # http://cheezburger.com/Asset/View/4033311488
82
- ensure
83
- # Clear the channels
84
- @channels = []
85
-
86
- # Create channel 0
87
- @channel = create_channel()
88
-
89
- # Close TCP Socket
90
- close_socket
91
- end
92
-
93
- alias stop close
94
-
95
- def connected?
96
- status == :connected
97
- end
98
-
99
- def connecting?
100
- connecting
101
- end
102
-
103
- def logging=(bool)
104
- @logging = bool
105
- create_logger if @logging
106
- end
107
-
108
- def next_payload(options = {})
109
- res = next_frame(options)
110
- res.payload if res
111
- end
112
-
113
- alias next_method next_payload
114
-
115
- def read(*args)
116
- send_command(:read, *args)
117
- # Got a SIGINT while waiting; give any traps a chance to run
118
- rescue Errno::EINTR
119
- retry
120
- end
121
-
122
- # Checks to see whether or not an undeliverable message has been returned as a result of a publish
123
- # with the <tt>:immediate</tt> or <tt>:mandatory</tt> options.
124
-
125
- # @param [Hash] opts Options.
126
- # @option opts [Numeric] :timeout (0.1) The method will wait for a return message until this timeout interval is reached.
127
- # @return [Hash] @{:header => nil, :payload => :no_return, :return_details => nil}@ if message is not returned before timeout. @{:header, :return_details, :payload}@ if message is returned. @:return_details@ is a hash @{:reply_code, :reply_text, :exchange, :routing_key}@.
128
- def returned_message(opts = {})
129
-
130
- begin
131
- frame = next_frame(:timeout => opts[:timeout] || 0.1)
132
- rescue Qrack::FrameTimeout
133
- return {:header => nil, :payload => :no_return, :return_details => nil}
134
- end
135
-
136
- method = frame.payload
137
- header = next_payload
138
-
139
- # If maximum frame size is smaller than message payload body then message
140
- # will have a message header and several message bodies
141
- msg = ''
142
- while msg.length < header.size
143
- msg << next_payload
144
- end
145
-
146
- # Return the message and related info
147
- {:header => header, :payload => msg, :return_details => method.arguments}
148
- end
149
-
150
- def switch_channel(chann)
151
- if (0...channels.size).include? chann
152
- @channel = channels[chann]
153
- chann
154
- else
155
- raise RuntimeError, "Invalid channel number - #{chann}"
156
- end
157
- end
158
-
159
- def write(*args)
160
- send_command(:write, *args)
161
- end
162
-
163
- def read_ready?(timeout, cancelator = nil)
164
- io = IO.select([ @socket, cancelator ].compact, nil, nil, timeout)
165
- io and io[0].include?(@socket)
166
- end
167
-
168
- private
169
-
170
- def close_socket(reason=nil)
171
- # Close the socket. The server is not considered dead.
172
- @socket.close if @socket and not @socket.closed?
173
- @socket = nil
174
- @status = :not_connected
175
- end
176
-
177
- def create_logger
178
- @logfile ? @logger = Logger.new("#{logfile}") : @logger = Logger.new(STDOUT)
179
- @logger.level = Logger::INFO
180
- @logger.datetime_format = "%Y-%m-%d %H:%M:%S"
181
- end
182
-
183
- def send_command(cmd, *args)
184
- begin
185
- raise Bunny::ConnectionError, 'No connection - socket has not been created' if !@socket
186
- if @read_write_timeout
187
- Bunny::Timer::timeout(@read_write_timeout, Qrack::ClientTimeout) do
188
- @socket.__send__(cmd, *args)
189
- end
190
- else
191
- @socket.__send__(cmd, *args)
192
- end
193
- rescue Errno::EPIPE, Errno::EAGAIN, Qrack::ClientTimeout, IOError => e
194
- # Ensure we close the socket when we are down to prevent further
195
- # attempts to write to a closed socket
196
- close_socket
197
- raise Bunny::ServerDownError, e.message
198
- end
199
- end
200
-
201
- def socket
202
- return @socket if @socket and (@status == :connected) and not @socket.closed?
203
-
204
- begin
205
- # Attempt to connect.
206
- @socket = Bunny::Timer::timeout(@connect_timeout, ConnectionTimeout) do
207
- TCPSocket.new(host, port)
208
- end
209
-
210
- if Socket.constants.include?('TCP_NODELAY') || Socket.constants.include?(:TCP_NODELAY)
211
- @socket.setsockopt Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1
212
- end
213
-
214
- if @ssl
215
- require 'openssl' unless defined? OpenSSL::SSL
216
- sslctx = OpenSSL::SSL::SSLContext.new
217
- initialize_client_pair(sslctx)
218
- @socket = OpenSSL::SSL::SSLSocket.new(@socket, sslctx)
219
- @socket.sync_close = true
220
- @socket.connect
221
- @socket.post_connection_check(host) if @verify_ssl
222
- @socket
223
- end
224
- rescue => e
225
- @status = :not_connected
226
- raise Bunny::ServerDownError, e.message
227
- end
228
-
229
- @socket
230
- end
231
-
232
- def initialize_client_pair(sslctx)
233
- if @ssl_cert
234
- @ssl_cert_string = File.read(@ssl_cert)
235
- end
236
- if @ssl_key
237
- @ssl_key_string = File.read(@ssl_key)
238
- end
239
-
240
- sslctx.cert = OpenSSL::X509::Certificate.new(@ssl_cert_string) if @ssl_cert_string
241
- sslctx.key = OpenSSL::PKey::RSA.new(@ssl_key_string) if @ssl_key_string
242
- sslctx
243
- end
244
-
245
- end
246
-
247
- end