/*
 * 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 <stdlib.h>
#define AXIS2_WANT_STRFUNC
#include <axutil_uri.h>

typedef struct schemes_t schemes_t;

/** Structure to store various schemes and their default ports */
struct schemes_t
{
    /** The name of the scheme */
    const axis2_char_t *name;

    /** The default port for the scheme */
    axis2_port_t default_port;
};

/* Some WWW schemes and their default ports; this is basically /etc/services */

/* This will become global when the protocol abstraction comes */

/* As the schemes are searched by a linear search, */

/* they are sorted by their expected frequency */
static schemes_t schemes[] = {
    {"http", AXIS2_URI_HTTP_DEFAULT_PORT},
    {"ftp", AXIS2_URI_FTP_DEFAULT_PORT},
    {"https", AXIS2_URI_HTTPS_DEFAULT_PORT},
    {"gopher", AXIS2_URI_GOPHER_DEFAULT_PORT},
    {"ldap", AXIS2_URI_LDAP_DEFAULT_PORT},
    {"nntp", AXIS2_URI_NNTP_DEFAULT_PORT},
    {"snews", AXIS2_URI_SNEWS_DEFAULT_PORT},
    {"imap", AXIS2_URI_IMAP_DEFAULT_PORT},
    {"pop", AXIS2_URI_POP_DEFAULT_PORT},
    {"sip", AXIS2_URI_SIP_DEFAULT_PORT},
    {"rtsp", AXIS2_URI_RTSP_DEFAULT_PORT},
    {"wais", AXIS2_URI_WAIS_DEFAULT_PORT},
    {"z39.50r", AXIS2_URI_WAIS_DEFAULT_PORT},
    {"z39.50s", AXIS2_URI_WAIS_DEFAULT_PORT},
    {"prospero", AXIS2_URI_PROSPERO_DEFAULT_PORT},
    {"nfs", AXIS2_URI_NFS_DEFAULT_PORT},
    {"tip", AXIS2_URI_TIP_DEFAULT_PORT},
    {"acap", AXIS2_URI_ACAP_DEFAULT_PORT},
    {"telnet", AXIS2_URI_TELNET_DEFAULT_PORT},
    {"ssh", AXIS2_URI_SSH_DEFAULT_PORT},
    {NULL, 0xFFFF}              /* unknown port */
};

/* Here is the hand-optimized parse_uri_components().  There are some wild
 * tricks we could pull in assembly language that we don't pull here... like we
 * can do word-at-time scans for delimiter characters using the same technique
 * that fast axutil_memchr()s use.  But that would be way non-portable. -djg
 */

/* We have a axis2_table_t that we can index by character and it tells us if the
 * character is one of the interesting delimiters.  Note that we even get
 * compares for NUL for free -- it's just another delimiter.
 */

#define T_COLON           0x01  /* ':' */
#define T_SLASH           0x02  /* '/' */
#define T_QUESTION        0x04  /* '?' */
#define T_HASH            0x08  /* '#' */
#define T_NUL             0x80  /* '\0' */

#if AXIS2_CHARSET_EBCDIC

