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

📄 uri.c

📁 电驴下载工具eMule0.47aVeryCD的源代码,可作分析测试也可用于P2P软件的开发研究.
💻 C
📖 第 1 页 / 共 3 页
字号:

    return FALSE;

}

/************************************************************************
*	Function :	remove_escaped_chars
*
*	Parameters :
*		INOUT char *in ;	string of characters to be modified
*		INOUT int *size ;	size limit for the number of characters
*
*	Description : removes http escaped characters such as: "%20" and 
*		replaces them with their character representation. i.e. 
*		"hello%20foo" -> "hello foo". The input IS MODIFIED in place. 
*		(shortened). Extra characters are replaced with NULL.
*
*	Return : int ;
*		UPNP_E_SUCCESS
*
*	Note :
************************************************************************/
int
remove_escaped_chars( INOUT char *in,
                      INOUT int *size )
{
    int i = 0;

    for( i = 0; i < *size; i++ ) {
        replace_escaped( in, i, size );
    }
    return UPNP_E_SUCCESS;
}

/************************************************************************
*	Function :	remove_dots
*
*	Parameters :
*		char *in ;	string of characters from which "dots" have to be 
*					removed
*		int size ;	size limit for the number of characters
*
*	Description : Removes ".", and ".." from a path. If a ".." can not
*		be resolved (i.e. the .. would go past the root of the path) an 
*		error is returned. The input IS modified in place.)
*
*	Return : int ;
*		UPNP_E_SUCCESS - On Success
*		UPNP_E_OUTOF_MEMORY - On failure to allocate memory
*		UPNP_E_INVALID_URL - Failure to resolve URL
*
*	Note :
*		Examples
*       char path[30]="/../hello";
*       remove_dots(path, strlen(path)) -> UPNP_E_INVALID_URL
*       char path[30]="/./hello";
*       remove_dots(path, strlen(path)) -> UPNP_E_SUCCESS, 
*       in = "/hello"
*       char path[30]="/./hello/foo/../goodbye" -> 
*       UPNP_E_SUCCESS, in = "/hello/goodbye"

************************************************************************/
int
remove_dots( char *in,
             int size )
{
    char *copyTo = in;
    char *copyFrom = in;
    char *max = in + size;
    char **Segments = NULL;
    int lastSegment = -1;

    Segments = malloc( sizeof( char * ) * size );

    if( Segments == NULL )
        return UPNP_E_OUTOF_MEMORY;

    Segments[0] = NULL;
    DBGONLY( UpnpPrintf
             ( UPNP_ALL, API, __FILE__, __LINE__,
               "REMOVE_DOTS: before: %s\n", in ) );
    while( ( copyFrom < max ) && ( *copyFrom != '?' )
           && ( *copyFrom != '#' ) ) {

        if( ( ( *copyFrom ) == '.' )
            && ( ( copyFrom == in ) || ( *( copyFrom - 1 ) == '/' ) ) ) {
            if( ( copyFrom + 1 == max )
                || ( *( copyFrom + 1 ) == '/' ) ) {

                copyFrom += 2;
                continue;
            } else if( ( *( copyFrom + 1 ) == '.' )
                       && ( ( copyFrom + 2 == max )
                            || ( *( copyFrom + 2 ) == '/' ) ) ) {
                copyFrom += 3;

                if( lastSegment > 0 ) {
                    copyTo = Segments[--lastSegment];
                } else {
                    free( Segments );
                    //TRACE("ERROR RESOLVING URL, ../ at ROOT");
                    return UPNP_E_INVALID_URL;
                }
                continue;
            }
        }

        if( ( *copyFrom ) == '/' ) {

            lastSegment++;
            Segments[lastSegment] = copyTo + 1;
        }
        ( *copyTo ) = ( *copyFrom );
        copyTo++;
        copyFrom++;
    }
    if( copyFrom < max ) {
        while( copyFrom < max ) {
            ( *copyTo ) = ( *copyFrom );
            copyTo++;
            copyFrom++;
        }
    }
    ( *copyTo ) = 0;
    free( Segments );
    DBGONLY( UpnpPrintf
             ( UPNP_ALL, API, __FILE__, __LINE__,
               "REMOVE_DOTS: after: %s\n", in ) );
    return UPNP_E_SUCCESS;
}

