📄 uri.c
字号:
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2003 Intel Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
/************************************************************************
* Purpose: This file contains functions for uri, url parsing utility.
************************************************************************/
#include "uri.h"
#ifdef _WIN32
#include "ws2tcpip.h"
#define strncasecmp strnicmp
#endif
/************************************************************************
* Function : is_reserved
*
* Parameters :
* char in ; char to be matched for RESERVED characters
*
* Description : Returns a 1 if a char is a RESERVED char as defined in
* http://www.ietf.org/rfc/rfc2396.txt RFC explaining URIs)
*
* Return : int ;
*
* Note :
************************************************************************/
int
is_reserved( char in )
{
if( strchr( RESERVED, in ) )
return 1;
else
return 0;
}
/************************************************************************
* Function : is_mark
*
* Parameters :
* char in ; character to be matched for MARKED characters
*
* Description : Returns a 1 if a char is a MARK char as defined in
* http://www.ietf.org/rfc/rfc2396.txt (RFC explaining URIs)
*
* Return : int ;
*
* Note :
************************************************************************/
int
is_mark( char in )
{
if( strchr( MARK, in ) )
return 1;
else
return 0;
}
/************************************************************************
* Function : is_unreserved
*
* Parameters :
* char in ; character to be matched for UNRESERVED characters
*
* Description : Returns a 1 if a char is an unreserved char as defined in
* http://www.ietf.org/rfc/rfc2396.txt (RFC explaining URIs)
*
* Return : int ;
*
* Note :
************************************************************************/
int
is_unreserved( char in )
{
if( isalnum( in ) || ( is_mark( in ) ) )
return 1;
else
return 0;
}
/************************************************************************
* Function : is_escaped
*
* Parameters :
* char * in ; character to be matched for ESCAPED characters
*
* Description : Returns a 1 if a char[3] sequence is escaped as defined
* in http://www.ietf.org/rfc/rfc2396.txt (RFC explaining URIs)
* size of array is NOT checked (MUST be checked by caller)
*
* Return : int ;
*
* Note :
************************************************************************/
int
is_escaped( char *in )
{
if( ( in[0] == '%' ) && ( isxdigit( in[1] ) ) && isxdigit( in[2] ) ) {
return 1;
} else
return 0;
}
/************************************************************************
* Function : replace_escaped
*
* Parameters :
* char * in ; string of characters
* int index ; index at which to start checking the characters
* int *max ;
*
* Description : Replaces an escaped sequence with its unescaped version
* as in http://www.ietf.org/rfc/rfc2396.txt (RFC explaining URIs)
* Size of array is NOT checked (MUST be checked by caller)
*
* Return : int ;
*
* Note : This function modifies the string. If the sequence is an
* escaped sequence it is replaced, the other characters in the
* string are shifted over, and NULL characters are placed at the
* end of the string.
************************************************************************/
int
replace_escaped( char *in,
int index,
int *max )
{
int tempInt = 0;
char tempChar = 0;
int i = 0;
int j = 0;
if( ( in[index] == '%' ) && ( isxdigit( in[index + 1] ) )
&& isxdigit( in[index + 2] ) ) {
//Note the "%2x", makes sure that we convert a maximum of two
//characters.
if( sscanf( &in[index + 1], "%2x", &tempInt ) != 1 )
return 0;
tempChar = ( char )tempInt;
for( i = index + 3, j = index; j < ( *max ); i++, j++ ) {
in[j] = tempChar;
if( i < ( *max ) )
tempChar = in[i];
else
tempChar = 0;
}
( *max ) -= 2;
return 1;
} else
return 0;
}
/************************************************************************
* Function : parse_uric
*
* Parameters :
* char *in ; string of characters
* int max ; maximum limit
* token *out ; token object where the string of characters is
* copied
*
* Description : Parses a string of uric characters starting at in[0]
* as defined in http://www.ietf.org/rfc/rfc2396.txt (RFC explaining
* URIs)
*
* Return : int ;
*
* Note :
************************************************************************/
int
parse_uric( char *in,
int max,
token * out )
{
int i = 0;
while( ( i < max )
&& ( ( is_unreserved( in[i] ) ) || ( is_reserved( in[i] ) )
|| ( ( i + 2 < max ) && ( is_escaped( &in[i] ) ) ) ) ) {
i++;
}
out->size = i;
out->buff = in;
return i;
}
/************************************************************************
* Function : copy_sockaddr_in
*
* Parameters :
* const struct sockaddr_in *in ; Source socket address object
* struct sockaddr_in *out ; Destination socket address object
*
* Description : Copies one socket address into another
*
* Return : void ;
*
* Note :
************************************************************************/
void
copy_sockaddr_in( const struct sockaddr_in *in,
struct sockaddr_in *out )
{
memset( out->sin_zero, 0, 8 );
out->sin_family = in->sin_family;
out->sin_port = in->sin_port;
out->sin_addr.s_addr = in->sin_addr.s_addr;
}
/************************************************************************
* Function : copy_token
*
* Parameters :
* const token *in ; source token
* const char * in_base ;
* token * out ; destination token
* char * out_base ;
*
* Description : Tokens are generally pointers into other strings
* this copies the offset and size from a token (in) relative to
* one string (in_base) into a token (out) relative to another
* string (out_base)
*
* Return : void ;
*
* Note :
************************************************************************/
static void
copy_token( const token * in,
const char *in_base,
token * out,
char *out_base )
{
out->size = in->size;
out->buff = out_base + ( in->buff - in_base );
}
/************************************************************************
* Function : copy_URL_list
*
* Parameters :
* URL_list *in ; Source URL list
* URL_list *out ; Destination URL list
*
* Description : Copies one URL_list into another. This includes
* dynamically allocating the out->URLs field (the full string),
* and the structures used to hold the parsedURLs. This memory MUST
* be freed by the caller through: free_URL_list(&out)
*
* Return : int ;
* HTTP_SUCCESS - On Success
* UPNP_E_OUTOF_MEMORY - On Failure to allocate memory
*
* Note :
************************************************************************/
int
copy_URL_list( URL_list * in,
URL_list * out )
{
int len = strlen( in->URLs ) + 1;
int i = 0;
out->URLs = NULL;
out->parsedURLs = NULL;
out->size = 0;
out->URLs = ( char * )malloc( len );
out->parsedURLs =
( uri_type * ) malloc( sizeof( uri_type ) * in->size );
if( ( out->URLs == NULL ) || ( out->parsedURLs == NULL ) )
return UPNP_E_OUTOF_MEMORY;
memcpy( out->URLs, in->URLs, len );
for( i = 0; i < in->size; i++ ) {
//copy the parsed uri
out->parsedURLs[i].type = in->parsedURLs[i].type;
copy_token( &in->parsedURLs[i].scheme, in->URLs,
&out->parsedURLs[i].scheme, out->URLs );
out->parsedURLs[i].path_type = in->parsedURLs[i].path_type;
copy_token( &in->parsedURLs[i].pathquery, in->URLs,
&out->parsedURLs[i].pathquery, out->URLs );
copy_token( &in->parsedURLs[i].fragment, in->URLs,
&out->parsedURLs[i].fragment, out->URLs );
copy_token( &in->parsedURLs[i].hostport.text,
in->URLs, &out->parsedURLs[i].hostport.text,
out->URLs );
copy_sockaddr_in( &in->parsedURLs[i].hostport.IPv4address,
&out->parsedURLs[i].hostport.IPv4address );
}
out->size = in->size;
return HTTP_SUCCESS;
}
/************************************************************************
* Function : free_URL_list
*
* Parameters :
* URL_list * list ; URL List object
*
* Description : Frees the memory associated with a URL_list. Frees the
* dynamically allocated members of of list. Does NOT free the
* pointer to the list itself ( i.e. does NOT free(list))
*
* Return : void ;
*
* Note :
************************************************************************/
void
free_URL_list( URL_list * list )
{
if( list->URLs )
free( list->URLs );
if( list->parsedURLs )
free( list->parsedURLs );
list->size = 0;
}
/************************************************************************
* Function : print_uri
*
* Parameters :
* uri_type *in ; URI object
*
* Description : Function useful in debugging for printing a parsed uri.
* Compiled out with DBGONLY macro.
*
* Return : void ;
*
* Note :
************************************************************************/
DBGONLY( void print_uri( uri_type * in ) {
print_token( &in->scheme );
print_token( &in->hostport.text );
print_token( &in->pathquery ); print_token( &in->fragment );} )
/************************************************************************
* Function : print_token
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -