跨平台http地址解析

7 篇文章 0 订阅

有时候会遇到需要解析http地址中的IP地址,端口和后面的接口,windows有现成的函数可以解析,linux也有库能解析,不过就是为了这么个小功能带一个库有点杀鸡牛刀了。

我们需求很简单就是解析出ip和端口以及后面的接口字符串而已,不多说,直接上干货

//定义解析结果的结构体

typedef struct urlitem
{
    string url;
    string fullpath;
    string query;
    std::map <string,string> param;
    string     prot;
    int        port;//端口
    string host ;//IP地址
    string path ;//接口字符串
    string file;
    string officalhost;
    std::vector <string> aliases;
    std::vector <string> ip;
};

//解析URL urlin为HTTP的URL地址 out结果结构体 其实也可以解析出附带参数什么的,自己根据需要改改,举一反三
bool urlparse(std::string urlin, urlitem & out) {
    bool ret = false;
    int i = 0;
#ifdef WIN32
    if (_stricmp(urlin.substr(0, 4).c_str(), "http") != 0)
#else
    if (strcasecmp(urlin.substr(0, 4).c_str(), "http") != 0)
#endif    
        return false;

    int lastpos = 0;
    int pos = 0;
    std::string childs[10];
    std::string temp;
    int idx = 0;
    out.url = urlin;
    // 查找‘?’
    out.fullpath = urlin;
    pos = urlin.find('?', 0);
    if (pos >= 0) {
        out.fullpath = urlin.substr(0, pos);
        out.query = urlin.substr(pos+1);
    }

    // 分析query以 & 分割参数对,以=分割 k-v
    lastpos = 0;
    for (i = 0; i < out.query.length(); i++) {
        if (out.query[i] == '&') {
            temp = out.query.substr(lastpos, i - lastpos);
            pos = temp.find('=', 0);
            if (pos >= 0) {
                out.param[temp.substr(0, pos)] = temp.substr(pos+1);
            }
            lastpos = i + 1;
        }
    }

    temp = out.query.substr(lastpos);
    pos = temp.find('=', 0);
    if (pos >= 0) {
        out.param[temp.substr(0, pos)] = temp.substr(pos + 1);
    }
    lastpos = 0;
    idx = 0;
    for (i = 0; i < out.fullpath.length(); i++) {
        if (out.fullpath[i] == ':') {
            childs[idx] = out.fullpath.substr(lastpos, i - lastpos);
            lastpos = i + 1;
            idx++;
            break;
        }
    }

    out.prot = childs[0];
    out.port = 80;
    std::string fullpath = out.fullpath.substr(out.prot.length() + 3);
    pos = fullpath.find('/');
    if (pos >= 0) {
        out.host = fullpath.substr(0, pos);
        out.path = fullpath.substr(pos);
    }else if (pos = fullpath.find('\\') >= 0) {
        out.host = fullpath.substr(0, pos);
        out.path = fullpath.substr(pos);
    }
    pos = out.host.find(':');
    if (pos >= 0) {
        out.port = atoi(out.host.substr(pos+1).c_str());
        out.host = out.host.substr(0, pos);
    }
    pos = out.path.rfind('/');
    if (pos >= 0) {
        out.file = out.path.substr(pos + 1);
    }else if (pos = out.path.rfind('\\') >= 0) {
        out.file = out.path.substr(pos + 1);
    }
    struct hostent *hptr;
    char **pptr;
    if ((hptr = gethostbyname(out.host.c_str())) != 0) {
        if (hptr->h_name != 0)
            out.officalhost = hptr->h_name;
        for (pptr = hptr->h_aliases; *pptr != NULL; pptr++)
            out.aliases.push_back(*pptr);
        switch (hptr->h_addrtype){
        case AF_INET:
            //case AF_INET6:
            pptr = hptr->h_addr_list;
            for (; *pptr != NULL; pptr++) {
                out.ip.push_back(inet_ntoa(*((in_addr *)*pptr)));
            }
            break;
        default:
            break;
        }
    }

    return ret;
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值