/************************************************************************
*	Function :	resolve_rel_url
*
*	Parameters :
*		char * base_url ;	Base URL
*		char * rel_url ;	Relative URL
*
*	Description : resolves a relative url with a base url returning a NEW 
*		(dynamically allocated with malloc) full url. If the base_url is 
*		NULL, then a copy of the  rel_url is passed back if the rel_url 
*		is absolute then a copy of the rel_url is passed back if neither 
*		the base nor the rel_url are Absolute then NULL is returned.
*		otherwise it tries and resolves the relative url with the base 
*		as described in: http://www.ietf.org/rfc/rfc2396.txt (RFCs 
*		explaining URIs) 
*       : resolution of '..' is NOT implemented, but '.' is resolved 
*
*	Return : char * ;
*
*	Note :
************************************************************************/
char *
resolve_rel_url( char *base_url,
                 char *rel_url )
{
    uri_type base;
    uri_type rel;
    char temp_path = '/';

    int i = 0;
    char *finger = NULL;

    char *last_slash = NULL;

    char *out = NULL;
    char *out_finger = NULL;

    if( base_url && rel_url ) {
        out =
            ( char * )malloc( strlen( base_url ) + strlen( rel_url ) + 2 );
        out_finger = out;
    } else {
        if( rel_url )
            return strdup( rel_url );
        else
            return NULL;
    }

    if( out == NULL ) {
        return NULL;
    }

    if( ( parse_uri( rel_url, strlen( rel_url ), &rel ) ) == HTTP_SUCCESS ) {

        if( rel.type == ABSOLUTE ) {

            strcpy( out, rel_url );
        } else {

            if( ( parse_uri( base_url, strlen( base_url ), &base ) ==
                  HTTP_SUCCESS )
                && ( base.type == ABSOLUTE ) ) {

                if( strlen( rel_url ) == 0 ) {
                    strcpy( out, base_url );
                } else {
                    memcpy( out, base.scheme.buff, base.scheme.size );
                    out_finger += base.scheme.size;
                    ( *out_finger ) = ':';
                    out_finger++;

                    if( rel.hostport.text.size > 0 ) {
                        sprintf( out_finger, "%s", rel_url );
                    } else {
                        if( base.hostport.text.size > 0 ) {
                            memcpy( out_finger, "//", 2 );
                            out_finger += 2;
                            memcpy( out_finger, base.hostport.text.buff,
                                    base.hostport.text.size );
                            out_finger += base.hostport.text.size;
                        }

                        if( rel.path_type == ABS_PATH ) {
                            strcpy( out_finger, rel_url );

                        } else {

                            if( base.pathquery.size == 0 ) {
                                base.pathquery.size = 1;
                                base.pathquery.buff = &temp_path;
                            }

                            finger = out_finger;
                            last_slash = finger;
                            i = 0;

                            while( ( i < base.pathquery.size ) &&
                                   ( base.pathquery.buff[i] != '?' ) ) {
                                ( *finger ) = base.pathquery.buff[i];
                                if( base.pathquery.buff[i] == '/' )
                                    last_slash = finger + 1;
                                i++;
                                finger++;

                            }
                            i = 0;
                            strcpy( last_slash, rel_url );
                            if( remove_dots( out_finger,
                                             strlen( out_finger ) ) !=
                                UPNP_E_SUCCESS ) {
                                free( out );
                                //free(rel_url);
                                return NULL;
                            }
                        }

                    }
                }
            } else {
                free( out );
                //free(rel_url);
                return NULL;
            }
        }
    } else {
        free( out );
        //free(rel_url);            
        return NULL;
    }

    //free(rel_url);
    return out;
}

/************************************************************************
*	Function :	parse_uri
*
*	Parameters :
*		char * in ;	character string containing uri information to be 
*					parsed
*		int max ;	maximum limit on the number of characters
*		uri_type * out ; out parameter which will have the parsed uri
*					information	
*
*	Description : parses a uri as defined in http://www.ietf.org/rfc/
*		rfc2396.txt (RFC explaining URIs)
*		Handles absolute, relative, and opaque uris. Parses into the 
*		following pieces: scheme, hostport, pathquery, fragment (path and
*		query are treated as one token)
*       Caller should check for the pieces they require.
*
*	Return : int ;
*
*	Note :
************************************************************************/
int
parse_uri( char *in,
           int max,
           uri_type * out )
{
    int begin_path = 0;
    int begin_hostport = 0;
    int begin_fragment = 0;

    if( ( begin_hostport = parse_scheme( in, max, &out->scheme ) ) ) {
        out->type = ABSOLUTE;
        out->path_type = OPAQUE_PART;
        begin_hostport++;
    } else {
        out->type = RELATIVE;
        out->path_type = REL_PATH;
    }

    if( ( ( begin_hostport + 1 ) < max ) && ( in[begin_hostport] == '/' )
        && ( in[begin_hostport + 1] == '/' ) ) {
        begin_hostport += 2;

        if( ( begin_path = parse_hostport( &in[begin_hostport],
                                           max - begin_hostport,
                                           &out->hostport ) ) >= 0 ) {
            begin_path += begin_hostport;
        } else
            return begin_path;

    } else {
        out->hostport.IPv4address.sin_port = 0;
        out->hostport.IPv4address.sin_addr.s_addr = 0;
        out->hostport.text.size = 0;
        out->hostport.text.buff = 0;
        begin_path = begin_hostport;
    }

    begin_fragment =
        parse_uric( &in[begin_path], max - begin_path,
                    &out->pathquery ) + begin_path;

    if( ( out->pathquery.size ) && ( out->pathquery.buff[0] == '/' ) ) {
        out->path_type = ABS_PATH;
    }

    if( ( begin_fragment < max ) && ( in[begin_fragment] == '#' ) ) {
        begin_fragment++;
        parse_uric( &in[begin_fragment], max - begin_fragment,
                    &out->fragment );
    } else {
        out->fragment.buff = NULL;
        out->fragment.size = 0;
    }
    return HTTP_SUCCESS;
}

/************************************************************************
*	Function :	parse_uri_and_unescape
*
*	Parameters :
*		char * in ;	
*		int max ;	
*		uri_type * out ;	
*
*	Description : Same as parse_uri, except that all strings are 
*		unescaped (%XX replaced by chars)
*
*	Return : int ;
*
*	Note: This modifies 'pathquery' and 'fragment' parts of the input
************************************************************************/
int
parse_uri_and_unescape( char *in,
                        int max,
                        uri_type * out )
{
    int ret;

    if( ( ret = parse_uri( in, max, out ) ) != HTTP_SUCCESS )
        return ret;
    if( out->pathquery.size > 0 )
        remove_escaped_chars( out->pathquery.buff, &out->pathquery.size );
    if( out->fragment.size > 0 )
        remove_escaped_chars( out->fragment.buff, &out->fragment.size );
    return HTTP_SUCCESS;
}

⌨️ 快捷键说明

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