zoukankan      html  css  js  c++  java
  • 基于Linux,URL解析以及获取域名的IP地址。

    int http_parse_url(http_dest_t *dest, const char *url)
    {
        char        *d;
        const char  *p, *q;
        const char  *uri;
        int i;
    
        uri = url;
    
        if ((p = strstr(url, "://"))) {
            snprintf(dest->scheme, URL_SCHEME_LEN + 1, "%.*s", (int)(p - uri), uri);
            uri =  p + 3;
        } else {
            p = uri;
            strcpy(dest->scheme, "http");
        }
        if (!*uri || *uri == '/' || *uri == '.')
            goto nohost;
    
        p = strpbrk(uri, "/@");
        if (p && *p == '@') {
            /* username */
            for (q = uri, i = 0; (*q != ':') && (*q != '@'); q++)
                if (i < URL_USER_LEN) {
                    dest->user[i++] = *q;
                }
            /* password */
            if (*q == ':')
                for (q++, i = 0; (*q != ':') && (*q != '@'); q++)
                    if (i < URL_PWD_LEN) {
                        dest->password[i++] = *q;
                    }
    
            p++;
        } else {
            p = uri;
        }
    
        memset(dest->host, 0, MAX_HOST_NAME_LEN+1);
        for (i = 0; *p && (*p != '/') && (*p != ':'); p++) {
            if (i < MAX_HOST_NAME_LEN){
                dest->host[i++] = *p;
            }
        }
           
        /* port */
        if(strncmp(url, "https:", 6) == 0) {
            dest->port = 443;    
        } else {
            dest->port = 80;
        }
        if (*p == ':') {
            dest->port = 0;
            for (q = ++p; *q && (*q != '/'); q++)
                if (isdigit(*q)) {
                    dest->port = dest->port * 10 + (*q - '0');
                } else {
                    /* invalid port */
                    return -1;
                }
            p = q;
        }
    nohost:
        if (!*p)
            p = "/";
        if (strcasecmp(dest->scheme, "http") == 0 ||
            strcasecmp(dest->scheme, "https") == 0) {
            const char hexnums[] = "0123456789abcdef";
            d = dest->uri;
            while (*p != '') {
                if (!isspace(*p)) {
                    *d++ = *p++;
                } else {
                    *d++ = '%';
                    *d++ = hexnums[((unsigned int)*p) >> 4];
                    *d++ = hexnums[((unsigned int)*p) & 0xf];
                    p++;
                }
            }
            *d = '';
        }
        return 0;
    }

    以上代码解析出URL包含的信息,其结构体为:

    typedef struct http_dest_t {
        char scheme[URL_SCHEME_LEN];
        char host[MAX_HOST_NAME_LEN];
        char uri[MAX_URI_LEN];
    
        char    user[URL_USER_LEN+1];
        char    password[URL_PWD_LEN+1];
    
        int     port;
    }http_dest_t;

    如下函数解析域名的ip地址。支持IPV6与IPV4

    int util_resolv_domain_name(const char* domain_name,char* ipv4_addr,char* ipv6_addr,int* result_ind)
    {
        struct addrinfo *answer,hints,*addr_info_p;
        int ret;
        struct sockaddr_in *sinp4;
        struct sockaddr_in6 *sinp6;
        char* addr;
    
        if( result_ind )
        {
            *result_ind=0;
        }
    
        memset(&hints, 0, sizeof(hints));
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_flags = AI_PASSIVE;
    
        /*
         * The getaddrinfo() function allocates and initializes a linked list of addrinfo structures, one for each network address that matches node  and  service,  subject  to  any
           restrictions imposed by hints, and returns a pointer to the start of the list in res.  The items in the linked list are linked by the ai_next field.
         * */
        ret = getaddrinfo(domain_name, NULL, &hints, &answer);
        if ( !ret ) {
            for (addr_info_p = answer; addr_info_p != NULL; addr_info_p = addr_info_p->ai_next) {
                if(addr_info_p->ai_family == AF_INET) {
                    sinp4 = (struct sockaddr_in *)addr_info_p->ai_addr;
                    /*
                     * The  inet_ntoa()  function  converts  the Internet host address in, given in network byte order, to a string in IPv4 dotted-decimal notation.  The string is returned in a
                                statically allocated buffer, which subsequent calls will overwrite.
                     * */
                    addr = inet_ntoa( sinp4->sin_addr);
                    if( ipv4_addr ) {
                        strcpy(ipv4_addr,addr);
                    }
                    if( result_ind ) {
                        *result_ind=(*result_ind)|IPv4_EXIST_FLAG;
                    }
                } else if(addr_info_p->ai_family == AF_INET6) {
                    sinp6 = (struct sockaddr_in6 *)addr_info_p->ai_addr;
                    if( ipv6_addr ) {
                        sprintf(ipv6_addr
                                ,"%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x"
                                ,sinp6->sin6_addr.s6_addr[0]
                                ,sinp6->sin6_addr.s6_addr[1]
                                ,sinp6->sin6_addr.s6_addr[2]
                                ,sinp6->sin6_addr.s6_addr[3]
                                ,sinp6->sin6_addr.s6_addr[4]
                                ,sinp6->sin6_addr.s6_addr[5]
                                ,sinp6->sin6_addr.s6_addr[6]
                                ,sinp6->sin6_addr.s6_addr[7]
                                ,sinp6->sin6_addr.s6_addr[8]
                                ,sinp6->sin6_addr.s6_addr[9]
                                ,sinp6->sin6_addr.s6_addr[10]
                                ,sinp6->sin6_addr.s6_addr[11]
                                ,sinp6->sin6_addr.s6_addr[12]
                                ,sinp6->sin6_addr.s6_addr[13]
                                ,sinp6->sin6_addr.s6_addr[14]
                                ,sinp6->sin6_addr.s6_addr[15]
                                );
                    }
                    if( result_ind ) {
                        *result_ind=(*result_ind)|IPv6_EXIST_FLAG;
                    }
                }
            }
            freeaddrinfo(answer);
        } else {
            return -1;
        }
        return 0;
    }
  • 相关阅读:
    hdu3746 KMP的next数组应用,求项链首尾项链循环
    hdu4067 费用流(混合欧拉的宽展和延伸)
    hdu4067 费用流(混合欧拉的宽展和延伸)
    hdu1501 记忆化搜索
    hdu1501 记忆化搜索
    hdu1316 大数
    hdu1316 大数
    hdu4411 经典费用里建图
    hdu4411 经典费用里建图
    hdu4768 非常规的二分
  • 原文地址:https://www.cnblogs.com/fogcell/p/7070361.html
Copyright © 2011-2022 走看看