/* Delimiter table for the EBCDIC character set */
static const unsigned char uri_delims[256] = {
    T_NUL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, T_SLASH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, T_QUESTION,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, T_COLON, T_HASH, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
#else

/* Delimiter table for the ASCII character set */
static const unsigned char uri_delims[256] = {
    T_NUL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, T_HASH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, T_SLASH,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, T_COLON, 0, 0, 0, 0, T_QUESTION,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
#endif

/* it works like this:
    if (uri_delims[ch] & NOTEND_foobar) {
        then we're not at a delimiter for foobar
    }
*/

/* Note that we optimize the scheme scanning here, we cheat and let the
 * compiler know that it doesn't have to do the & masking.
 */
#define NOTEND_SCHEME     (0xff)
#define NOTEND_HOSTINFO   (T_SLASH | T_QUESTION | T_HASH | T_NUL)
#define NOTEND_PATH       (T_QUESTION | T_HASH | T_NUL)

/**
 * A structure to encompass all of the fields in a uri
 */
struct axutil_uri
{
    /** scheme ("http"/"ftp"/...) */
    axis2_char_t *scheme;

    /** combined [user[:password]\@]host[:port] */
    axis2_char_t *hostinfo;

    /** user name, as in http://user:passwd\@host:port/ */
    axis2_char_t *user;

    /** password, as in http://user:passwd\@host:port/ */
    axis2_char_t *password;

    /** hostname from URI (or from Host: header) */
    axis2_char_t *hostname;

    /** port string (integer representation is in "port") */
    axis2_char_t *port_str;

    /** the request path (or "/" if only scheme://host was given) */
    axis2_char_t *path;

    /** Everything after a '?' in the path, if present */
    axis2_char_t *query;

    /** Trailing "#fragment" string, if present */
    axis2_char_t *fragment;

    /** structure returned from gethostbyname() */
    struct hostent *hostent;

    /** The port number, numeric, valid only if port_str  */
    axis2_port_t port;

    /** has the structure been initialized */
    unsigned is_initialized:1;

    /** has the DNS been looked up yet */
    unsigned dns_looked_up:1;

    /** has the dns been resolved yet */
    unsigned dns_resolved:1;

    /** is it an IPv6 URL */
    unsigned is_ipv6:1;
};

AXIS2_EXTERN axutil_uri_t *AXIS2_CALL
axutil_uri_create(
    const axutil_env_t *env)
{
    axutil_uri_t *uri = NULL;
    AXIS2_ENV_CHECK(env, NULL);

    uri = (axutil_uri_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_uri_t));

    if(!uri)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory");
        return NULL;
    }
    uri->scheme = NULL;
    uri->hostinfo = NULL;
    uri->user = NULL;
    uri->password = NULL;
    uri->hostname = NULL;
    uri->port_str = NULL;
    uri->path = NULL;
    uri->query = NULL;
    uri->fragment = NULL;
    uri->hostent = NULL;
    uri->port = 0;
    uri->is_ipv6 = 0;

    return uri;
}

AXIS2_EXTERN void AXIS2_CALL
axutil_uri_free(
    axutil_uri_t *uri,
    const axutil_env_t *env)
{
    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);

    if(uri->scheme)
    {
        AXIS2_FREE(env->allocator, uri->scheme);
        uri->scheme = NULL;
    }

    if(uri->hostinfo)
    {
        AXIS2_FREE(env->allocator, uri->hostinfo);
        uri->hostinfo = NULL;
    }

    if(uri->user)
    {
        AXIS2_FREE(env->allocator, uri->user);
        uri->user = NULL;
    }

    if(uri->password)
    {
        AXIS2_FREE(env->allocator, uri->password);
        uri->password = NULL;
    }

    if(uri->hostname)
    {
        AXIS2_FREE(env->allocator, uri->hostname);
        uri->hostname = NULL;
    }

    if(uri->port_str)
    {
        AXIS2_FREE(env->allocator, uri->port_str);
        uri->port_str = NULL;
    }

    if(uri->path)
    {
        AXIS2_FREE(env->allocator, uri->path);
        uri->path = NULL;
    }

    if(uri->query)
    {
        AXIS2_FREE(env->allocator, uri->query);
        uri->query = NULL;
    }

    if(uri->fragment)
    {
        AXIS2_FREE(env->allocator, uri->fragment);
        uri->fragment = NULL;
    }

    AXIS2_FREE(env->allocator, uri);

    return;
}

/* parse_uri_components():
 * Parse a given URI, fill in all supplied fields of a uri_components
 * structure. This eliminates the necessity of extracting host, port,
 * path, query info repeatedly in the modules.
 * Side effects:
 *  - fills in fields of uri_components *uptr
 *  - none on any of the r->* fields
 */

AXIS2_EXTERN axutil_uri_t *AXIS2_CALL
axutil_uri_parse_string(
    const axutil_env_t *env,
    const axis2_char_t *uri_str)
{
    axutil_uri_t *uri = NULL;
    const axis2_char_t *s;
    const axis2_char_t *s1;
    const axis2_char_t *hostinfo;
    axis2_char_t *endstr;
    int port;
    int v6_offset1 = 0, v6_offset2 = 0;

    AXIS2_PARAM_CHECK(env->error, uri_str, NULL);

    uri = (axutil_uri_t *)axutil_uri_create(env);

    /* Initialize the structure. parse_uri() and parse_uri_components()
     * can be called more than once per request.
     */
    uri->is_initialized = 1;

    /* We assume the processor has a branch predictor like most --
     * it assumes forward branches are untaken and backwards are taken.  That's
     * the reason for the gotos.
     */
    if(uri_str[0] == '/')
    {
        /* RFC2396 #4.3 says that two leading slashes mean we have an
         * authority component, not a path!  Fixing this looks scary
         * with the gotos here.  But if the existing logic is valid,
         * then presumably a goto pointing to deal_with_authority works.
         *
         * RFC2396 describes this as resolving an ambiguity.  In the
         * case of three or more slashes there would seem to be no
         * ambiguity, so it is a path after all.
         */
        if(uri_str[1] == '/' && uri_str[2] != '/')
        {
            s = uri_str + 2;
            goto deal_with_authority;
        }

        deal_with_path:
        /* we expect uri to point to first character of path ... remember
         * that the path could be empty -- http://foobar?query for example
         */
        s = uri_str;
        if((!uri->hostinfo && uri_str[0] == '/' && uri_str[1] == '/') || (!uri->scheme
            && uri_str[0] == ':'))
        {
            if(uri)
            {
                axutil_uri_free(uri, env);
            }
            uri = NULL;
            goto end;
        }
        while((uri_delims[*(unsigned char *)s] & NOTEND_PATH) == 0)
        {
            ++s;
        }
        if(s != uri_str)
        {
            uri->path = axutil_strmemdup(uri_str, s - uri_str, env);
        }
        if(*s == 0)
        {
            goto end;
        }
        if(*s == '?')
        {
            ++s;
            s1 = strchr(s, '#');
            if(s1)
            {
                uri->fragment = axutil_strdup(env, s1 + 1);
                uri->query = axutil_strmemdup(s, s1 - s, env);
            }
            else
            {
                uri->query = axutil_strdup(env, s);
            }
            goto end;
        }
        /* otherwise it's a fragment */
        uri->fragment = axutil_strdup(env, s + 1);

        goto end;
    }

    /* find the scheme: */
    s = uri_str;
    while((uri_delims[*(unsigned char *)s] & NOTEND_SCHEME) == 0)
    {
        ++s;
    }
    /* scheme must be non-empty and followed by :// */
    if(s == uri_str || s[0] != ':' || s[1] != '/' || s[2] != '/')
    {
        if(uri->scheme)
        {
            AXIS2_FREE(env->allocator, uri->scheme);
            uri->scheme = NULL;
        }
        s = uri_str; /* restart from beginning as the loop must have ended in
         * in a wrong place. */
        goto deal_with_authority;
        /* backwards predicted taken! */
    }

    uri->scheme = axutil_strmemdup(uri_str, s - uri_str, env);
    s += 3;

    deal_with_authority: hostinfo = s;
    while((uri_delims[*(unsigned char *)s] & NOTEND_HOSTINFO) == 0)
    {
        ++s;
    }
    uri_str = s; /* whatever follows hostinfo is start of uri */
    uri->hostinfo = axutil_strmemdup(hostinfo, uri_str - hostinfo, env);

    /* If there's a username:password@host:port, the @ we want is the last @...
     * too bad there's no memrchr()... For the C purists, note that hostinfo
     * is definitely not the first character of the original uri so therefore
     * &hostinfo[-1] < &hostinfo[0] ... and this loop is valid C.
     */
    do
    {
        --s;
    }
    while(s >= hostinfo && *s != '@');
    if(s < hostinfo)
    {
        /* again we want the common case to be fall through */
        deal_with_host:
        /* We expect hostinfo to point to the first character of
         * the hostname.  If there's a port it is the first colon,
         * except with IPv6.
         */
        if(*hostinfo == '[')
        {
            if(*(hostinfo + 1) == ']')
            {
                if(uri)
                {
                    axutil_uri_free(uri, env);
                }
                uri = NULL;
                goto end;
            }
            if((*(hostinfo + 1) >= '0' && *(hostinfo + 1) <= '9') || (*(hostinfo + 1) >= 'a'
                && *(hostinfo + 1) <= 'z') || (*(hostinfo + 1) >= 'A' && *(hostinfo + 1) <= 'Z')
                || (*(hostinfo + 1) == ':' && *(hostinfo + 2) == ':'))
            {
                uri->is_ipv6 = 1;
            }
            else
            {
                if(uri)
                {
                    axutil_uri_free(uri, env);
                }
                uri = NULL;
                goto end;
            }
            v6_offset1 = 1;
            v6_offset2 = 2;
            s = axutil_memchr(hostinfo, ']', uri_str - hostinfo);
            if(!s)
            {
                if(uri)
                {
                    axutil_uri_free(uri, env);
                }
                uri = NULL;
                goto end;
            }
            if(*++s != ':')
            {
                s = NULL; /* no port */
            }
        }
        else if(!*hostinfo || (*hostinfo >= '0' && *hostinfo <= '9') || (*hostinfo >= 'a'
            && *hostinfo <= 'z') || (*hostinfo >= 'A' && *hostinfo <= 'Z') || *hostinfo == '?'
            || *hostinfo == '/' || *hostinfo == '#')
        {
            s = axutil_memchr(hostinfo, ':', uri_str - hostinfo);
        }
        else
        {
            if(uri)
            {
                axutil_uri_free(uri, env);
            }
            uri = NULL;
            goto end;
        }
        if(!s)
        {
            /* we expect the common case to have no port */
            uri->hostname = axutil_strmemdup(hostinfo + v6_offset1,
                uri_str - hostinfo - v6_offset2, env);
            goto deal_with_path;
        }
        uri->hostname = axutil_strmemdup(hostinfo + v6_offset1, s - hostinfo - v6_offset2, env);
        ++s;
        uri->port_str = axutil_strmemdup(s, uri_str - s, env);
        if(uri_str != s)
        {
            port = strtol(uri->port_str, &endstr, 10);
            uri->port = (axis2_port_t)port;
            /* We are sure that the conversion is safe */
            if(*endstr == '\0')
            {
                goto deal_with_path;
            }
            /* Invalid characters after ':' found */
            if(uri)
            {
                axutil_uri_free(uri, env);
            }
            uri = NULL;
            goto end;
        }
        uri->port = axutil_uri_port_of_scheme(uri->scheme);
        goto deal_with_path;
    }

    /* first colon delimits username:password */
    s1 = axutil_memchr(hostinfo, ':', s - hostinfo);
    if(s1)
    {
        uri->user = axutil_strmemdup(hostinfo, s1 - hostinfo, env);
        ++s1;
        uri->password = axutil_strmemdup(s1, s - s1, env);
    }
    else
    {
        uri->user = axutil_strmemdup(hostinfo, s - hostinfo, env);
    }
    hostinfo = s + 1;
    goto deal_with_host;

    /* End of function call */
    end: return uri;
}

