/** * * GMythURI utils * - Extracts and parses a URI char string, in according with the RFC 2396 * [http://www.ietf.org/rfc/rfc2396.txt] * * @author Rosfran Borges (rosfran.borges@indt.org.br) * */ #include "gmyth_uri.h" #include #include #include static gint gmyth_strstr( const gchar *haystack, const gchar *needle ) { gchar *strPos; if (haystack == NULL || needle == NULL) return -1; strPos = strstr(haystack, needle); if (strPos == NULL) return -1; return (strPos - haystack); } static gboolean gmyth_uri_isabsolute( const GMythURI *uri ) { gboolean ret = FALSE; g_return_val_if_fail( uri != NULL && uri->uri != NULL && uri->protocol != NULL, FALSE ); if ( gmyth_strstr( uri->uri->str, GMYTH_URI_PROTOCOL_DELIM ) == 0 || strlen(uri->protocol->str) > 0 ) ret = TRUE; return ret; } static gint gmyth_strrchr( const gchar *str, const gchar *chars, const gint nchars ) { gint strLen; gint i, j; if ( str == NULL || chars == NULL ) return -1; strLen = strlen( str ); for ( i= (strLen-1); 0 <= i; i-- ) { for ( j=0; jhost = g_string_new(""); uri->fragment = g_string_new(""); uri->password = g_string_new(""); uri->path = g_string_new(""); uri->protocol = g_string_new(""); uri->query = g_string_new(""); uri->uri = g_string_new(""); uri->user = g_string_new(""); return uri; } const GMythURI * gmyth_uri_new( gchar *value ) { GMythURI *uri = gmyth_uri_init(); gchar *protocol; gint uriLen; gint currIdx; gint protoIdx; gint atIdx; gint colonIdx; gint shashIdx; gchar *host; gint eblacketIdx; GString *hostStr; GString *portStr; gint hostLen; gint sharpIdx; gint questionIdx; gint queryLen; uriLen = strlen(value); uri->uri = g_string_new( value ); currIdx = 0; /*** Protocol ****/ protoIdx = gmyth_strstr( value, GMYTH_URI_PROTOCOL_DELIM ); if (0 < protoIdx) { uri->protocol = g_string_append_len( uri->protocol, value, protoIdx ); currIdx += protoIdx + strlen( GMYTH_URI_PROTOCOL_DELIM ); } /*** User (Password) ****/ atIdx = gmyth_strstr( value+currIdx, GMYTH_URI_USER_DELIM ); if ( 0 < atIdx ) { colonIdx = gmyth_strstr( value+currIdx, GMYTH_URI_COLON_DELIM ); if (0 < colonIdx && colonIdx < atIdx) { uri->user = g_string_append_len( uri->user, value+currIdx, colonIdx ); uri->password = g_string_append_len( uri->password, value+currIdx+colonIdx+1, atIdx-(colonIdx+1) ); } else uri->user = g_string_append_len( uri->user, value+currIdx, atIdx - currIdx ); currIdx += atIdx + 1; } /*** Host (Port) ****/ shashIdx = gmyth_strstr( value+currIdx, GMYTH_URI_SLASH_DELIM ); if ( 0 < shashIdx ) uri->host = g_string_append_len( uri->host, value+currIdx, shashIdx ); else if ( gmyth_uri_isabsolute(uri) == TRUE ) uri->host = g_string_append_len( uri->host, value+currIdx, strlen(value) - currIdx ); host = g_strdup( gmyth_uri_gethost(uri) ); colonIdx = gmyth_strrchr( host, GMYTH_URI_COLON_DELIM, 1 ); eblacketIdx = gmyth_strrchr( host, GMYTH_URI_EBLACET_DELIM, 1 ); if ( ( 0 < colonIdx ) && ( eblacketIdx < colonIdx ) ) { hostStr = g_string_new( host ); hostLen = hostStr->len; /**** host ****/ uri->host = g_string_erase( uri->host, 0, hostLen ); uri->host = g_string_insert_len( uri->host, 0, hostStr->str, colonIdx ); //host = gmyth_uri_gethost( uri ); if (0 < hostLen) { if (host[0] == '[' && host[hostLen-1] == ']') uri->host = g_string_append_len( uri->host, hostStr->str+1, colonIdx-2 ); } /**** port ****/ portStr = g_string_new(""); portStr = g_string_append_len( portStr, hostStr->str+colonIdx+1, hostLen-colonIdx-1 ); uri->port = atoi( portStr->str ); g_string_free( portStr, TRUE ); g_string_free( hostStr, FALSE ); } else { uri->port = GMYTH_URI_KNKOWN_PORT; protocol = gmyth_uri_getprotocol(uri); if ( strcmp(protocol, GMYTH_URI_PROTOCOL_HTTP) == 0 ) uri->port = GMYTH_URI_DEFAULT_HTTP_PORT; if ( strcmp(protocol, GMYTH_URI_PROTOCOL_FTP) == 0 ) uri->port = GMYTH_URI_DEFAULT_FTP_PORT; } if (shashIdx > 0) currIdx += shashIdx; /* Handle relative URL */ if (gmyth_uri_isabsolute(uri) == FALSE) { if (shashIdx != 0) { /* Add slash delimiter at the beginning of the URL, if it doesn't exist */ uri->path = g_string_new( GMYTH_URI_SLASH_DELIM ); } uri->path = g_string_append( uri->path, value ); } else { /* First set path simply to the rest of URI */ g_string_append_len( uri->path, value+currIdx, uriLen-currIdx ); } /**** Path (Query/Fragment) ****/ sharpIdx = gmyth_strstr(value+currIdx, GMYTH_URI_SHARP_DELIM); if (0 < sharpIdx) { uri->path = g_string_append_len( uri->path, value+currIdx, sharpIdx); uri->fragment = g_string_append_len( uri->fragment, value+currIdx+sharpIdx+1, uriLen-(currIdx+sharpIdx+1)); } questionIdx = gmyth_strstr( value+currIdx, GMYTH_URI_QUESTION_DELIM ); if ( 0 < questionIdx ) { uri->path = g_string_append_len( uri->path, value+currIdx, questionIdx ); queryLen = uriLen-(currIdx+questionIdx+1); if ( 0 < sharpIdx ) queryLen -= uriLen - (currIdx+sharpIdx+1); uri->query = g_string_append_len( uri->query, value+currIdx+questionIdx+1, queryLen ); } return uri; }