You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ac...@apache.org on 2017/11/22 15:16:08 UTC
qpid-proton git commit: PROTON-1693: Update Qpid::Proton#uri parser
to allow "shortcut" URIs
Repository: qpid-proton
Updated Branches:
refs/heads/master 235f0a8aa -> b2adecde3
PROTON-1693: Update Qpid::Proton#uri parser to allow "shortcut" URIs
See the comment for details - allows shortcuts like to the pn_url() parser.
The standard URI parser extensions provided by the module allow for a strict,
standard parse of AMQP URIs if desired. The Container connect/listen functions
will allow shortcut strings, but won't modify already-parsed URIs (except to
add an amqp scheme to scheme-less URIs)
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/b2adecde
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/b2adecde
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/b2adecde
Branch: refs/heads/master
Commit: b2adecde31106361f2ad03a6ca84379e5bf3b2ed
Parents: 235f0a8
Author: Alan Conway <ac...@redhat.com>
Authored: Wed Nov 22 10:03:17 2017 -0500
Committer: Alan Conway <ac...@redhat.com>
Committed: Wed Nov 22 10:12:19 2017 -0500
----------------------------------------------------------------------
proton-c/bindings/ruby/lib/core/container.rb | 6 +-
proton-c/bindings/ruby/lib/core/uri.rb | 44 ++++++++++----
proton-c/bindings/ruby/lib/core/url.rb | 3 +-
proton-c/bindings/ruby/tests/test_uri.rb | 70 ++++++++++++++++++-----
4 files changed, 93 insertions(+), 30 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b2adecde/proton-c/bindings/ruby/lib/core/container.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/container.rb b/proton-c/bindings/ruby/lib/core/container.rb
index 6fbdbb5..38dcd74 100644
--- a/proton-c/bindings/ruby/lib/core/container.rb
+++ b/proton-c/bindings/ruby/lib/core/container.rb
@@ -32,8 +32,6 @@ module Qpid::Proton
class Container
private
- def amqp_uri(s) Qpid::Proton::amqp_uri s; end
-
# Container driver applies options and adds container context to events
class ConnectionTask < Qpid::Proton::HandlerDriver
def initialize container, io, opts, server=false
@@ -162,7 +160,7 @@ module Qpid::Proton
# @option (see Connection#open)
# @return [Connection] The new AMQP connection
def connect(url, opts = {})
- url = amqp_uri(url)
+ url = Qpid::Proton::uri(url)
opts[:user] ||= url.user
opts[:password] ||= url.password
# TODO aconway 2017-10-26: Use SSL for amqps URLs
@@ -187,7 +185,7 @@ module Qpid::Proton
# @return [Listener] The AMQP listener.
#
def listen(url, handler=Listener::Handler.new)
- url = amqp_uri(url)
+ url = Qpid::Proton::uri(url)
# TODO aconway 2017-11-01: amqps
listen_io(TCPServer.new(url.host, url.port), handler)
end
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b2adecde/proton-c/bindings/ruby/lib/core/uri.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/uri.rb b/proton-c/bindings/ruby/lib/core/uri.rb
index b29a719..aea1e6a 100644
--- a/proton-c/bindings/ruby/lib/core/uri.rb
+++ b/proton-c/bindings/ruby/lib/core/uri.rb
@@ -34,17 +34,37 @@ module URI
end
module Qpid::Proton
- # Convert s to an {URI::AMQP} or {URI::AMQPS}
- # @param s [String,URI] If s has no scheme, use the {URI::AMQP} scheme
- # @return [URI::AMQP]
- # @raise [BadURIError] If s has a scheme that is not "amqp" or "amqps"
- def self.amqp_uri(s)
- u = URI(s)
- u.host ||= "" # Behaves badly with nil host
- return u if u.is_a? URI::AMQP
- raise URI::BadURIError, "Not an AMQP URI: '#{u}'" if u.scheme
- u.scheme = "amqp" unless u.scheme
- u = URI::parse(u.to_s) # Re-parse with amqp scheme
- return u
+ # Returns +s+ converted to a {URI::AMQP} or {URI::AMQPS} object
+ #
+ # Shortcut strings are allowed: an "amqp://" prefix is added if +s+ does
+ # not already look like an 'amqp:', 'amqps:' URI.
+ #
+ # @note this does not give the same result as a standard URI parser in all cases.
+ # For standard conversion to a URI use: {#URI}(s)
+ #
+ # @param s [String,URI] String to convert to a URI, or a URI object.
+ # A URI object with no scheme will be converted to {URI::AMQP}
+ # @return [URI::AMQP] A valid {URI::AMQP} or {URI::AMQPS} object
+ # @raise [BadURIError] s is a URI object with a non-AMQP scheme
+ # @raise [InvalidURIError] s cannot be parsed as a URI or shortcut
+ # @raise [::ArgumentError] s is not a string or URI
+ #
+ def self.uri(s)
+ case s
+ when URI::AMQP then s # Pass-thru
+ when URI::Generic
+ s.scheme ||= 'amqp'
+ u = URI.parse(s.to_s) # Re-parse as amqp
+ raise URI::BadURIError, "Not an AMQP URI: '#{u}'" unless u.is_a? URI::AMQP
+ u
+ else
+ s = String.try_convert s
+ raise ::ArgumentError, "bad argument (expected URI object or URI string)" unless s
+ case s
+ when %r{^amqps?:} then URI.parse(s) # Looks like an AMQP URI
+ when %r{^//} then URI.parse("amqp:#{s}") # Looks like a scheme-less URI
+ else URI.parse("amqp://#{s}") # Treat as a bare host:port/path string
+ end
+ end
end
end
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b2adecde/proton-c/bindings/ruby/lib/core/url.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/url.rb b/proton-c/bindings/ruby/lib/core/url.rb
index b54df66..ff49053 100644
--- a/proton-c/bindings/ruby/lib/core/url.rb
+++ b/proton-c/bindings/ruby/lib/core/url.rb
@@ -32,6 +32,7 @@ module Qpid::Proton
# Parse a string, return a new URL
# @param url [#to_s] the URL string
def initialize(url = nil)
+ deprecated self.class, 'URI or String'
if url
@url = Cproton.pn_url_parse(url.to_s)
if @url.nil?
@@ -72,7 +73,7 @@ module Qpid::Proton
private
def defaults
- @scheme = @scheme || "ampq"
+ @scheme = @scheme || "amqp"
@host = @host || "0.0.0.0"
@port = @port || 5672
end
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b2adecde/proton-c/bindings/ruby/tests/test_uri.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/tests/test_uri.rb b/proton-c/bindings/ruby/tests/test_uri.rb
index e5279d8..2cfa3b7 100644
--- a/proton-c/bindings/ruby/tests/test_uri.rb
+++ b/proton-c/bindings/ruby/tests/test_uri.rb
@@ -22,19 +22,63 @@ require 'qpid_proton'
class TestURI < Minitest::Test
- def amqp_uri(u) Qpid::Proton::amqp_uri(u); end
-
- def test_amqp_uri
- assert_equal URI("amqp:").port, 5672
- assert_equal URI("amqps:").port, 5671
- assert_equal URI("amqp://user:pass@host:1234/path"), amqp_uri("//user:pass@host:1234/path")
- assert_equal URI("amqp://user:pass@host:1234/path"), amqp_uri("amqp://user:pass@host:1234/path")
- assert_equal URI("amqps://user:pass@host:1234/path"), amqp_uri("amqps://user:pass@host:1234/path")
- assert_equal URI("amqp://host:1234/path"), amqp_uri("//host:1234/path")
- assert_equal URI("amqp://host:1234"), amqp_uri("//host:1234")
- assert_equal URI("amqp://host"), amqp_uri("//host")
- assert_equal URI("amqp://:1234"), amqp_uri("//:1234")
- assert_raises(URI::BadURIError) { amqp_uri("http://foo") }
+ def uri(u) Qpid::Proton::uri(u); end
+
+ # Extension to standard URI parser
+ def test_standard
+ u = URI("amqp://u:p@h/x")
+ assert_equal URI::AMQP, u.class
+ assert_equal ['amqp', 'u:p', 'h', 5672, '/x'], u.select(:scheme, :userinfo, :host, :port, :path)
+
+ u = URI("amqps://u:p@h/x")
+ assert_equal URI::AMQPS, u.class
+ assert_equal ['amqps', 'u:p', 'h', 5671, '/x'], u.select(:scheme, :userinfo, :host, :port, :path)
+
+ assert_equal ['amqp', '[::1:2:3]', 5672], URI('amqp://[::1:2:3]').select(:scheme, :host, :port)
+ end
+
+ # Proton::uri on valid URIs
+ def test_valid
+ u = uri("amqp://u:p@h:1/x")
+ assert_equal URI::AMQP, u.class
+ assert_equal u.select(:scheme, :userinfo, :host, :port, :path), ['amqp', 'u:p', 'h', 1, '/x']
+
+ u = uri("amqps://u:p@h:1/x")
+ assert_equal URI::AMQPS, u.class
+ assert_equal u.select(:scheme, :userinfo, :host, :port, :path), ['amqps', 'u:p', 'h', 1, '/x']
+
+ # Schemeless string -> amqp
+ assert_equal URI("amqp://h:1/x"), uri("//h:1/x")
+ assert_equal URI("amqp:/x"), uri("/x")
+ assert_equal URI("amqp:"), uri("//")
+ assert_equal URI("amqp:"), uri("")
+ assert_equal URI("amqp://[::1]"), uri("//[::1]")
+
+ # Schemeless URI -> amqp, no re-parse for ambiguous case of path only
+ assert_equal URI("amqp:x"), uri(URI("x"))
+ assert_equal URI("amqp:/x"), uri(URI("/x"))
+
+ # Pass-through
+ u = uri('')
+ assert_same u, uri(u)
+ end
+
+ # Proton::uri non-standard shortcuts
+ def test_shortcut
+ assert_equal URI("amqp://u:p@h:1/x"), uri("u:p@h:1/x")
+ assert_equal URI("amqp://h:1"), uri("h:1")
+ assert_equal URI("amqp://h"), uri("h")
+ assert_equal URI("amqp://h"), uri("h:")
+ assert_equal URI("amqp://:1"), uri(":1")
+ assert_equal URI("amqp://[::1:2]:1"), uri("[::1:2]:1")
+ assert_equal URI("amqp://[::1:2]"), uri("[::1:2]")
+ end
+
+ def test_error
+ assert_raises(::ArgumentError) { uri(nil) }
+ assert_raises(URI::BadURIError) { uri(URI("http:x")) } # Don't re-parse a URI with wrong scheme
+ assert_raises(URI::InvalidURIError) { uri("x:y:z") } # Nonsense
+ assert_raises(URI::InvalidURIError) { uri("amqp://[foobar]") } # Bad host
end
end
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org