/* Special case for CONNECT parsing: it comes with the hostinfo part only */

/* See the INTERNET-DRAFT document "Tunneling SSL Through a WWW Proxy"
 * currently at http://muffin.doit.org/docs/rfc/tunneling_ssl.html
 * for the format of the "CONNECT host:port HTTP/1.0" request
 */
AXIS2_EXTERN axutil_uri_t *AXIS2_CALL
axutil_uri_parse_hostinfo(
    const axutil_env_t *env,
    const axis2_char_t *hostinfo)
{
    axutil_uri_t *uri = NULL;
    const axis2_char_t *s;
    axis2_char_t *endstr;
    const axis2_char_t *rsb;
    int v6_offset1 = 0;

    AXIS2_PARAM_CHECK(env->error, hostinfo, NULL);

    uri = (axutil_uri_t *)axutil_uri_create(env);
    if(!uri)
    {
        return NULL;
    }
    /* Initialize the structure. parse_uri() and parse_uri_components()
     * can be called more than once per request.
     */
    memset(uri, '\0', sizeof(*uri));
    uri->is_initialized = 1;
    uri->hostinfo = axutil_strdup(env, hostinfo);

    /* We expect hostinfo to point to the first character of
     * the hostname.  There must be a port, separated by a colon
     */
    if(*hostinfo == '[')
    {
        if(*(hostinfo + 1) == ']')
        {
            axutil_uri_free(uri, env);
            return NULL;
        }
        uri->is_ipv6 = 1;
        rsb = strchr(hostinfo, ']');
        if(!rsb || *(rsb + 1) != ':')
        {
            axutil_uri_free(uri, env);
            return NULL;
        }
        /* literal IPv6 address
         * Special allowances has been made according to RFC3986 for
         * IPv6 addresses beginning with "::"
         */
        s = rsb + 1;
        if((*(hostinfo + 1) >= '0' && *(hostinfo + 1) <= '9') || (*(hostinfo + 1) >= 'a'
            && *(hostinfo + 1) <= 'z') || (*(hostinfo + 1) >= 'A' && *(hostinfo + 1) <= 'Z')
            || (*(hostinfo + 1) == ':' && *(hostinfo + 2) == ':'))
        {
            ++hostinfo;
        }
        else
        {
            axutil_uri_free(uri, env);
            return NULL;
        }
        v6_offset1 = 1;
    }
    else if((*hostinfo >= '0' && *hostinfo <= '9') || (*hostinfo >= 'a' && *hostinfo <= 'z')
        || (*hostinfo >= 'A' && *hostinfo <= 'Z'))
    {
        s = strchr(hostinfo, ':');
    }
    else
    {
        axutil_uri_free(uri, env);
        return NULL;
    }
    if(!s)
    {
        axutil_uri_free(uri, env);
        return NULL;
    }
    uri->hostname = axutil_strndup(env, hostinfo, (int)(s - hostinfo - v6_offset1));
    /* We are sure that the difference lies within the int range */
    ++s;
    uri->port_str = axutil_strdup(env, s);
    if(*s != '\0')
    {
        uri->port = (unsigned short)strtol(uri->port_str, &endstr, 10);
        if(*endstr == '\0')
        {
            return uri;
        }
        /* Invalid characters after ':' found */
    }
    axutil_uri_free(uri, env);
    return NULL;
}

