⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 apr_uri.c

📁 Apache官方在今天放出产品系列2.2的最新版本2.2.11的源码包 最流行的HTTP服务器软件之一
💻 C
📖 第 1 页 / 共 2 页
字号:
 * 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)/* 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 */APU_DECLARE(apr_status_t) apr_uri_parse(apr_pool_t *p, const char *uri,                                         apr_uri_t *uptr){    const char *s;    const char *s1;    const char *hostinfo;    char *endstr;    int port;    int v6_offset1 = 0, v6_offset2 = 0;    /* Initialize the structure. parse_uri() and parse_uri_components()     * can be called more than once per request.     */    memset (uptr, '\0', sizeof(*uptr));    uptr->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.  -djg     */    if (uri[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[1] == '/' && uri[2] != '/') {            s = uri + 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;        while ((uri_delims[*(unsigned char *)s] & NOTEND_PATH) == 0) {            ++s;        }        if (s != uri) {            uptr->path = apr_pstrmemdup(p, uri, s - uri);        }        if (*s == 0) {            return APR_SUCCESS;        }        if (*s == '?') {            ++s;            s1 = strchr(s, '#');            if (s1) {                uptr->fragment = apr_pstrdup(p, s1 + 1);                uptr->query = apr_pstrmemdup(p, s, s1 - s);            }            else {                uptr->query = apr_pstrdup(p, s);            }            return APR_SUCCESS;        }        /* otherwise it's a fragment */        uptr->fragment = apr_pstrdup(p, s + 1);        return APR_SUCCESS;    }    /* find the scheme: */    s = uri;    while ((uri_delims[*(unsigned char *)s] & NOTEND_SCHEME) == 0) {        ++s;    }    /* scheme must be non-empty and followed by : */    if (s == uri || s[0] != ':') {        goto deal_with_path;        /* backwards predicted taken! */    }    uptr->scheme = apr_pstrmemdup(p, uri, s - uri);    if (s[1] != '/' || s[2] != '/') {        uri = s + 1;        goto deal_with_path;    }    s += 3;deal_with_authority:    hostinfo = s;    while ((uri_delims[*(unsigned char *)s] & NOTEND_HOSTINFO) == 0) {        ++s;    }    uri = s;        /* whatever follows hostinfo is start of uri */    uptr->hostinfo = apr_pstrmemdup(p, hostinfo, uri - hostinfo);    /* 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 definately 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 == '[') {            v6_offset1 = 1;            v6_offset2 = 2;            s = memchr(hostinfo, ']', uri - hostinfo);            if (s == NULL) {                return APR_EGENERAL;            }            if (*++s != ':') {                s = NULL; /* no port */            }        }        else {            s = memchr(hostinfo, ':', uri - hostinfo);        }        if (s == NULL) {            /* we expect the common case to have no port */            uptr->hostname = apr_pstrmemdup(p,                                            hostinfo + v6_offset1,                                            uri - hostinfo - v6_offset2);            goto deal_with_path;        }        uptr->hostname = apr_pstrmemdup(p,                                        hostinfo + v6_offset1,                                        s - hostinfo - v6_offset2);        ++s;        uptr->port_str = apr_pstrmemdup(p, s, uri - s);        if (uri != s) {            port = strtol(uptr->port_str, &endstr, 10);            uptr->port = port;            if (*endstr == '\0') {                goto deal_with_path;            }            /* Invalid characters after ':' found */            return APR_EGENERAL;        }        uptr->port = apr_uri_port_of_scheme(uptr->scheme);        goto deal_with_path;    }    /* first colon delimits username:password */    s1 = memchr(hostinfo, ':', s - hostinfo);    if (s1) {        uptr->user = apr_pstrmemdup(p, hostinfo, s1 - hostinfo);        ++s1;        uptr->password = apr_pstrmemdup(p, s1, s - s1);    }    else {        uptr->user = apr_pstrmemdup(p, hostinfo, s - hostinfo);    }    hostinfo = s + 1;    goto deal_with_host;}/* 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://www.mcom.com/newsref/std/tunneling_ssl.html * for the format of the "CONNECT host:port HTTP/1.0" request */APU_DECLARE(apr_status_t) apr_uri_parse_hostinfo(apr_pool_t *p,                                                  const char *hostinfo,                                                  apr_uri_t *uptr){    const char *s;    char *endstr;    const char *rsb;    int v6_offset1 = 0;    /* Initialize the structure. parse_uri() and parse_uri_components()     * can be called more than once per request.     */    memset(uptr, '\0', sizeof(*uptr));    uptr->is_initialized = 1;    uptr->hostinfo = apr_pstrdup(p, 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 ((rsb = strchr(hostinfo, ']')) == NULL ||            *(rsb + 1) != ':') {            return APR_EGENERAL;        }        /* literal IPv6 address */        s = rsb + 1;        ++hostinfo;        v6_offset1 = 1;    }    else {        s = strchr(hostinfo, ':');    }    if (s == NULL) {        return APR_EGENERAL;    }    uptr->hostname = apr_pstrndup(p, hostinfo, s - hostinfo - v6_offset1);    ++s;    uptr->port_str = apr_pstrdup(p, s);    if (*s != '\0') {        uptr->port = (unsigned short) strtol(uptr->port_str, &endstr, 10);        if (*endstr == '\0') {            return APR_SUCCESS;        }        /* Invalid characters after ':' found */    }    return APR_EGENERAL;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -