1 // Copyright (c) 2012, Sean Treadway, SoundCloud Ltd.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4 // Source code and contact info at http://github.com/streadway/amqp
16 var errURIScheme = errors.New("AMQP scheme must be either 'amqp://' or 'amqps://'")
17 var errURIWhitespace = errors.New("URI must not contain whitespace")
19 var schemePorts = map[string]int{
33 // URI represents a parsed AMQP URI string.
43 // ParseURI attempts to parse the given AMQP URI according to the spec.
44 // See http://www.rabbitmq.com/uri-spec.html.
46 // Default values for the fields are:
55 func ParseURI(uri string) (URI, error) {
58 if strings.Contains(uri, " ") == true {
59 return builder, errURIWhitespace
62 u, err := url.Parse(uri)
67 defaultPort, okScheme := schemePorts[u.Scheme]
70 builder.Scheme = u.Scheme
72 return builder, errURIScheme
83 port32, err := strconv.ParseInt(port, 10, 32)
87 builder.Port = int(port32)
89 builder.Port = defaultPort
93 builder.Username = u.User.Username()
94 if password, ok := u.User.Password(); ok {
95 builder.Password = password
100 if strings.HasPrefix(u.Path, "/") {
101 if u.Host == "" && strings.HasPrefix(u.Path, "///") {
102 // net/url doesn't handle local context authorities and leaves that up
103 // to the scheme handler. In our case, we translate amqp:/// into the
104 // default host and whatever the vhost should be
106 builder.Vhost = u.Path[3:]
108 } else if len(u.Path) > 1 {
109 builder.Vhost = u.Path[1:]
112 builder.Vhost = u.Path
119 // PlainAuth returns a PlainAuth structure based on the parsed URI's
120 // Username and Password fields.
121 func (uri URI) PlainAuth() *PlainAuth {
123 Username: uri.Username,
124 Password: uri.Password,
128 // AMQPlainAuth returns a PlainAuth structure based on the parsed URI's
129 // Username and Password fields.
130 func (uri URI) AMQPlainAuth() *AMQPlainAuth {
131 return &AMQPlainAuth{
132 Username: uri.Username,
133 Password: uri.Password,
137 func (uri URI) String() string {
138 authority, err := url.Parse("")
143 authority.Scheme = uri.Scheme
145 if uri.Username != defaultURI.Username || uri.Password != defaultURI.Password {
146 authority.User = url.User(uri.Username)
148 if uri.Password != defaultURI.Password {
149 authority.User = url.UserPassword(uri.Username, uri.Password)
153 authority.Host = net.JoinHostPort(uri.Host, strconv.Itoa(uri.Port))
155 if defaultPort, found := schemePorts[uri.Scheme]; !found || defaultPort != uri.Port {
156 authority.Host = net.JoinHostPort(uri.Host, strconv.Itoa(uri.Port))
158 // JoinHostPort() automatically add brackets to the host if it's
161 // If not port is specified, JoinHostPort() return an IP address in the
162 // form of "[::1]:", so we use TrimSuffix() to remove the extra ":".
163 authority.Host = strings.TrimSuffix(net.JoinHostPort(uri.Host, ""), ":")
166 if uri.Vhost != defaultURI.Vhost {
167 // Make sure net/url does not double escape, e.g.
168 // "%2F" does not become "%252F".
169 authority.Path = uri.Vhost
170 authority.RawPath = url.QueryEscape(uri.Vhost)
175 return authority.String()