leo_sobral@2: /** leo_sobral@2: * leo_sobral@2: * MythURI utils leo_sobral@2: * - Extracts and parses a URI char string, in according with the RFC 2396 leo_sobral@2: * [http://www.ietf.org/rfc/rfc2396.txt] leo_sobral@2: * leo_sobral@2: * @author Rosfran Borges (rosfran.borges@indt.org.br) leo_sobral@2: * leo_sobral@2: */ leo_sobral@2: leo_sobral@2: #include "myth_uri.h" leo_sobral@2: #include leo_sobral@2: #include leo_sobral@2: #include leo_sobral@2: leo_sobral@2: static gint leo_sobral@2: myth_strstr( const gchar *haystack, const gchar *needle ) leo_sobral@2: { leo_sobral@2: leo_sobral@2: gchar *strPos; leo_sobral@2: leo_sobral@2: if (haystack == NULL || needle == NULL) leo_sobral@2: return -1; leo_sobral@2: strPos = strstr(haystack, needle); leo_sobral@2: if (strPos == NULL) leo_sobral@2: return -1; leo_sobral@2: leo_sobral@2: return (strPos - haystack); leo_sobral@2: leo_sobral@2: } leo_sobral@2: leo_sobral@2: static gboolean leo_sobral@2: myth_uri_isabsolute( const MythURI *uri ) leo_sobral@2: { leo_sobral@2: gboolean ret = FALSE; leo_sobral@2: leo_sobral@2: g_return_val_if_fail( uri != NULL && uri->uri != NULL && uri->protocol != NULL, FALSE ); leo_sobral@2: leo_sobral@2: if ( myth_strstr( uri->uri->str, MYTH_URI_PROTOCOL_DELIM ) == 0 || strlen(uri->protocol->str) > 0 ) leo_sobral@2: ret = TRUE; leo_sobral@2: leo_sobral@2: return ret; leo_sobral@2: } leo_sobral@2: leo_sobral@2: static gint leo_sobral@2: myth_strrchr( const gchar *str, const gchar *chars, const gint nchars ) leo_sobral@2: { leo_sobral@2: leo_sobral@2: gint strLen; leo_sobral@2: gint i, j; leo_sobral@2: leo_sobral@2: if ( str == NULL || chars == NULL ) leo_sobral@2: return -1; leo_sobral@2: leo_sobral@2: strLen = strlen( str ); leo_sobral@2: for ( i= (strLen-1); 0 <= i; i-- ) { leo_sobral@2: for ( j=0; jhost = g_string_new(""); leo_sobral@2: uri->fragment = g_string_new(""); leo_sobral@2: uri->password = g_string_new(""); leo_sobral@2: uri->path = g_string_new(""); leo_sobral@2: uri->protocol = g_string_new(""); leo_sobral@2: uri->query = g_string_new(""); leo_sobral@2: uri->uri = g_string_new(""); leo_sobral@2: uri->user = g_string_new(""); leo_sobral@2: return uri; leo_sobral@2: } leo_sobral@2: leo_sobral@2: const MythURI * leo_sobral@2: myth_uri_new( gchar *value ) leo_sobral@2: { leo_sobral@2: leo_sobral@2: MythURI *uri = myth_uri_init(); leo_sobral@2: leo_sobral@2: gchar *protocol; leo_sobral@2: gint uriLen; leo_sobral@2: gint currIdx; leo_sobral@2: gint protoIdx; leo_sobral@2: gint atIdx; leo_sobral@2: gint colonIdx; leo_sobral@2: gint shashIdx; leo_sobral@2: gchar *host; leo_sobral@2: gint eblacketIdx; leo_sobral@2: GString *hostStr; leo_sobral@2: GString *portStr; leo_sobral@2: gint hostLen; leo_sobral@2: gint sharpIdx; leo_sobral@2: gint questionIdx; leo_sobral@2: gint queryLen; leo_sobral@2: leo_sobral@2: uriLen = strlen(value); leo_sobral@2: uri->uri = g_string_new( value ); leo_sobral@2: leo_sobral@2: currIdx = 0; leo_sobral@2: leo_sobral@2: /*** Protocol ****/ leo_sobral@2: protoIdx = myth_strstr( value, MYTH_URI_PROTOCOL_DELIM ); leo_sobral@2: if (0 < protoIdx) { leo_sobral@2: uri->protocol = g_string_append_len( uri->protocol, value, protoIdx ); leo_sobral@2: currIdx += protoIdx + strlen( MYTH_URI_PROTOCOL_DELIM ); leo_sobral@2: } leo_sobral@2: leo_sobral@2: /*** User (Password) ****/ leo_sobral@2: atIdx = myth_strstr( value+currIdx, MYTH_URI_USER_DELIM ); leo_sobral@2: if ( 0 < atIdx ) { leo_sobral@2: colonIdx = myth_strstr( value+currIdx, MYTH_URI_COLON_DELIM ); leo_sobral@2: leo_sobral@2: if (0 < colonIdx && colonIdx < atIdx) { leo_sobral@2: uri->user = g_string_append_len( uri->user, value+currIdx, colonIdx ); leo_sobral@2: uri->password = g_string_append_len( uri->password, value+currIdx+colonIdx+1, atIdx-(colonIdx+1) ); leo_sobral@2: } leo_sobral@2: else leo_sobral@2: uri->user = g_string_append_len( uri->user, value+currIdx, atIdx - currIdx ); leo_sobral@2: currIdx += atIdx + 1; leo_sobral@2: } leo_sobral@2: leo_sobral@2: /*** Host (Port) ****/ leo_sobral@2: shashIdx = myth_strstr( value+currIdx, MYTH_URI_SLASH_DELIM ); leo_sobral@2: if ( 0 < shashIdx ) leo_sobral@2: uri->host = g_string_append_len( uri->host, value+currIdx, shashIdx ); leo_sobral@2: else if ( myth_uri_isabsolute(uri) == TRUE ) leo_sobral@2: uri->host = g_string_append_len( uri->host, value+currIdx, strlen(value) - currIdx ); leo_sobral@2: host = g_strdup( myth_uri_gethost(uri) ); leo_sobral@2: colonIdx = myth_strrchr( host, MYTH_URI_COLON_DELIM, 1 ); leo_sobral@2: eblacketIdx = myth_strrchr( host, MYTH_URI_EBLACET_DELIM, 1 ); leo_sobral@2: if ( ( 0 < colonIdx ) && ( eblacketIdx < colonIdx ) ) { leo_sobral@2: hostStr = g_string_new( host ); leo_sobral@2: leo_sobral@2: hostLen = hostStr->len; leo_sobral@2: /**** host ****/ leo_sobral@2: uri->host = g_string_erase( uri->host, 0, hostLen ); leo_sobral@2: uri->host = g_string_insert_len( uri->host, 0, hostStr->str, colonIdx ); leo_sobral@2: //host = myth_uri_gethost( uri ); leo_sobral@2: if (0 < hostLen) { leo_sobral@2: if (host[0] == '[' && host[hostLen-1] == ']') leo_sobral@2: uri->host = g_string_append_len( uri->host, hostStr->str+1, colonIdx-2 ); leo_sobral@2: } leo_sobral@2: /**** port ****/ leo_sobral@2: portStr = g_string_new(""); leo_sobral@2: portStr = g_string_append_len( portStr, hostStr->str+colonIdx+1, hostLen-colonIdx-1 ); leo_sobral@2: uri->port = atoi( portStr->str ); leo_sobral@2: g_string_free( portStr, TRUE ); leo_sobral@2: g_string_free( hostStr, FALSE ); leo_sobral@2: } leo_sobral@2: else { leo_sobral@2: uri->port = MYTH_URI_KNKOWN_PORT; leo_sobral@2: protocol = myth_uri_getprotocol(uri); leo_sobral@2: if ( strcmp(protocol, MYTH_URI_PROTOCOL_HTTP) == 0 ) leo_sobral@2: uri->port = MYTH_URI_DEFAULT_HTTP_PORT; leo_sobral@2: if ( strcmp(protocol, MYTH_URI_PROTOCOL_FTP) == 0 ) leo_sobral@2: uri->port = MYTH_URI_DEFAULT_FTP_PORT; leo_sobral@2: } leo_sobral@2: leo_sobral@2: if (shashIdx > 0) currIdx += shashIdx; leo_sobral@2: leo_sobral@2: /* leo_sobral@2: Handle relative URL leo_sobral@2: */ leo_sobral@2: if (myth_uri_isabsolute(uri) == FALSE) leo_sobral@2: { leo_sobral@2: leo_sobral@2: if (shashIdx != 0) leo_sobral@2: { leo_sobral@2: /* Add slash delimiter at the beginning of the URL, leo_sobral@2: if it doesn't exist leo_sobral@2: */ leo_sobral@2: uri->path = g_string_new( MYTH_URI_SLASH_DELIM ); leo_sobral@2: } leo_sobral@2: uri->path = g_string_append( uri->path, value ); leo_sobral@2: leo_sobral@2: } else { leo_sobral@2: /* First set path simply to the rest of URI */ leo_sobral@2: g_string_append_len( uri->path, value+currIdx, uriLen-currIdx ); leo_sobral@2: } leo_sobral@2: leo_sobral@2: /**** Path (Query/Fragment) ****/ leo_sobral@2: sharpIdx = myth_strstr(value+currIdx, MYTH_URI_SHARP_DELIM); leo_sobral@2: if (0 < sharpIdx) { leo_sobral@2: uri->path = g_string_append_len( uri->path, value+currIdx, sharpIdx); leo_sobral@2: uri->fragment = g_string_append_len( uri->fragment, leo_sobral@2: value+currIdx+sharpIdx+1, uriLen-(currIdx+sharpIdx+1)); leo_sobral@2: } leo_sobral@2: leo_sobral@2: questionIdx = myth_strstr( value+currIdx, MYTH_URI_QUESTION_DELIM ); leo_sobral@2: if ( 0 < questionIdx ) { leo_sobral@2: uri->path = g_string_append_len( uri->path, value+currIdx, questionIdx ); leo_sobral@2: queryLen = uriLen-(currIdx+questionIdx+1); leo_sobral@2: if ( 0 < sharpIdx ) leo_sobral@2: queryLen -= uriLen - (currIdx+sharpIdx+1); leo_sobral@2: uri->query = g_string_append_len( uri->query, value+currIdx+questionIdx+1, queryLen ); leo_sobral@2: } leo_sobral@2: leo_sobral@2: return uri; leo_sobral@2: leo_sobral@2: }