/* Resolve relative to a base.  This means host/etc, and (crucially) path */
AXIS2_EXTERN axutil_uri_t *AXIS2_CALL
axutil_uri_resolve_relative(
    const axutil_env_t *env,
    const axutil_uri_t *base,
    axutil_uri_t *uri)
{
    AXIS2_PARAM_CHECK(env->error, base, NULL);
    AXIS2_PARAM_CHECK(env->error, uri, NULL);

    if(!uri || !base || !base->is_initialized || !uri->is_initialized)
    {
        return NULL;
    }
    /* The interesting bit is the path.  */
    if(!uri->path)
    {
        if(!uri->hostname)
        {
            /* is this compatible with is_initialised?  Harmless in any case */
            uri->path = base->path ? base->path : axutil_strdup(env, "/");
        }
        else
        {
            /* deal with the idiosyncracy of APR allowing path==NULL
             * without risk of breaking back-compatibility
             */
            uri->path = axutil_strdup(env, "/");
        }
    }
    else if(uri->path[0] != '/')
    {
        size_t baselen;
        const char *basepath = base->path ? base->path : "/";
        char *path = uri->path;
        char *temp = NULL;
        const char *base_end = strrchr(basepath, '/');

        temp = path;

        /* if base is nonsensical, bail out */
        if(basepath[0] != '/')
        {
            return NULL;
        }
        /* munch "up" components at the start, and chop them from base path */
        while(!strncmp(path, "../", 3))
        {
            while(base_end > basepath)
            {
                if(*--base_end == '/')
                {
                    break;
                }
            }
            path += 3;
        }
        /* munch "here" components at the start */
        while(!strncmp(path, "./", 2))
        {
            path += 2;
        }
        baselen = base_end - basepath + 1;
        uri->path = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * baselen + strlen(path) + 1);
        memcpy(uri->path, basepath, baselen);
        strcpy(uri->path + baselen, path);
        if(temp)
        {
            AXIS2_FREE(env->allocator, temp);
        }
    }

    /* The trivial bits are everything-but-path */
    if(!uri->scheme)
    {
        uri->scheme = axutil_strdup(env, base->scheme);
    }
    if(!uri->hostinfo)
    {
        uri->hostinfo = axutil_strdup(env, base->hostinfo);
    }
    if(!uri->user)
    {
        uri->user = axutil_strdup(env, base->user);
    }
    if(!uri->password)
    {
        uri->password = axutil_strdup(env, base->password);
    }
    if(!uri->hostname)
    {
        uri->hostname = axutil_strdup(env, base->hostname);
    }
    if(!uri->port_str)
    {
        uri->port_str = axutil_strdup(env, base->port_str);
    }
    if(!uri->hostent)
    {
        uri->hostent = base->hostent;
    }
    if(!uri->port)
    {
        uri->port = base->port;
    }
    uri->is_ipv6 = base->is_ipv6;

    return uri;
}

AXIS2_EXTERN axutil_uri_t *AXIS2_CALL
axutil_uri_parse_relative(
    const axutil_env_t *env,
    const axutil_uri_t *base,
    const char *uri)
{
    axutil_uri_t *uptr = NULL;
    axutil_uri_t *temp = NULL;

    uptr = axutil_uri_parse_string(env, uri);
    if(!uptr && AXIS2_SUCCESS != AXIS2_ERROR_GET_STATUS_CODE(env->error))
    {
        return uptr;
    }
    temp = uptr;
    uptr = axutil_uri_resolve_relative(env, base, uptr);

    if(!uptr)
    {
        axutil_uri_free(temp, env);
    }

    return uptr;
}
AXIS2_EXTERN axis2_port_t AXIS2_CALL
axutil_uri_port_of_scheme(
    const axis2_char_t *scheme_str)
{
    schemes_t *scheme;

    if(scheme_str)
    {
        for(scheme = schemes; scheme->name; ++scheme)
        {
            if(axutil_strcasecmp(scheme_str, scheme->name) == 0)
            {
                return scheme->default_port;
            }
        }
    }
    return 0;
}

AXIS2_EXTERN axutil_uri_t *AXIS2_CALL
axutil_uri_clone(
    const axutil_uri_t *uri,
    const axutil_env_t *env)
{
    axutil_uri_t *new_uri = NULL;

    new_uri = (axutil_uri_t *)axutil_uri_create(env);

    new_uri->scheme = axutil_strdup(env, uri->scheme);
    new_uri->hostinfo = axutil_strdup(env, uri->hostinfo);
    new_uri->user = axutil_strdup(env, uri->user);
    new_uri->password = axutil_strdup(env, uri->password);
    new_uri->hostname = axutil_strdup(env, uri->hostname);
    new_uri->port_str = axutil_strdup(env, uri->port_str);
    new_uri->path = axutil_strdup(env, uri->path);
    new_uri->query = axutil_strdup(env, uri->query);
    new_uri->fragment = axutil_strdup(env, uri->fragment);
    new_uri->hostent = uri->hostent;
    new_uri->port = uri->port;
    new_uri->is_initialized = uri->is_initialized;
    new_uri->dns_looked_up = uri->dns_looked_up;
    new_uri->dns_resolved = uri->dns_resolved;
    new_uri->is_ipv6 = uri->is_ipv6;

    return new_uri;
}

/* Unparse a axutil_uri_t structure to an URI string.
 * Optionally suppress the password for security reasons.
 */
AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axutil_uri_to_string(
    const axutil_uri_t *uri,
    const axutil_env_t *env,
    unsigned flags)
{
    axis2_char_t *ret = "";
    axis2_char_t *temp = NULL;
    AXIS2_ENV_CHECK(env, NULL);

    /* If suppressing the site part, omit both user name & scheme://hostname */
    if(!(flags & AXIS2_URI_UNP_OMITSITEPART))
    {

        /* Construct a "user:password@" string, honoring the passed
         * AXIS2_URI_UNP_ flags: */
        if(uri->user || uri->password)
        {
            ret = axutil_strcat(env, (uri->user && !(flags & AXIS2_URI_UNP_OMITUSER)) ? uri-> user
                : "", (uri->password && !(flags & AXIS2_URI_UNP_OMITPASSWORD)) ? ":" : "",
                (uri->password && !(flags & AXIS2_URI_UNP_OMITPASSWORD)) ? ((flags
                    & AXIS2_URI_UNP_REVEALPASSWORD) ? uri-> password : "XXXXXXXX") : "",
                ((uri->user && !(flags & AXIS2_URI_UNP_OMITUSER)) || (uri->password && !(flags
                    & AXIS2_URI_UNP_OMITPASSWORD))) ? "@" : "", NULL);
            temp = ret;
        }

        /* Construct scheme://site string */
        if(uri->hostname)
        {
            int is_default_port;
            const axis2_char_t *lbrk = "", *rbrk = "";

            if(uri->is_ipv6)
            { /* v6 literal */
                lbrk = "[";
                rbrk = "]";
            }

            is_default_port = (uri->port_str == NULL || uri->port == 0 || uri->port
                == axutil_uri_port_of_scheme(uri->scheme));

            if(uri->scheme)
            {
                ret = axutil_strcat(env, uri->scheme, "://", ret, lbrk, uri->hostname, rbrk,
                    is_default_port ? "" : ":", is_default_port ? "" : uri->port_str, NULL);
                if(temp)
                {
                    AXIS2_FREE(env->allocator, temp);
                }
                temp = ret;
            }
            else
            {
                /* Fixed to support Abbreviated URLs as in RFC2396.
                 * Thus, if no scheme, we omit "//" too, eventhough
                 * it is a part of authority.
                 */
                ret = axutil_strcat(env, ret, lbrk, uri->hostname, rbrk,
                    is_default_port ? "" : ":", is_default_port ? "" : uri->port_str, NULL);
                /*ret =
                 axutil_strcat(env, "//", ret, lbrk, uri->hostname, rbrk,
                 is_default_port ? "" : ":",
                 is_default_port ? "" : uri->port_str, NULL);*/
                if(temp)
                {
                    AXIS2_FREE(env->allocator, temp);
                }
                temp = ret;
            }
        }
    }

    /* Should we suppress all path info? */
    if(!(flags & AXIS2_URI_UNP_OMITPATHINFO))
    {
        /* Append path, query and fragment strings: */
        ret = axutil_strcat(env, ret, (uri->path) ? uri->path : "", (uri->query && !(flags
            & AXIS2_URI_UNP_OMITQUERY_ONLY)) ? "?" : "", (uri->query && !(flags
            & AXIS2_URI_UNP_OMITQUERY_ONLY)) ? uri-> query : "", (uri->fragment && !(flags
            & AXIS2_URI_UNP_OMITFRAGMENT_ONLY)) ? "#" : NULL, (uri->fragment && !(flags
            & AXIS2_URI_UNP_OMITFRAGMENT_ONLY)) ? uri-> fragment : NULL, NULL);
        if(temp)
        {
            AXIS2_FREE(env->allocator, temp);
        }
    }
    return ret;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axutil_uri_get_protocol(
    axutil_uri_t *uri,
    const axutil_env_t *env)
{
    return uri->scheme;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axutil_uri_get_server(
    axutil_uri_t *uri,
    const axutil_env_t *env)
{
    return uri->hostinfo;
}

AXIS2_EXTERN axis2_port_t AXIS2_CALL
axutil_uri_get_port(
    axutil_uri_t *uri,
    const axutil_env_t *env)
{
    return uri->port;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axutil_uri_get_host(
    axutil_uri_t *uri,
    const axutil_env_t *env)
{
    return uri->hostname;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axutil_uri_get_query(
    axutil_uri_t *uri,
    const axutil_env_t *env)
{
    return uri->query;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axutil_uri_get_fragment(
    axutil_uri_t *uri,
    const axutil_env_t *env)
{
    return uri->fragment;
}

AXIS2_EXTERN axis2_char_t *AXIS2_CALL
axutil_uri_get_path(
    axutil_uri_t *uri,
    const axutil_env_t *env)
{
    return uri->path;
}
