amq-protocol 1.0.0.pre7 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitmodules +2 -2
- data/ChangeLog.md +23 -0
- data/LICENSE +1 -0
- data/README.md +21 -10
- data/{__init__.py → codegen/__init__.py} +0 -0
- data/{amqp_0.9.1_changes.json → codegen/amqp_0.9.1_changes.json} +0 -0
- data/{codegen.py → codegen/codegen.py} +3 -3
- data/{codegen_helpers.py → codegen/codegen_helpers.py} +0 -0
- data/{protocol.rb.pytemplate → codegen/protocol.rb.pytemplate} +4 -2
- data/generate.rb +3 -3
- data/lib/amq/protocol/client.rb +234 -97
- data/lib/amq/protocol/frame.rb +2 -1
- data/lib/amq/protocol/version.rb +1 -1
- data/lib/amq/settings.rb +132 -0
- data/spec/amq/protocol/constants_spec.rb +14 -0
- data/spec/amq/settings_spec.rb +116 -0
- metadata +66 -80
- data/irb.rb +0 -98
- data/post-processing.rb +0 -25
data/lib/amq/protocol/frame.rb
CHANGED
@@ -42,7 +42,8 @@ This functionality is part of the https://github.com/ruby-amqp/amq-client librar
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def self.decode_header(header)
|
45
|
-
raise EmptyResponseError if header == nil
|
45
|
+
raise EmptyResponseError if header == nil || header.empty?
|
46
|
+
|
46
47
|
type_id, channel, size = header.unpack(PACK_CHAR_UINT16_UINT32)
|
47
48
|
type = TYPES_REVERSE[type_id]
|
48
49
|
raise FrameTypeError.new(TYPES_OPTIONS) unless type
|
data/lib/amq/protocol/version.rb
CHANGED
data/lib/amq/settings.rb
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "amq/protocol/client"
|
4
|
+
require "uri"
|
5
|
+
|
6
|
+
module AMQ
|
7
|
+
module Settings
|
8
|
+
# @private
|
9
|
+
AMQP_PORTS = {"amqp" => 5672, "amqps" => 5671}.freeze
|
10
|
+
|
11
|
+
# @private
|
12
|
+
AMQPS = "amqps".freeze
|
13
|
+
|
14
|
+
# Default connection settings used by AMQ clients
|
15
|
+
#
|
16
|
+
# @see AMQ::Client::Settings.configure
|
17
|
+
def self.default
|
18
|
+
@default ||= {
|
19
|
+
# server
|
20
|
+
:host => "127.0.0.1",
|
21
|
+
:port => AMQ::Protocol::DEFAULT_PORT,
|
22
|
+
|
23
|
+
# login
|
24
|
+
:user => "guest",
|
25
|
+
:pass => "guest",
|
26
|
+
:vhost => "/",
|
27
|
+
|
28
|
+
# ssl
|
29
|
+
:ssl => false,
|
30
|
+
|
31
|
+
:frame_max => (128 * 1024),
|
32
|
+
:heartbeat => 0
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
# Merges given configuration parameters with defaults and returns
|
38
|
+
# the result.
|
39
|
+
#
|
40
|
+
# @param [Hash] Configuration parameters to use.
|
41
|
+
#
|
42
|
+
# @option settings [String] :host ("127.0.0.1") Hostname AMQ broker runs on.
|
43
|
+
# @option settings [String] :port (5672) Port AMQ broker listens on.
|
44
|
+
# @option settings [String] :vhost ("/") Virtual host to use.
|
45
|
+
# @option settings [String] :user ("guest") Username to use for authentication.
|
46
|
+
# @option settings [String] :pass ("guest") Password to use for authentication.
|
47
|
+
# @option settings [String] :ssl (false) Should be use TLS (SSL) for connection?
|
48
|
+
# @option settings [String] :timeout (nil) Connection timeout.
|
49
|
+
# @option settings [String] :broker (nil) Broker name (use if you intend to use broker-specific features).
|
50
|
+
# @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.
|
51
|
+
#
|
52
|
+
# @return [Hash] Merged configuration parameters.
|
53
|
+
def self.configure(settings = nil)
|
54
|
+
case settings
|
55
|
+
when Hash then
|
56
|
+
if username = (settings.delete(:username) || settings.delete(:user))
|
57
|
+
settings[:user] ||= username
|
58
|
+
end
|
59
|
+
|
60
|
+
if password = (settings.delete(:password) || settings.delete(:pass))
|
61
|
+
settings[:pass] ||= password
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
self.default.merge(settings)
|
66
|
+
when String then
|
67
|
+
settings = self.parse_amqp_url(settings)
|
68
|
+
self.default.merge(settings)
|
69
|
+
when NilClass then
|
70
|
+
self.default
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Parses AMQP connection URI and returns its components as a hash.
|
75
|
+
#
|
76
|
+
# h2. vhost naming schemes
|
77
|
+
#
|
78
|
+
# It is convenient to be able to specify the AMQP connection
|
79
|
+
# parameters as a URI string, and various "amqp" URI schemes
|
80
|
+
# exist. Unfortunately, there is no standard for these URIs, so
|
81
|
+
# while the schemes share the basic idea, they differ in some
|
82
|
+
# details. This implementation aims to encourage URIs that work
|
83
|
+
# as widely as possible.
|
84
|
+
#
|
85
|
+
# The URI scheme should be "amqp", or "amqps" if SSL is required.
|
86
|
+
#
|
87
|
+
# The host, port, username and password are represented in the
|
88
|
+
# authority component of the URI in the same way as in http URIs.
|
89
|
+
#
|
90
|
+
# The vhost is obtained from the first segment of the path, with the
|
91
|
+
# leading slash removed. The path should contain only a single
|
92
|
+
# segment (i.e, the only slash in it should be the leading one).
|
93
|
+
# If the vhost is to include slashes or other reserved URI
|
94
|
+
# characters, these should be percent-escaped.
|
95
|
+
#
|
96
|
+
# @example How vhost is parsed
|
97
|
+
#
|
98
|
+
# AMQ::Settings.parse_amqp_url("amqp://dev.rabbitmq.com") # => vhost is nil, so default (/) will be used
|
99
|
+
# AMQ::Settings.parse_amqp_url("amqp://dev.rabbitmq.com/") # => vhost is an empty string
|
100
|
+
# AMQ::Settings.parse_amqp_url("amqp://dev.rabbitmq.com/%2Fvault") # => vhost is /vault
|
101
|
+
# AMQ::Settings.parse_amqp_url("amqp://dev.rabbitmq.com/production") # => vhost is production
|
102
|
+
# AMQ::Settings.parse_amqp_url("amqp://dev.rabbitmq.com/a.b.c") # => vhost is a.b.c
|
103
|
+
# AMQ::Settings.parse_amqp_url("amqp://dev.rabbitmq.com/foo/bar") # => ArgumentError
|
104
|
+
#
|
105
|
+
#
|
106
|
+
# @param [String] connection_string AMQP connection URI, à la JDBC connection string. For example: amqp://bus.megacorp.internal:5877.
|
107
|
+
# @return [Hash] Connection parameters (:username, :password, :vhost, :host, :port, :ssl)
|
108
|
+
#
|
109
|
+
# @raise [ArgumentError] When connection URI schema is not amqp or amqps, or the path contains multiple segments
|
110
|
+
#
|
111
|
+
# @api public
|
112
|
+
def self.parse_amqp_url(connection_string)
|
113
|
+
uri = URI.parse(connection_string)
|
114
|
+
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)
|
115
|
+
|
116
|
+
opts = {}
|
117
|
+
|
118
|
+
opts[:scheme] = uri.scheme
|
119
|
+
opts[:user] = URI.unescape(uri.user) if uri.user
|
120
|
+
opts[:pass] = URI.unescape(uri.password) if uri.password
|
121
|
+
opts[:host] = uri.host if uri.host
|
122
|
+
opts[:port] = uri.port || AMQP_PORTS[uri.scheme]
|
123
|
+
opts[:ssl] = uri.scheme.to_s.downcase =~ /amqps/i
|
124
|
+
if uri.path =~ %r{^/(.*)}
|
125
|
+
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('/')
|
126
|
+
opts[:vhost] = URI.unescape($1)
|
127
|
+
end
|
128
|
+
|
129
|
+
opts
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# encoding: binary
|
2
|
+
|
3
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
4
|
+
|
5
|
+
describe "(Some)", AMQ::Protocol, "constants" do
|
6
|
+
it "include regular port" do
|
7
|
+
AMQ::Protocol::DEFAULT_PORT.should == 5672
|
8
|
+
end
|
9
|
+
|
10
|
+
it "provides TLS/SSL port" do
|
11
|
+
AMQ::Protocol::TLS_PORT.should == 5671
|
12
|
+
AMQ::Protocol::SSL_PORT.should == 5671
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
require "amq/settings"
|
5
|
+
|
6
|
+
describe AMQ::Settings do
|
7
|
+
describe ".default" do
|
8
|
+
it "should provide some default values" do
|
9
|
+
AMQ::Settings.default.should_not be_nil
|
10
|
+
AMQ::Settings.default[:host].should_not be_nil
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe ".configure(&block)" do
|
15
|
+
it "should merge custom settings with default settings" do
|
16
|
+
settings = AMQ::Settings.configure(:host => "tagadab")
|
17
|
+
settings[:host].should eql("tagadab")
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should merge custom settings from AMQP URL with default settings" do
|
21
|
+
settings = AMQ::Settings.configure("amqp://tagadab")
|
22
|
+
settings[:host].should eql("tagadab")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe ".parse_amqp_url(connection_string)" do
|
27
|
+
context "when schema is not one of [amqp, amqps]" do
|
28
|
+
it "raises ArgumentError" do
|
29
|
+
expect {
|
30
|
+
described_class.parse_amqp_url("http://dev.rabbitmq.com")
|
31
|
+
}.to raise_error(ArgumentError, /amqp or amqps schema/)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
it "handles amqp:// URIs w/o path part" do
|
37
|
+
val = described_class.parse_amqp_url("amqp://dev.rabbitmq.com")
|
38
|
+
|
39
|
+
val[:vhost].should be_nil # in this case, default / will be used
|
40
|
+
val[:host].should == "dev.rabbitmq.com"
|
41
|
+
val[:port].should == 5672
|
42
|
+
val[:scheme].should == "amqp"
|
43
|
+
val[:ssl].should be_false
|
44
|
+
end
|
45
|
+
|
46
|
+
it "handles amqps:// URIs w/o path part" do
|
47
|
+
val = described_class.parse_amqp_url("amqps://dev.rabbitmq.com")
|
48
|
+
|
49
|
+
val[:vhost].should be_nil
|
50
|
+
val[:host].should == "dev.rabbitmq.com"
|
51
|
+
val[:port].should == 5671
|
52
|
+
val[:scheme].should == "amqps"
|
53
|
+
val[:ssl].should be_true
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
context "when URI ends in a slash" do
|
58
|
+
it "parses vhost as an empty string" do
|
59
|
+
val = described_class.parse_amqp_url("amqp://dev.rabbitmq.com/")
|
60
|
+
|
61
|
+
val[:host].should == "dev.rabbitmq.com"
|
62
|
+
val[:port].should == 5672
|
63
|
+
val[:scheme].should == "amqp"
|
64
|
+
val[:ssl].should be_false
|
65
|
+
val[:vhost].should == ""
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
context "when URI ends in /%2Fvault" do
|
71
|
+
it "parses vhost as /vault" do
|
72
|
+
val = described_class.parse_amqp_url("amqp://dev.rabbitmq.com/%2Fvault")
|
73
|
+
|
74
|
+
val[:host].should == "dev.rabbitmq.com"
|
75
|
+
val[:port].should == 5672
|
76
|
+
val[:scheme].should == "amqp"
|
77
|
+
val[:ssl].should be_false
|
78
|
+
val[:vhost].should == "/vault"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
context "when URI is amqp://dev.rabbitmq.com/a.path.without.slashes" do
|
84
|
+
it "parses vhost as a.path.without.slashes" do
|
85
|
+
val = described_class.parse_amqp_url("amqp://dev.rabbitmq.com/a.path.without.slashes")
|
86
|
+
|
87
|
+
val[:host].should == "dev.rabbitmq.com"
|
88
|
+
val[:port].should == 5672
|
89
|
+
val[:scheme].should == "amqp"
|
90
|
+
val[:ssl].should be_false
|
91
|
+
val[:vhost].should == "a.path.without.slashes"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context "when URI is amqp://dev.rabbitmq.com/a/path/with/slashes" do
|
96
|
+
it "raises an ArgumentError" do
|
97
|
+
lambda { described_class.parse_amqp_url("amqp://dev.rabbitmq.com/a/path/with/slashes") }.should raise_error(ArgumentError)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
context "when URI has username:password, for instance, amqp://hedgehog:t0ps3kr3t@hub.megacorp.internal" do
|
103
|
+
it "parses them out" do
|
104
|
+
val = described_class.parse_amqp_url("amqp://hedgehog:t0ps3kr3t@hub.megacorp.internal")
|
105
|
+
|
106
|
+
val[:host].should == "hub.megacorp.internal"
|
107
|
+
val[:port].should == 5672
|
108
|
+
val[:scheme].should == "amqp"
|
109
|
+
val[:ssl].should be_false
|
110
|
+
val[:user].should == "hedgehog"
|
111
|
+
val[:pass].should == "t0ps3kr3t"
|
112
|
+
val[:vhost].should be_nil # in this case, default / will be used
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
metadata
CHANGED
@@ -1,113 +1,100 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: amq-protocol
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
segments:
|
7
|
-
- 1
|
8
|
-
- 0
|
9
|
-
- 0
|
10
|
-
- pre
|
11
|
-
- 7
|
12
|
-
version: 1.0.0.pre7
|
4
|
+
prerelease:
|
5
|
+
version: 1.0.0
|
13
6
|
platform: ruby
|
14
7
|
authors:
|
15
|
-
- Jakub Stastny
|
16
|
-
- Michael S. Klishin
|
17
|
-
- Theo Hultberg
|
18
|
-
- Mark Abramov
|
8
|
+
- Jakub Stastny
|
9
|
+
- Michael S. Klishin
|
10
|
+
- Theo Hultberg
|
11
|
+
- Mark Abramov
|
19
12
|
autorequire:
|
20
13
|
bindir: bin
|
21
14
|
cert_chain: []
|
22
15
|
|
23
|
-
date: 2012-
|
16
|
+
date: 2012-11-27 00:00:00 Z
|
24
17
|
dependencies: []
|
25
18
|
|
26
19
|
description: " amq-protocol is an AMQP 0.9.1 serialization library for Ruby. It is not an\n AMQP client: amq-protocol only handles serialization and deserialization.\n If you want to write your own AMQP client, this gem can help you with that.\n"
|
27
20
|
email:
|
28
|
-
- michael@novemberain.com
|
29
|
-
- stastny@101ideas.cz
|
21
|
+
- michael@novemberain.com
|
22
|
+
- stastny@101ideas.cz
|
30
23
|
executables: []
|
31
24
|
|
32
25
|
extensions: []
|
33
26
|
|
34
27
|
extra_rdoc_files:
|
35
|
-
- README.md
|
28
|
+
- README.md
|
36
29
|
files:
|
37
|
-
- .gitignore
|
38
|
-
- .gitmodules
|
39
|
-
- .rspec
|
40
|
-
- .travis.yml
|
41
|
-
-
|
42
|
-
-
|
43
|
-
-
|
44
|
-
-
|
45
|
-
-
|
46
|
-
- amq-protocol.gemspec
|
47
|
-
-
|
48
|
-
- codegen.
|
49
|
-
-
|
50
|
-
-
|
51
|
-
-
|
52
|
-
-
|
53
|
-
- lib/amq/
|
54
|
-
- lib/amq/
|
55
|
-
- lib/amq/
|
56
|
-
- lib/amq/protocol
|
57
|
-
- lib/amq/protocol/
|
58
|
-
- lib/amq/protocol/
|
59
|
-
- lib/amq/protocol/
|
60
|
-
- lib/amq/protocol/
|
61
|
-
- lib/amq/protocol/
|
62
|
-
- lib/amq/protocol/
|
63
|
-
-
|
64
|
-
-
|
65
|
-
- spec/amq/bit_set_spec.rb
|
66
|
-
- spec/amq/hacks_spec.rb
|
67
|
-
- spec/amq/int_allocator_spec.rb
|
68
|
-
- spec/amq/protocol/basic_spec.rb
|
69
|
-
- spec/amq/protocol/blank_body_encoding_spec.rb
|
70
|
-
- spec/amq/protocol/channel_spec.rb
|
71
|
-
- spec/amq/protocol/confirm_spec.rb
|
72
|
-
- spec/amq/protocol/connection_spec.rb
|
73
|
-
- spec/amq/protocol/
|
74
|
-
- spec/amq/protocol/
|
75
|
-
- spec/amq/protocol/
|
76
|
-
- spec/amq/protocol/
|
77
|
-
- spec/amq/protocol/
|
78
|
-
- spec/amq/protocol/
|
79
|
-
- spec/amq/protocol/
|
80
|
-
- spec/amq/protocol/
|
81
|
-
- spec/amq/
|
82
|
-
- spec/
|
30
|
+
- .gitignore
|
31
|
+
- .gitmodules
|
32
|
+
- .rspec
|
33
|
+
- .travis.yml
|
34
|
+
- ChangeLog.md
|
35
|
+
- Gemfile
|
36
|
+
- LICENSE
|
37
|
+
- PROFILING.md
|
38
|
+
- README.md
|
39
|
+
- amq-protocol.gemspec
|
40
|
+
- codegen/__init__.py
|
41
|
+
- codegen/amqp_0.9.1_changes.json
|
42
|
+
- codegen/codegen.py
|
43
|
+
- codegen/codegen_helpers.py
|
44
|
+
- codegen/protocol.rb.pytemplate
|
45
|
+
- generate.rb
|
46
|
+
- lib/amq/bit_set.rb
|
47
|
+
- lib/amq/hacks.rb
|
48
|
+
- lib/amq/int_allocator.rb
|
49
|
+
- lib/amq/protocol.rb
|
50
|
+
- lib/amq/protocol/client.rb
|
51
|
+
- lib/amq/protocol/frame.rb
|
52
|
+
- lib/amq/protocol/table.rb
|
53
|
+
- lib/amq/protocol/table_value_decoder.rb
|
54
|
+
- lib/amq/protocol/table_value_encoder.rb
|
55
|
+
- lib/amq/protocol/type_constants.rb
|
56
|
+
- lib/amq/protocol/version.rb
|
57
|
+
- lib/amq/settings.rb
|
58
|
+
- spec/amq/bit_set_spec.rb
|
59
|
+
- spec/amq/hacks_spec.rb
|
60
|
+
- spec/amq/int_allocator_spec.rb
|
61
|
+
- spec/amq/protocol/basic_spec.rb
|
62
|
+
- spec/amq/protocol/blank_body_encoding_spec.rb
|
63
|
+
- spec/amq/protocol/channel_spec.rb
|
64
|
+
- spec/amq/protocol/confirm_spec.rb
|
65
|
+
- spec/amq/protocol/connection_spec.rb
|
66
|
+
- spec/amq/protocol/constants_spec.rb
|
67
|
+
- spec/amq/protocol/exchange_spec.rb
|
68
|
+
- spec/amq/protocol/frame_spec.rb
|
69
|
+
- spec/amq/protocol/method_spec.rb
|
70
|
+
- spec/amq/protocol/queue_spec.rb
|
71
|
+
- spec/amq/protocol/table_spec.rb
|
72
|
+
- spec/amq/protocol/tx_spec.rb
|
73
|
+
- spec/amq/protocol/value_decoder_spec.rb
|
74
|
+
- spec/amq/protocol/value_encoder_spec.rb
|
75
|
+
- spec/amq/protocol_spec.rb
|
76
|
+
- spec/amq/settings_spec.rb
|
77
|
+
- spec/spec_helper.rb
|
83
78
|
homepage: http://github.com/ruby-amqp/amq-protocol
|
84
79
|
licenses:
|
85
|
-
- MIT
|
80
|
+
- MIT
|
86
81
|
post_install_message:
|
87
82
|
rdoc_options: []
|
88
83
|
|
89
84
|
require_paths:
|
90
|
-
- lib
|
85
|
+
- lib
|
91
86
|
required_ruby_version: !ruby/object:Gem::Requirement
|
92
87
|
none: false
|
93
88
|
requirements:
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
segments:
|
98
|
-
- 0
|
99
|
-
version: "0"
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: "0"
|
100
92
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
93
|
none: false
|
102
94
|
requirements:
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
segments:
|
107
|
-
- 1
|
108
|
-
- 3
|
109
|
-
- 1
|
110
|
-
version: 1.3.1
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: "0"
|
111
98
|
requirements: []
|
112
99
|
|
113
100
|
rubyforge_project: amq-protocol
|
@@ -117,4 +104,3 @@ specification_version: 3
|
|
117
104
|
summary: AMQP 0.9.1 encoder & decoder.
|
118
105
|
test_files: []
|
119
106
|
|
120
|
-
has_rdoc:
|