mgurlparser.cpp

来自「一款LINUX下的下载软件」· C++ 代码 · 共 968 行 · 第 1/2 页

CPP
968
字号

                if ( 256 < slen )
                    return false; //server too long

                char temp[ 256 ];

                memcpy( temp, s, slen );

                temp[ slen ] = 0;

                server = std::string( temp );

                if ( plen > 5 )
                    return false; //max port is 65535

                char prt[ 6 ];

                memcpy( prt, ck + 1, plen );

                prt[ plen ] = 0;

                //检查是否都为数字?
                for ( int i = 0;i < plen;i++ )
                {
                    if ( prt[ i ] < '0' || prt[ i ] > '9' )
                        return false; //wrong port
                }

                port = atoi( prt );

                return true;
            }

        }
        else
        { //url wrong format
            return false;
        }
    }
    else //到了结尾没有@
    {
        p = url;

        while ( *p != '/' && *p != 0 )
            p++;

        p++;

        while ( *p != '/' && *p != 0 )
            p++;

        p++;

        char *s = p;

        while ( *p != '/' && *p != 0 )
            p++;

        if ( *p == '/' )
        {
            int len = p - s;	//包含端口在内的长度
            //检查是否包含了端口在内
            char *ck = p - 1;

            while ( *ck != ':' && ck > s )
                ck--;

            if ( ck == s )
            { //无端口

                if ( 256 < len + 1 )
                    return false; //server too long

                char temp[ 256 ];

                memcpy( temp, s, len );

                temp[ len ] = 0;

                server = std::string( temp );

                //按协议类型给出缺省的端口,以后可括从
                port = GetDefaultPort( m_protocol );

                return true;

            }
            else
            {
                //有端口
                int slen = ck - s;
                int plen = len - slen - 1;

                if ( 256 < slen )
                    return false;

                char temp[ 256 ];

                memcpy( temp, s, slen );

                temp[ slen ] = 0;

                server = std::string( temp );

                if ( plen > 5 )
                    return false; //max port is 65535

                char prt[ 6 ];

                memcpy( prt, ck + 1, plen );

                prt[ plen ] = 0;

                //检查是否都为数字?
                for ( int i = 0;i < plen;i++ )
                {
                    if ( prt[ i ] < '0' || prt[ i ] > '9' )
                        return false; //wrong port
                }

                port = atoi( prt );

                return true;
            }
        }
        else
        {
            return false;
        }
    }
}


int CUrlParser::GetDefaultPort( _PROTYPE protocol )
{
    //按协议类型给出缺省的端口,以后可括从

    switch ( protocol )
    {

        case FTP_PROTOCOL:
        return 21;

        case HTTP_PROTOCOL:
        return 80;

        default:
        return 0;
    }

}

//去掉用户和密码的url
bool CUrlParser::GetRawUrl( std::string& fullurl, std::string& rawurl )
{
    //ftp://user:pa@ss@www.abc.com/fdfas.txt,去掉//到@之间的内容。

    char url[ 512 ];
    strcpy( url, fullurl.c_str() );

    char* p = url;

    while ( *p != '/' && *p != 0 )
        p++;

    if ( *p == 0 )
        return false;

    p++;

    while ( *p != '/' && *p != 0 )
        p++;

    if ( *p == 0 )
        return false;

    p++;

    //这里p指向'u'
    char* h = p;

    p = url + strlen( url );
findat:
    while ( *p != '@' && p != url )
        p--;
	//根据提交的BUG,有时后面会有这个@字符,添加检查过滤无效的@	if ( *p == '@' )	{		//检查是否前方的'/'位置是否是第2个'/'		char *q=p;		while ( *q != '/' && q > url )
            q--;		if( q == url ) return false; //其实不会出现这个情况		char *m = url; //从前向后找第二个'/',应该等于q		while ( *m != '/' ) m++;		if( q != m + 1 ) { p--; goto findat; }	}
    if ( p == url )
    {
        rawurl = fullurl;

    }
    else
    {
        p++;
        char temp[ 512 ];
        memcpy( temp, url, h - url );
        strcpy( &temp[ h - url ], p );
        rawurl = std::string( temp );
    }

    return true;
}

//从url中获得路径和文件的数据
//不检查是否为目录,也不进行编码
bool CUrlParser::GetPathFile( std::string& fullurl, std::string& pathfile )
{
    //ftp://dfasdfas.com/dfad/dfs =》/dfad/dfs
    //找第三个'/'

    char url[ 512 ];
    strcpy( url, fullurl.c_str() );

    char *p = url;

    while ( *p != '/' && *p != 0 )
        p++;

    if ( *p == 0 )
        return false;

    p++;

    while ( *p != '/' && *p != 0 )
        p++;

    if ( *p == 0 )
        return false;

    p++;

    while ( *p != '/' && *p != 0 )
        p++;

    if ( *p == 0 )
        return false;

    if ( 510 < int( strlen( url ) - ( p - url ) ) )
    {
        return false; //too long
    }

    char temp[ 512 ];
    memcpy( temp, p, strlen( url ) - ( p - url ) );
    temp[ strlen( url ) - ( p - url ) ] = 0;
    pathfile = std::string( temp );
    return true;
}

//提取refer
bool CUrlParser::GetRefer( std::string rawurl, std::string& refer )
{

    if ( !m_refer.empty() )
        return true; //already have set refer

    //找最后一个'/',之前的就算refer

    char url[ 512 ];

    strcpy( url, rawurl.c_str() );

    char* p = url + strlen( url );

    while ( p != url && *p != '/' )
        p--;

    if ( p == url )
    {
        refer.clear();
    }
    else
    {
        if ( 512 < p - url )
            return false;

        char temp[ 512 ];

        memcpy( temp, url, p - url );

        temp[ p - url ] = 0;

        refer = std::string( temp );

    }

    return true;
}

void CUrlParser::Precode( const std::string& pathfile, std::string& escfile )
{
    char * str_new;
    int str_new_len;
    char *ptr, *pptr;

    // get the length of the new string
    ptr = ( char* ) pathfile.c_str();
    str_new_len = 0;

    while ( *ptr != '\0' )
    {
        if ( *ptr == '%' )
        {
            if ( isxdigit( ptr[ 1 ] ) && isxdigit( ptr[ 2 ] ) )
            {
                str_new_len += 3;
                ptr += 3;
            }
            else
            {
                str_new_len += 3;
                ptr += 1;
            }
        }
        else if ( URL_UNSAFE_CHAR( *ptr ) && !URL_RESERVED_CHAR( *ptr ) )
        {
            str_new_len += 3;
            ptr += 1;
        }
        else
        {
            str_new_len += 1;
            ptr += 1;
        }
    } // end of while

    /* encode the url */
    str_new = new char[ str_new_len + 1 ];

    ptr = ( char* ) pathfile.c_str();

    pptr = str_new;

    while ( *ptr != '\0' )
    {
        if ( *ptr == '%' )
        {
            if ( isxdigit( ptr[ 1 ] ) && isxdigit( ptr[ 2 ] ) )
            {
                strncpy( pptr, ptr, 3 );
                ptr += 3;
                pptr += 3;
            }
            else
            {
                strncpy( pptr, "%25", 3 );
                ptr += 1;
                pptr += 3;
            }
        }
        else if ( URL_UNSAFE_CHAR( *ptr ) && !URL_RESERVED_CHAR( *ptr ) )
        {
            pptr[ 0 ] = '%';
            pptr[ 1 ] = XDIGIT_TO_XCHAR( ( ( unsigned char ) * ptr ) >> 4 );
            pptr[ 2 ] = XDIGIT_TO_XCHAR( ( ( unsigned char ) * ptr ) & 0x0f );
            ptr += 1;
            pptr += 3;
        }
        else
        {
            *pptr = *ptr;
            ptr += 1;
            pptr += 1;
        }
    } // end of while

    *pptr = '\0';

    escfile = std::string( str_new );

    delete[] str_new;

}

std::string CUrlParser::GetRawUrl()
{
    return m_raw;
}

//把user,pass添加到url中
bool CUrlParser::RebuildUrl(
    std::string& fullurl, std::string user, std::string pass, std::string& rebuild )
{
    std::string raw;

    if ( user.empty() || pass.empty() )
        return false;

    if ( !GetRawUrl( fullurl, raw ) )
        return false;

    string::size_type pos = raw.find( "//", 0 );

    if ( pos == string::npos )
        return false;

    raw.insert( pos + 2, user + ":" + pass + "@" );

    rebuild = raw;

    return true;
}

void CUrlParser::SetRefer( std::string& refer )
{
    m_refer = refer;
}

bool CUrlParser::IsValidMirror()
{
    return m_bValidMirrorUrl;
}

void CUrlParser::UnEscape( std::string& str )
{
    char buf[ 512 ];
    strcpy( buf, str.c_str() );
    UnEscape( buf );
    str = std::string( buf );
}

void CUrlParser::UnEscape ( char *s )
{
    char * t = s;
    char *h = s;

    for ( ; *h; h++, t++ )
    {
        if ( *h != '%' )
        {
            *t = *h;
        }
        else
        {
            unsigned char c;

            if ( !h[ 1 ] || !h[ 2 ] || !( ISXDIGIT ( h[ 1 ] ) && ISXDIGIT ( h[ 2 ] ) ) )
            {
                *t = *h;
                continue;
            }

            //c = X2DIGITS_TO_NUM (h[1], h[2]);
            //			printf("h[1]=%c,h[2]=%c\n",h[1],h[2]);

            unsigned char k, m;

            k = XCHAR_TO_XDIGIT( h[ 1 ] );

            m = XCHAR_TO_XDIGIT( h[ 2 ] );

            c = k * 16 + m;

            //	  		if (c == 0)
            //	    	{
            //DBGOUT("c==0");
            //				*t=*h;
            //				continue;
            //			}

            *t = c;

            h += 2;
        }
    }

    *t = '\0';
}

⌨️ 快捷键说明

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