qpid-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alan Conway <acon...@redhat.com>
Subject Re: svn commit: r1626329 - in /qpid/proton/trunk: proton-c/ proton-c/bindings/perl/ proton-c/bindings/php/ proton-c/bindings/python/ proton-c/bindings/ruby/ proton-c/include/proton/ proton-c/src/ tests/python/proton_tests/
Date Thu, 25 Sep 2014 14:00:44 GMT
On Wed, 2014-09-24 at 12:19 +0100, Robbie Gemmell wrote:
> The tests are now running again, but a couple of the URL tests still seem
> to be failing on the CI job:
> https://builds.apache.org/view/M-R/view/Qpid/job/Qpid-proton-j/lastBuild/org.apache.qpid$proton-tests/testReport/
> 

They are all failing with:
 Not a valid port number or service name: 'amqps'

Could this be a configuration problem on the CI machine, i.e. missing an
'amqps' entry in /etc/services? Can I get access to the CI machine to
poke around and see what's up?

The URL code uses socket.getservbyname() to look up service names. Is
there a more portable way to do it?

Cheers,
Alan.

> As mentioned in my other post about a timeline for dropping Java6 support,
> they seem to work on Java8 (havent tried Java7).
> 
> Robbie
> 
> On 22 September 2014 21:14, Alan Conway <aconway@redhat.com> wrote:
> 
> > My bad, didn't run the java tests. Will fix ASAP and then give myself a
> > flogging.
> >
> > On Mon, 2014-09-22 at 19:50 +0100, Robbie Gemmell wrote:
> > > This seems to have broken the Java test runs:
> > >
> > > https://builds.apache.org/view/M-R/view/Qpid/job/Qpid-proton-j/664/
> > >
> > >
> > >
> > > On 19 September 2014 22:00, <aconway@apache.org> wrote:
> > >
> > > > Author: aconway
> > > > Date: Fri Sep 19 21:00:50 2014
> > > > New Revision: 1626329
> > > >
> > > > URL: http://svn.apache.org/r1626329
> > > > Log:
> > > > PROTON-693: Python Url class to wrap C function pni_parse_url
> > > >
> > > > It was pointed out that pni_parse_url is an internal function and the
> > > > interface
> > > > is not suitable for public API.
> > > >
> > > > Rewrote the URL parser as a proper swigable C API pn_url_*. This gets
> > rid
> > > > of the
> > > > need for previous swig insanity and is cleaner all round.
> > > >
> > > > Internally still uses the pni_parse_url parser, we can clean that up
> > later.
> > > >
> > > > Added:
> > > >     qpid/proton/trunk/proton-c/include/proton/url.h
> > > >     qpid/proton/trunk/proton-c/src/url.c
> > > > Modified:
> > > >     qpid/proton/trunk/proton-c/CMakeLists.txt
> > > >     qpid/proton/trunk/proton-c/bindings/perl/perl.i
> > > >     qpid/proton/trunk/proton-c/bindings/php/php.i
> > > >     qpid/proton/trunk/proton-c/bindings/python/cproton.i
> > > >     qpid/proton/trunk/proton-c/bindings/python/proton.py
> > > >     qpid/proton/trunk/proton-c/bindings/ruby/ruby.i
> > > >     qpid/proton/trunk/proton-c/include/proton/cproton.i
> > > >     qpid/proton/trunk/tests/python/proton_tests/url.py
> > > >
> > > > Modified: qpid/proton/trunk/proton-c/CMakeLists.txt
> > > > URL:
> > > >
> > http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/CMakeLists.txt?rev=1626329&r1=1626328&r2=1626329&view=diff
> > > >
> > > >
> > ==============================================================================
> > > > --- qpid/proton/trunk/proton-c/CMakeLists.txt (original)
> > > > +++ qpid/proton/trunk/proton-c/CMakeLists.txt Fri Sep 19 21:00:50 2014
> > > > @@ -270,6 +270,7 @@ set (qpid-proton-core
> > > >    src/object/iterator.c
> > > >
> > > >    src/util.c
> > > > +  src/url.c
> > > >    src/error.c
> > > >    src/buffer.c
> > > >    src/parser.c
> > > >
> > > > Modified: qpid/proton/trunk/proton-c/bindings/perl/perl.i
> > > > URL:
> > > >
> > http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/bindings/perl/perl.i?rev=1626329&r1=1626328&r2=1626329&view=diff
> > > >
> > > >
> > ==============================================================================
> > > > --- qpid/proton/trunk/proton-c/bindings/perl/perl.i (original)
> > > > +++ qpid/proton/trunk/proton-c/bindings/perl/perl.i Fri Sep 19 21:00:50
> > > > 2014
> > > > @@ -8,6 +8,7 @@
> > > >  #include <proton/messenger.h>
> > > >  #include <proton/ssl.h>
> > > >  #include <proton/driver_extras.h>
> > > > +#include <proton/url.h>
> > > >  %}
> > > >
> > > >  %include <cstring.i>
> > > >
> > > > Modified: qpid/proton/trunk/proton-c/bindings/php/php.i
> > > > URL:
> > > >
> > http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/bindings/php/php.i?rev=1626329&r1=1626328&r2=1626329&view=diff
> > > >
> > > >
> > ==============================================================================
> > > > --- qpid/proton/trunk/proton-c/bindings/php/php.i (original)
> > > > +++ qpid/proton/trunk/proton-c/bindings/php/php.i Fri Sep 19 21:00:50
> > 2014
> > > > @@ -29,6 +29,7 @@
> > > >  %header %{
> > > >  /* Include the headers needed by the code in this wrapper file */
> > > >  #include <proton/types.h>
> > > > +#include <proton/url.h>
> > > >  #include <proton/message.h>
> > > >  #include <proton/driver.h>
> > > >  #include <proton/driver_extras.h>
> > > >
> > > > Modified: qpid/proton/trunk/proton-c/bindings/python/cproton.i
> > > > URL:
> > > >
> > http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/bindings/python/cproton.i?rev=1626329&r1=1626328&r2=1626329&view=diff
> > > >
> > > >
> > ==============================================================================
> > > > --- qpid/proton/trunk/proton-c/bindings/python/cproton.i (original)
> > > > +++ qpid/proton/trunk/proton-c/bindings/python/cproton.i Fri Sep 19
> > > > 21:00:50 2014
> > > > @@ -23,6 +23,7 @@
> > > >  #include <winsock2.h>
> > > >  #endif
> > > >  #include <proton/engine.h>
> > > > +#include <proton/url.h>
> > > >  #include <proton/message.h>
> > > >  #include <proton/sasl.h>
> > > >  #include <proton/driver.h>
> > > > @@ -280,41 +281,4 @@ int pn_ssl_get_peer_hostname(pn_ssl_t *s
> > > >    }
> > > >  %}
> > > >
> > > > -
> > > > -/**
> > > > -   pni_parse_url(char* url, char **scheme, char **user, char **pass,
> > char
> > > > **host, char **port, char **path)
> > > > -   The following type maps convert this into a python function that
> > taks
> > > > a URL string argument
> > > > -   and returns a list of strings [scheme, user, pass, host, port,
> > path]
> > > > -   This probably could be done more neatly.
> > > > -*/
> > > > -
> > > > -// Typemap to copy the url string as it will be modified by parse_url
> > > > -%typemap(in,noblock=1,fragment="SWIG_AsCharPtrAndSize") char *url (int
> > > > res, char *t = 0, size_t n = 0, int alloc = 0) {
> > > > -  res = SWIG_AsCharPtrAndSize($input, &t, &n, &alloc);
> > > > -  if (!SWIG_IsOK(res)) {
> > > > -    %argument_fail(res, "char *url", $symname, $argnum);
> > > > -  }
> > > > -  $1 = %new_array(n, $*1_ltype);
> > > > -  memcpy($1,t,sizeof(char)*n);
> > > > -  if (alloc == SWIG_NEWOBJ) %delete_array(t);
> > > > -  $1[n-1] = 0;
> > > > -}
> > > > -%typemap(freearg,match="in") char *url "free($1);";
> > > > -%typemap(argout) char *url "";
> > > > -
> > > > -// Typemap for char** return strings. Don't free them.
> > > > -%typemap(in,numinputs=0) char **OUTSTR($*1_ltype temp = 0) "$1 =
> > &temp;";
> > > > -%typemap(freearg,match="in") char **OUTSTR "";
> > > > -%typemap(argout,noblock=1,fragment="SWIG_FromCharPtr") char **OUTSTR
{
> > > > -    %append_output(SWIG_FromCharPtr(*$1));
> > > > -}
> > > > -
> > > > -// Typemap to initialize result as empty list
> > > > -%typemap(out) void "$result = PyList_New(0);";
> > > > -
> > > > -
> > > > -%apply char** OUTSTR {char **scheme, char **user, char **pass, char
> > > > **host, char **port, char **path};
> > > > -void pni_parse_url(char* url, char **scheme, char **user, char **pass,
> > > > char **host, char **port, char **path);
> > > > -%ignore pni_parse_url;
> > > > -
> > > >  %include "proton/cproton.i"
> > > >
> > > > Modified: qpid/proton/trunk/proton-c/bindings/python/proton.py
> > > > URL:
> > > >
> > http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/bindings/python/proton.py?rev=1626329&r1=1626328&r2=1626329&view=diff
> > > >
> > > >
> > ==============================================================================
> > > > --- qpid/proton/trunk/proton-c/bindings/python/proton.py (original)
> > > > +++ qpid/proton/trunk/proton-c/bindings/python/proton.py Fri Sep 19
> > > > 21:00:50 2014
> > > > @@ -3657,114 +3657,98 @@ __all__ = [
> > > >
> > > >
> > > >  class Url(object):
> > > > -    """
> > > > -    Simple URL parser/constructor, handles URLs of the form:
> > > > +  """
> > > > +  Simple URL parser/constructor, handles URLs of the form:
> > > >
> > > > -      <scheme>://<user>:<password>@<host>:<port>/<path>
> > > > +    <scheme>://<user>:<password>@<host>:<port>/<path>
> > > >
> > > > -    All components can be None if not specifeid in the URL string.
> > > > +  All components can be None if not specifeid in the URL string.
> > > >
> > > > -    The port can be specified as a service name, e.g. 'amqp' in the
> > > > -    URL string but Url.port always gives the integer value.
> > > > +  The port can be specified as a service name, e.g. 'amqp' in the
> > > > +  URL string but Url.port always gives the integer value.
> > > > +
> > > > +  @ivar scheme: Url scheme e.g. 'amqp' or 'amqps'
> > > > +  @ivar user: Username
> > > > +  @ivar password: Password
> > > > +  @ivar host: Host name, ipv6 literal or ipv4 dotted quad.
> > > > +  @ivar port: Integer port.
> > > > +  @ivar host_port: Returns host:port
> > > > +  """
> > > > +
> > > > +  AMQPS = "amqps"
> > > > +  AMQP = "amqp"
> > > > +
> > > > +  class Port(int):
> > > > +    """An integer port number that can be constructed from a service
> > name
> > > > string"""
> > > > +
> > > > +    def __new__(cls, value):
> > > > +      port = super(Url.Port, cls).__new__(cls, cls.port_int(value))
> > > > +      setattr(port, 'name', str(value))
> > > > +      return port
> > > > +
> > > > +    def __eq__(self, x): return str(self) == x or int(self) == x
> > > > +    def __ne__(self, x): return not self == x
> > > > +    def __str__(self): return str(self.name)
> > > > +
> > > > +    @staticmethod
> > > > +    def port_int(value):
> > > > +      """Convert service, an integer or a service name, into an
> > integer
> > > > port number."""
> > > > +      try:
> > > > +        return int(value)
> > > > +      except ValueError:
> > > > +        try:
> > > > +          return socket.getservbyname(value)
> > > > +        except socket.error:
> > > > +          raise ValueError("Not a valid port number or service name:
> > > > '%s'" % value)
> > > >
> > > > -    @ivar scheme: Url scheme e.g. 'amqp' or 'amqps'
> > > > -    @ivar user: Username
> > > > -    @ivar password: Password
> > > > -    @ivar host: Host name, ipv6 literal or ipv4 dotted quad.
> > > > -    @ivar port: Integer port.
> > > > -    @ivar host_port: Returns host:port
> > > > +  def __init__(self, url=None, **kwargs):
> > > > +    """
> > > > +    @param url: URL string to parse.
> > > > +    @param kwargs: scheme, user, password, host, port, path.
> > > > +      If specified, replaces corresponding part in url string.
> > > >      """
> > > > +    if url:
> > > > +      self._url = pn_url_parse(str(url))
> > > > +      if not self._url: raise ValueError("Invalid URL '%s'" % url)
> > > > +    else:
> > > > +      self._url = pn_url()
> > > > +    for k in kwargs:            # Let kwargs override values parsed
> > from
> > > > url
> > > > +      getattr(self, k)          # Check for invalid kwargs
> > > > +      setattr(self, k, kwargs[k])
> > > > +
> > > > +  class PartDescriptor(object):
> > > > +    def __init__(self, part):
> > > > +      self.getter = globals()["pn_url_%s" % part]
> > > > +      self.setter = globals()["pn_url_set_%s" % part]
> > > > +    def __get__(self, obj, type=None): return self.getter(obj._url)
> > > > +    def __set__(self, obj, value): return self.setter(obj._url,
> > > > str(value))
> > > > +
> > > > +  scheme = PartDescriptor('scheme')
> > > > +  username = PartDescriptor('username')
> > > > +  password = PartDescriptor('password')
> > > > +  host = PartDescriptor('host')
> > > > +  path = PartDescriptor('path')
> > > > +
> > > > +  @property
> > > > +  def port(self):
> > > > +    portstr = pn_url_port(self._url)
> > > > +    return portstr and Url.Port(portstr)
> > > > +
> > > > +  @port.setter
> > > > +  def port(self, value):
> > > > +    if value is None: pn_url_set_port(self._url, None)
> > > > +    else: pn_url_set_port(self._url, str(Url.Port(value)))
> > > >
> > > > -    AMQPS = "amqps"
> > > > -    AMQP = "amqp"
> > > > +  def __str__(self): return pn_url_str(self._url)
> > > >
> > > > -    class Port(int):
> > > > -      """An integer port number that can also have an associated
> > service
> > > > name string"""
> > > > +  def __repr__(self): return "Url(%r)" % str(self)
> > > >
> > > > -      def __new__(cls, value):
> > > > -        port = super(Url.Port, cls).__new__(cls, cls.port_int(value))
> > > > -        setattr(port, 'name', str(value))
> > > > -        return port
> > > > -
> > > > -      def __eq__(self, x): return str(self) == x or int(self) == x
> > > > -      def __ne__(self, x): return not self == x
> > > > -      def __str__(self): return str(self.name)
> > > > -
> > > > -      @staticmethod
> > > > -      def port_int(value):
> > > > -        """Convert service, an integer or a service name, into an
> > integer
> > > > port number."""
> > > > -        try:
> > > > -          return int(value)
> > > > -        except ValueError:
> > > > -          try:
> > > > -            return socket.getservbyname(value)
> > > > -          except socket.error:
> > > > -            raise ValueError("Not a valid port number or service name:
> > > > '%s'" % value)
> > > > -
> > > > -    def __init__(self, url=None, **kwargs):
> > > > -        """
> > > > -        @param url: String or Url instance to parse or copy.
> > > > -        @param kwargs: URL fields: scheme, user, password, host, port,
> > > > path.
> > > > -            If specified, replaces corresponding component in url.
> > > > -        """
> > > > -
> > > > -        fields = ['scheme', 'user', 'password', 'host', 'port',
> > 'path']
> > > > -
> > > > -        for f in fields: setattr(self, f, None)
> > > > -        for k in kwargs: getattr(self, k) # Check for invalid kwargs
> > > > -
> > > > -        if isinstance(url, Url): # Copy from another Url instance.
> > > > -            self.__dict__.update(url.__dict__)
> > > > -        elif url is not None:   # Parse from url
> > > > -            parts = pni_parse_url(str(url))
> > > > -            if not filter(None, parts): raise ValueError("Invalid AMQP
> > > > URL: '%s'" % url)
> > > > -            self.scheme, self.user, self.password, self.host, port,
> > > > self.path = parts
> > > > -            if not self.host: self.host = None
> > > > -            self.port = port and self.Port(port)
> > > > -
> > > > -        # Let kwargs override values previously set from url
> > > > -        for field in fields:
> > > > -            setattr(self, field, kwargs.get(field, getattr(self,
> > field)))
> > > > -
> > > > -    def __repr__(self):
> > > > -        return "Url(%r)" % str(self)
> > > > -
> > > > -    def __str__(self):
> > > > -        s = ""
> > > > -        if self.scheme:
> > > > -            s += "%s://" % self.scheme
> > > > -        if self.user:
> > > > -            s += self.user
> > > > -        if self.password:
> > > > -            s += ":%s" % self.password
> > > > -        if self.user or self.password:
> > > > -            s += '@'
> > > > -        if self.host and ':' in self.host:
> > > > -            s += "[%s]" % self.host
> > > > -        elif self.host:
> > > > -            s += self.host
> > > > -        if self.port:
> > > > -            s += ":%s" % self.port
> > > > -        if self.path:
> > > > -            s += "/%s" % self.path
> > > > -        return s
> > > > -
> > > > -    def __eq__(self, url):
> > > > -        return \
> > > > -            self.scheme == url.scheme and \
> > > > -            self.user == url.user and self.password == url.password
> > and \
> > > > -            self.host == url.host and self.port == url.port and \
> > > > -            self.path == url.path
> > > > -
> > > > -    def __ne__(self, url):
> > > > -        return not self.__eq__(url)
> > > > -
> > > > -    def defaults(self):
> > > > -        """
> > > > -        Fill in missing values with defaults
> > > > -        @return: self
> > > > -        """
> > > > -        self.scheme = self.scheme or self.AMQP
> > > > -        self.host = self.host or '0.0.0.0'
> > > > -        self.port = self.port or self.Port(self.scheme)
> > > > -        return self
> > > > +  def defaults(self):
> > > > +    """
> > > > +    Fill in missing values (scheme, host or port) with defaults
> > > > +    @return: self
> > > > +    """
> > > > +    self.scheme = self.scheme or self.AMQP
> > > > +    self.host = self.host or '0.0.0.0'
> > > > +    self.port = self.port or self.Port(self.scheme)
> > > > +    return self
> > > >
> > > > Modified: qpid/proton/trunk/proton-c/bindings/ruby/ruby.i
> > > > URL:
> > > >
> > http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/bindings/ruby/ruby.i?rev=1626329&r1=1626328&r2=1626329&view=diff
> > > >
> > > >
> > ==============================================================================
> > > > --- qpid/proton/trunk/proton-c/bindings/ruby/ruby.i (original)
> > > > +++ qpid/proton/trunk/proton-c/bindings/ruby/ruby.i Fri Sep 19 21:00:50
> > > > 2014
> > > > @@ -26,8 +26,8 @@
> > > >  #include <proton/messenger.h>
> > > >  #include <proton/ssl.h>
> > > >  #include <proton/driver_extras.h>
> > > > -
> > > >  #include <proton/types.h>
> > > > +#include <proton/url.h>
> > > >
> > > >  #include <uuid/uuid.h>
> > > >  %}
> > > >
> > > > Modified: qpid/proton/trunk/proton-c/include/proton/cproton.i
> > > > URL:
> > > >
> > http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/include/proton/cproton.i?rev=1626329&r1=1626328&r2=1626329&view=diff
> > > >
> > > >
> > ==============================================================================
> > > > --- qpid/proton/trunk/proton-c/include/proton/cproton.i (original)
> > > > +++ qpid/proton/trunk/proton-c/include/proton/cproton.i Fri Sep 19
> > > > 21:00:50 2014
> > > > @@ -1394,3 +1394,6 @@ typedef unsigned long int uintptr_t;
> > > >    pn_delivery_t *pn_cast_pn_delivery(void *x) { return (pn_delivery_t
> > *)
> > > > x; }
> > > >    pn_transport_t *pn_cast_pn_transport(void *x) { return
> > (pn_transport_t
> > > > *) x; }
> > > >  %}
> > > > +
> > > > +%include "proton/url.h"
> > > > +
> > > >
> > > > Added: qpid/proton/trunk/proton-c/include/proton/url.h
> > > > URL:
> > > >
> > http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/include/proton/url.h?rev=1626329&view=auto
> > > >
> > > >
> > ==============================================================================
> > > > --- qpid/proton/trunk/proton-c/include/proton/url.h (added)
> > > > +++ qpid/proton/trunk/proton-c/include/proton/url.h Fri Sep 19 21:00:50
> > > > 2014
> > > > @@ -0,0 +1,83 @@
> > > > +#ifndef PROTON_URL_H
> > > > +#define PROTON_URL_H
> > > > +/*
> > > > + * Licensed to the Apache Software Foundation (ASF) under one
> > > > + * or more contributor license agreements.  See the NOTICE file
> > > > + * distributed with this work for additional information
> > > > + * regarding copyright ownership.  The ASF licenses this file
> > > > + * to you under the Apache License, Version 2.0 (the
> > > > + * "License"); you may not use this file except in compliance
> > > > + * with the License.  You may obtain a copy of the License at
> > > > + *
> > > > + *   http://www.apache.org/licenses/LICENSE-2.0
> > > > + *
> > > > + * Unless required by applicable law or agreed to in writing,
> > > > + * software distributed under the License is distributed on an
> > > > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > > > + * KIND, either express or implied.  See the License for the
> > > > + * specific language governing permissions and limitations
> > > > + * under the License.
> > > > + */
> > > > +
> > > > +#include <proton/import_export.h>
> > > > +
> > > > +/** @file
> > > > + * URL API for parsing URLs.
> > > > + *
> > > > + * @defgroup url URL
> > > > + * @{
> > > > + */
> > > > +
> > > > +/** A parsed URL */
> > > > +typedef struct pn_url_t pn_url_t;
> > > > +
> > > > +/** Create an empty URL */
> > > > +PN_EXTERN pn_url_t *pn_url(void);
> > > > +
> > > > +/** Parse a string URL as a pn_url_t.
> > > > + *@param[in] url A URL string.
> > > > + *@return The parsed pn_url_t or NULL if url is not a valid URL
> > string.
> > > > + */
> > > > +PN_EXTERN pn_url_t *pn_url_parse(const char *url);
> > > > +
> > > > +/** Free a URL */
> > > > +PN_EXTERN void pn_url_free(pn_url_t *url);
> > > > +
> > > > +/** Clear the contents of the URL. */
> > > > +PN_EXTERN void pn_url_clear(pn_url_t *url);
> > > > +
> > > > +/** Return the string form of a URL. Owned by the pn_url_t.*/
> > > > +PN_EXTERN const char *pn_url_str(pn_url_t *url);
> > > > +
> > > > +/**
> > > > + *@name Getters for parts of the URL.
> > > > + *
> > > > + *Values belong to the URL. May return NULL if the value is not set.
> > > > + *
> > > > + *@{
> > > > + */
> > > > +PN_EXTERN const char *pn_url_scheme(pn_url_t *url);
> > > > +PN_EXTERN const char *pn_url_username(pn_url_t *url);
> > > > +PN_EXTERN const char *pn_url_password(pn_url_t *url);
> > > > +PN_EXTERN const char *pn_url_host(pn_url_t *url);
> > > > +PN_EXTERN const char *pn_url_port(pn_url_t *url);
> > > > +PN_EXTERN const char *pn_url_path(pn_url_t *url);
> > > > +///@}
> > > > +
> > > > +/**
> > > > + *@name Setters for parts of the URL.
> > > > + *
> > > > + *Values are copied. Value can be NULL to indicate the part is not
> > set.
> > > > + *
> > > > + *@{
> > > > + */
> > > > +PN_EXTERN void pn_url_set_scheme(pn_url_t *url, const char *scheme);
> > > > +PN_EXTERN void pn_url_set_username(pn_url_t *url, const char
> > *username);
> > > > +PN_EXTERN void pn_url_set_password(pn_url_t *url, const char
> > *password);
> > > > +PN_EXTERN void pn_url_set_host(pn_url_t *url, const char *host);
> > > > +PN_EXTERN void pn_url_set_port(pn_url_t *url, const char *port);
> > > > +PN_EXTERN void pn_url_set_path(pn_url_t *url, const char *path);
> > > > +///@}
> > > > +
> > > > +///@}
> > > > +#endif
> > > >
> > > > Added: qpid/proton/trunk/proton-c/src/url.c
> > > > URL:
> > > >
> > http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/url.c?rev=1626329&view=auto
> > > >
> > > >
> > ==============================================================================
> > > > --- qpid/proton/trunk/proton-c/src/url.c (added)
> > > > +++ qpid/proton/trunk/proton-c/src/url.c Fri Sep 19 21:00:50 2014
> > > > @@ -0,0 +1,127 @@
> > > > +/*
> > > > + *
> > > > + * Licensed to the Apache Software Foundation (ASF) under one
> > > > + * or more contributor license agreements.  See the NOTICE file
> > > > + * distributed with this work for additional information
> > > > + * regarding copyright ownership.  The ASF licenses this file
> > > > + * to you under the Apache License, Version 2.0 (the
> > > > + * "License"); you may not use this file except in compliance
> > > > + * with the License.  You may obtain a copy of the License at
> > > > + *
> > > > + *   http://www.apache.org/licenses/LICENSE-2.0
> > > > + *
> > > > + * Unless required by applicable law or agreed to in writing,
> > > > + * software distributed under the License is distributed on an
> > > > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > > > + * KIND, either express or implied.  See the License for the
> > > > + * specific language governing permissions and limitations
> > > > + * under the License.
> > > > + *
> > > > + */
> > > > +
> > > > +#include <proton/url.h>
> > > > +#include <proton/util.h>
> > > > +#include <stdlib.h>
> > > > +#include <string.h>
> > > > +#include <stdio.h>
> > > > +
> > > > +static char* copy(const char* str) {
> > > > +    if (str ==  NULL) return NULL;
> > > > +    char *str2 = (char*)malloc(strlen(str));
> > > > +    if (str2) strcpy(str2, str);
> > > > +    return str2;
> > > > +}
> > > > +
> > > > +struct pn_url_t {
> > > > +    char *scheme;
> > > > +    char *username;
> > > > +    char *password;
> > > > +    char *host;
> > > > +    char *port;
> > > > +    char *path;
> > > > +    char *str;
> > > > +};
> > > > +
> > > > +PN_EXTERN pn_url_t *pn_url() {
> > > > +    pn_url_t *url = (pn_url_t*)malloc(sizeof(pn_url_t));
> > > > +    memset(url, 0, sizeof(*url));
> > > > +    return url;
> > > > +}
> > > > +
> > > > +/** Parse a string URL as a pn_url_t.
> > > > + *@param[in] url A URL string.
> > > > + *@return The parsed pn_url_t or NULL if url is not a valid URL
> > string.
> > > > + */
> > > > +PN_EXTERN pn_url_t *pn_url_parse(const char *str) {
> > > > +    if (!str || !*str)          /* Empty string or NULL is illegal. */
> > > > +        return NULL;
> > > > +
> > > > +    pn_url_t *url = pn_url();
> > > > +    char *str2 = copy(str);         /* FIXME aconway 2014-09-19:
> > clean up
> > > > */
> > > > +    pni_parse_url(str2, &url->scheme, &url->username, &url->password,
> > > > &url->host, &url->port, &url->path);
> > > > +    url->scheme = copy(url->scheme);
> > > > +    url->username = copy(url->username);
> > > > +    url->password = copy(url->password);
> > > > +    url->host = (url->host && !*url->host) ? NULL :
copy(url->host);
> > > > +    url->port = copy(url->port);
> > > > +    url->path = copy(url->path);
> > > > +    return url;
> > > > +}
> > > > +
> > > > +/** Free a URL */
> > > > +PN_EXTERN void pn_url_free(pn_url_t *url) {
> > > > +    pn_url_clear(url);
> > > > +    free(url);
> > > > +}
> > > > +
> > > > +/** Clear the contents of the URL. */
> > > > +PN_EXTERN void pn_url_clear(pn_url_t *url) {
> > > > +    pn_url_set_username(url, NULL);
> > > > +    pn_url_set_password(url, NULL);
> > > > +    pn_url_set_host(url, NULL);
> > > > +    pn_url_set_port(url, NULL);
> > > > +    pn_url_set_path(url, NULL);
> > > > +    free(url->str); url->str = NULL;
> > > > +}
> > > > +
> > > > +static inline int len(const char *str) { return str ? strlen(str) :
> > 0; }
> > > > +
> > > > +/** Return the string form of a URL. */
> > > > +PN_EXTERN const char *pn_url_str(pn_url_t *url) {
> > > > +    int size = len(url->scheme) + len(url->username) +
> > len(url->password)
> > > > +        + len(url->host) + len(url->port) + len(url->path)
> > > > +        + len("s://u:p@[h]:p/p");
> > > > +    free(url->str);
> > > > +    url->str = (char*)malloc(size);
> > > > +    if (!url->str) return NULL;
> > > > +
> > > > +    int i = 0;
> > > > +    if (url->scheme) i += snprintf(url->str+i, size-i, "%s://",
> > > > url->scheme);
> > > > +    if (url->username) i += snprintf(url->str+i, size-i, "%s",
> > > > url->username);
> > > > +    if (url->password) i += snprintf(url->str+i, size-i, ":%s",
> > > > url->password);
> > > > +    if (url->username || url->password) i += snprintf(url->str+i,
> > size-i,
> > > > "@");
> > > > +    if (url->host) {
> > > > +        if (strchr(url->host, ':')) i += snprintf(url->str+i, size-i,
> > > > "[%s]", url->host);
> > > > +        else i += snprintf(url->str+i, size-i, "%s", url->host);
> > > > +    }
> > > > +    if (url->port) i += snprintf(url->str+i, size-i, ":%s",
> > url->port);
> > > > +    if (url->path) i += snprintf(url->str+i, size-i, "/%s",
> > url->path);
> > > > +    return url->str;
> > > > +}
> > > > +
> > > > +PN_EXTERN const char *pn_url_scheme(pn_url_t *url) { return
> > url->scheme; }
> > > > +PN_EXTERN const char *pn_url_username(pn_url_t *url) { return
> > > > url->username; }
> > > > +PN_EXTERN const char *pn_url_password(pn_url_t *url) { return
> > > > url->password; }
> > > > +PN_EXTERN const char *pn_url_host(pn_url_t *url) { return url->host;
}
> > > > +PN_EXTERN const char *pn_url_port(pn_url_t *url) { return url->port;
}
> > > > +PN_EXTERN const char *pn_url_path(pn_url_t *url) { return url->path;
}
> > > > +
> > > > +#define SET(part) free(url->part); url->part = copy(part)
> > > > +PN_EXTERN void pn_url_set_scheme(pn_url_t *url, const char *scheme) {
> > > > SET(scheme); }
> > > > +PN_EXTERN void pn_url_set_username(pn_url_t *url, const char
> > *username) {
> > > > SET(username); }
> > > > +PN_EXTERN void pn_url_set_password(pn_url_t *url, const char
> > *password) {
> > > > SET(password); }
> > > > +PN_EXTERN void pn_url_set_host(pn_url_t *url, const char *host) {
> > > > SET(host); }
> > > > +PN_EXTERN void pn_url_set_port(pn_url_t *url, const char *port) {
> > > > SET(port); }
> > > > +PN_EXTERN void pn_url_set_path(pn_url_t *url, const char *path) {
> > > > SET(path); }
> > > > +
> > > > +
> > > >
> > > > Modified: qpid/proton/trunk/tests/python/proton_tests/url.py
> > > > URL:
> > > >
> > http://svn.apache.org/viewvc/qpid/proton/trunk/tests/python/proton_tests/url.py?rev=1626329&r1=1626328&r2=1626329&view=diff
> > > >
> > > >
> > ==============================================================================
> > > > --- qpid/proton/trunk/tests/python/proton_tests/url.py (original)
> > > > +++ qpid/proton/trunk/tests/python/proton_tests/url.py Fri Sep 19
> > 21:00:50
> > > > 2014
> > > > @@ -28,9 +28,9 @@ class UrlTest(common.Test):
> > > >      def assertNotEqual(self, a, b):
> > > >          assert a != b, "%s == %s" % (a, b)
> > > >
> > > > -    def assertUrl(self, u, scheme, user, password, host, port, path):
> > > > -        self.assertEqual((u.scheme, u.user, u.password, u.host,
> > u.port,
> > > > u.path),
> > > > -                         (scheme, user, password, host, port, path))
> > > > +    def assertUrl(self, u, scheme, username, password, host, port,
> > path):
> > > > +        self.assertEqual((u.scheme, u.username, u.password, u.host,
> > > > u.port, u.path),
> > > > +                         (scheme, username, password, host, port,
> > path))
> > > >
> > > >      def testUrl(self):
> > > >          url = Url('amqp://me:secret@myhost:1234/foobar')
> > > > @@ -40,7 +40,7 @@ class UrlTest(common.Test):
> > > >
> > > >      def testDefaults(self):
> > > >          # Check that we allow None for scheme, port
> > > > -        url = Url(user='me', password='secret', host='myhost',
> > > > path='foobar')
> > > > +        url = Url(username='me', password='secret', host='myhost',
> > > > path='foobar')
> > > >          self.assertEqual(str(url), "me:secret@myhost/foobar")
> > > >          self.assertUrl(url, None, 'me', 'secret', 'myhost', None,
> > > > 'foobar')
> > > >
> > > > @@ -97,21 +97,19 @@ class UrlTest(common.Test):
> > > >      def testMissing(self):
> > > >          self.assertUrl(Url(), None, None, None, None, None, None)
> > > >          self.assertUrl(Url('amqp://'), 'amqp', None, None, None, None,
> > > > None)
> > > > -        self.assertUrl(Url('user@'), None, 'user', None, None, None,
> > > > None)
> > > > +        self.assertUrl(Url('username@'), None, 'username', None,
> > None,
> > > > None, None)
> > > >          self.assertUrl(Url(':pass@'), None, '', 'pass', None, None,
> > None)
> > > >          self.assertUrl(Url('host'), None, None, None, 'host', None,
> > None)
> > > >          self.assertUrl(Url(':1234'), None, None, None, None, 1234,
> > None)
> > > >          self.assertUrl(Url('/path'), None, None, None, None, None,
> > 'path')
> > > >
> > > > -        for s in ['amqp://', 'user@', ':pass@', ':1234', '/path']:
> > > > +        for s in ['amqp://', 'username@', ':pass@', ':1234',
> > '/path']:
> > > >              self.assertEqual(s, str(Url(s)))
> > > >
> > > >          for s, full in [
> > > >                  ('amqp://', 'amqp://0.0.0.0:amqp'),
> > > > -                ('user@', 'amqp://user@0.0.0.0:amqp'),
> > > > +                ('username@', 'amqp://username@0.0.0.0:amqp'),
> > > >                  (':pass@', 'amqp://:pass@0.0.0.0:amqp'),
> > > >                  (':1234', 'amqp://0.0.0.0:1234'),
> > > >                  ('/path', 'amqp://0.0.0.0:amqp/path')]:
> > > >              self.assertEqual(str(Url(s).defaults()), full)
> > > > -
> > > > -        self.assertRaises(ValueError, Url, '')
> > > >
> > > >
> > > >
> > > > ---------------------------------------------------------------------
> > > > To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
> > > > For additional commands, e-mail: commits-help@qpid.apache.org
> > > >
> > > >
> >
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
> > For additional commands, e-mail: dev-help@qpid.apache.org
> >
> >



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org


Mime
View raw message