uri.c
来自「原来由英特尔制定的UPnP SDK的」· C语言 代码 · 共 1,128 行 · 第 1/3 页
C
1,128 行
{ print_token( &in->scheme ); print_token( &in->hostport.text ); print_token( &in->pathquery ); print_token( &in->fragment );}#endif/************************************************************************* Function : print_token** Parameters :* token * in ; token** Description : Function useful in debugging for printing a token.** Return : void ;** Note :************************************************************************/#ifdef DEBUGvoid print_token(token * in){ int i = 0; printf( "Token Size : %"PRIzu"\n\'", in->size ); for( i = 0; i < in->size; i++ ) { putchar( in->buff[i] ); } putchar( '\'' ); putchar( '\n' );}#endif/************************************************************************* Function : token_string_casecmp** Parameters :* token * in1 ; Token object whose buffer is to be compared* char * in2 ; string of characters to compare with** Description : Compares buffer in the token object with the buffer * in in2** Return : int ;* < 0 string1 less than string2 * 0 string1 identical to string2 * > 0 string1 greater than string2 ** Note :************************************************************************/int token_string_casecmp( token * in1, char *in2 ){ int in2_length = strlen( in2 ); if( in1->size != in2_length ) return 1; else return strncasecmp( in1->buff, in2, in1->size );}/************************************************************************* Function : token_string_cmp** Parameters :* token * in1 ; Token object whose buffer is to be compared* char * in2 ; string of characters to compare with** Description : Compares a null terminated string to a token (exact) ** Return : int ;* < 0 string1 less than string2 * 0 string1 identical to string2 * > 0 string1 greater than string2 ** Note :************************************************************************/inttoken_string_cmp( token * in1, char *in2 ){ int in2_length = strlen( in2 ); if( in1->size != in2_length ) return 1; else return strncmp( in1->buff, in2, in1->size );}/************************************************************************* Function : token_cmp** Parameters :* token *in1 ; First token object whose buffer is to be compared* token *in2 ; Second token object used for the comparison** Description : Compares two tokens ** Return : int ;* < 0 string1 less than string2 * 0 string1 identical to string2 * > 0 string1 greater than string2 ** Note :************************************************************************/inttoken_cmp( token * in1, token * in2 ){ if( in1->size != in2->size ) return 1; else return memcmp( in1->buff, in2->buff, in1->size );}/************************************************************************* Function : parse_port** Parameters :* int max ; sets a maximum limit* char * port ; port to be parsed.* unsigned short * out ; out parameter where the port is parsed * and converted into network format** Description : parses a port (i.e. '4000') and converts it into a * network ordered unsigned short int.** Return : int ;** Note :************************************************************************/intparse_port( int max, const char *port, unsigned short *out ){ const char *finger = port; const char *max_ptr = finger + max; unsigned short temp = 0; while( ( finger < max_ptr ) && ( isdigit( *finger ) ) ) { temp = temp * 10; temp += ( *finger ) - '0'; finger++; } *out = htons( temp ); return finger - port;}/************************************************************************* Function : parse_hostport** Parameters :* char *in ; string of characters representing host and port* int max ; sets a maximum limit* hostport_type *out ; out parameter where the host and port* are represented as an internet address** Description : Parses a string representing a host and port* (e.g. "127.127.0.1:80" or "localhost") and fills out a * hostport_type struct with internet address and a token * representing the full host and port. uses gethostbyname.** Return : int ;** Note :************************************************************************/intparse_hostport( const char *in, int max, hostport_type * out ){#define BUFFER_SIZE 8192 int i = 0; int begin_port; int hostport_size = 0; int host_size = 0;#if !defined(WIN32) && !(defined(__OSX__) || defined(__APPLE__)) char temp_hostbyname_buff[BUFFER_SIZE]; struct hostent h_buf;#endif struct hostent *h = NULL; int errcode = 0; char *temp_host_name = NULL; int last_dot = -1; out->text.size = 0; out->text.buff = NULL; out->IPv4address.sin_port = htons( 80 ); //default port is 80 memset( &out->IPv4address.sin_zero, 0, 8 ); while( ( i < max ) && ( in[i] != ':' ) && ( in[i] != '/' ) && ( ( isalnum( in[i] ) ) || ( in[i] == '.' ) || ( in[i] == '-' ) ) ) { i++; if( in[i] == '.' ) { last_dot = i; } } host_size = i; if( ( i < max ) && ( in[i] == ':' ) ) { begin_port = i + 1; //convert port if( !( hostport_size = parse_port( max - begin_port, &in[begin_port], &out->IPv4address.sin_port ) ) ) { return UPNP_E_INVALID_URL; } hostport_size += begin_port; } else hostport_size = host_size; //convert to temporary null terminated string temp_host_name = ( char * )malloc( host_size + 1 ); if( temp_host_name == NULL ) return UPNP_E_OUTOF_MEMORY; memcpy( temp_host_name, in, host_size ); temp_host_name[host_size] = '\0'; //check to see if host name is an ipv4 address if( ( last_dot != -1 ) && ( last_dot + 1 < host_size ) && ( isdigit( temp_host_name[last_dot + 1] ) ) ) { //must be ipv4 address errcode = inet_pton( AF_INET, temp_host_name, &out->IPv4address.sin_addr ); if( errcode == 1 ) { out->IPv4address.sin_family = AF_INET; } else { out->IPv4address.sin_addr.s_addr = 0; out->IPv4address.sin_family = AF_INET; free( temp_host_name ); temp_host_name = NULL; return UPNP_E_INVALID_URL; } } else { int errCode = 0; //call gethostbyname_r (reentrant form of gethostbyname) // TODO: Use autoconf to discover this rather than the // platform-specific stuff below#if defined(WIN32) || defined(__CYGWIN__) h = gethostbyname(temp_host_name);#elif defined(SPARC_SOLARIS) errCode = gethostbyname_r( temp_host_name, &h, temp_hostbyname_buff, BUFFER_SIZE, &errcode );#elif defined(__FreeBSD__) && __FreeBSD_version < 601103 h = lwres_gethostbyname_r( temp_host_name, &h_buf, temp_hostbyname_buff, BUFFER_SIZE, &errcode ); if ( h == NULL ) { errCode = 1; }#elif defined(__OSX__) || defined(__APPLE__) h = gethostbyname(temp_host_name); if ( h == NULL ) { errCode = 1; }#elif defined(__linux__) errCode = gethostbyname_r( temp_host_name, &h_buf, temp_hostbyname_buff, BUFFER_SIZE, &h, &errcode );#else { struct addrinfo hints, *res, *res0; h = NULL; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_INET; hints.ai_socktype = SOCK_STREAM; errCode = getaddrinfo(temp_host_name, "http", &hints, &res0); if (!errCode) { for (res = res0; res; res = res->ai_next) { if (res->ai_family == PF_INET && res->ai_addr->sa_family == AF_INET) { h = &h_buf; h->h_addrtype = res->ai_addr->sa_family; h->h_length = 4; h->h_addr = (void *) temp_hostbyname_buff; *(struct in_addr *)h->h_addr = ((struct sockaddr_in *)res->ai_addr)->sin_addr; break; } } freeaddrinfo(res0); } }#endif if( errCode == 0 ) { if( h ) { if( ( h->h_addrtype == AF_INET ) && ( h->h_length == 4 ) ) { out->IPv4address.sin_addr = ( *( struct in_addr * )h->h_addr ); out->IPv4address.sin_family = AF_INET; } } } else { out->IPv4address.sin_addr.s_addr = 0; out->IPv4address.sin_family = AF_INET; free( temp_host_name ); temp_host_name = NULL; return UPNP_E_INVALID_URL; } } if( temp_host_name ) { free( temp_host_name ); temp_host_name = NULL; } out->text.size = hostport_size; out->text.buff = in; return hostport_size;}/************************************************************************* Function : parse_scheme** Parameters :* char * in ; string of characters representing a scheme* int max ; maximum number of characters* token * out ; output parameter whose buffer is filled in with * the scheme** Description : parses a uri scheme starting at in[0] as defined in * http://www.ietf.org/rfc/rfc2396.txt (RFC explaining URIs)* (e.g. "http:" -> scheme= "http"). * Note, string MUST include ':' within the max charcters** Return : int ;** Note :************************************************************************/intparse_scheme( const char *in, int max, token * out ){ int i = 0; out->size = 0; out->buff = NULL; if( ( max == 0 ) || ( !isalpha( in[0] ) ) ) return FALSE; i++; while( ( i < max ) && ( in[i] != ':' ) ) { if( !( isalnum( in[i] ) || ( in[i] == '+' ) || ( in[i] == '-' ) || ( in[i] == '.' ) ) ) return FALSE; i++; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?