leo_sobral@2
|
1 |
/**
|
leo_sobral@2
|
2 |
*
|
leo_sobral@2
|
3 |
* MythURI utils
|
leo_sobral@2
|
4 |
* - Extracts and parses a URI char string, in according with the RFC 2396
|
leo_sobral@2
|
5 |
* [http://www.ietf.org/rfc/rfc2396.txt]
|
leo_sobral@2
|
6 |
*
|
leo_sobral@2
|
7 |
* @author Rosfran Borges (rosfran.borges@indt.org.br)
|
leo_sobral@2
|
8 |
*
|
leo_sobral@2
|
9 |
*/
|
leo_sobral@2
|
10 |
|
leo_sobral@2
|
11 |
#include "myth_uri.h"
|
leo_sobral@2
|
12 |
#include <glib.h>
|
leo_sobral@2
|
13 |
#include <string.h>
|
leo_sobral@2
|
14 |
#include <stdlib.h>
|
leo_sobral@2
|
15 |
|
leo_sobral@2
|
16 |
static gint
|
leo_sobral@2
|
17 |
myth_strstr( const gchar *haystack, const gchar *needle )
|
leo_sobral@2
|
18 |
{
|
leo_sobral@2
|
19 |
|
leo_sobral@2
|
20 |
gchar *strPos;
|
leo_sobral@2
|
21 |
|
leo_sobral@2
|
22 |
if (haystack == NULL || needle == NULL)
|
leo_sobral@2
|
23 |
return -1;
|
leo_sobral@2
|
24 |
strPos = strstr(haystack, needle);
|
leo_sobral@2
|
25 |
if (strPos == NULL)
|
leo_sobral@2
|
26 |
return -1;
|
leo_sobral@2
|
27 |
|
leo_sobral@2
|
28 |
return (strPos - haystack);
|
leo_sobral@2
|
29 |
|
leo_sobral@2
|
30 |
}
|
leo_sobral@2
|
31 |
|
leo_sobral@2
|
32 |
static gboolean
|
leo_sobral@2
|
33 |
myth_uri_isabsolute( const MythURI *uri )
|
leo_sobral@2
|
34 |
{
|
leo_sobral@2
|
35 |
gboolean ret = FALSE;
|
leo_sobral@2
|
36 |
|
leo_sobral@2
|
37 |
g_return_val_if_fail( uri != NULL && uri->uri != NULL && uri->protocol != NULL, FALSE );
|
leo_sobral@2
|
38 |
|
leo_sobral@2
|
39 |
if ( myth_strstr( uri->uri->str, MYTH_URI_PROTOCOL_DELIM ) == 0 || strlen(uri->protocol->str) > 0 )
|
leo_sobral@2
|
40 |
ret = TRUE;
|
leo_sobral@2
|
41 |
|
leo_sobral@2
|
42 |
return ret;
|
leo_sobral@2
|
43 |
}
|
leo_sobral@2
|
44 |
|
leo_sobral@2
|
45 |
static gint
|
leo_sobral@2
|
46 |
myth_strrchr( const gchar *str, const gchar *chars, const gint nchars )
|
leo_sobral@2
|
47 |
{
|
leo_sobral@2
|
48 |
|
leo_sobral@2
|
49 |
gint strLen;
|
leo_sobral@2
|
50 |
gint i, j;
|
leo_sobral@2
|
51 |
|
leo_sobral@2
|
52 |
if ( str == NULL || chars == NULL )
|
leo_sobral@2
|
53 |
return -1;
|
leo_sobral@2
|
54 |
|
leo_sobral@2
|
55 |
strLen = strlen( str );
|
leo_sobral@2
|
56 |
for ( i= (strLen-1); 0 <= i; i-- ) {
|
leo_sobral@2
|
57 |
for ( j=0; j<nchars; j++ ) {
|
leo_sobral@2
|
58 |
if ( str[i] == chars[j] )
|
leo_sobral@2
|
59 |
return i;
|
leo_sobral@2
|
60 |
}
|
leo_sobral@2
|
61 |
}
|
leo_sobral@2
|
62 |
|
leo_sobral@2
|
63 |
return -1;
|
leo_sobral@2
|
64 |
|
leo_sobral@2
|
65 |
}
|
leo_sobral@2
|
66 |
|
leo_sobral@2
|
67 |
static MythURI *
|
leo_sobral@2
|
68 |
myth_uri_init( )
|
leo_sobral@2
|
69 |
{
|
leo_sobral@2
|
70 |
MythURI *uri = g_new0( MythURI, 1 );
|
leo_sobral@2
|
71 |
uri->host = g_string_new("");
|
leo_sobral@2
|
72 |
uri->fragment = g_string_new("");
|
leo_sobral@2
|
73 |
uri->password = g_string_new("");
|
leo_sobral@2
|
74 |
uri->path = g_string_new("");
|
leo_sobral@2
|
75 |
uri->protocol = g_string_new("");
|
leo_sobral@2
|
76 |
uri->query = g_string_new("");
|
leo_sobral@2
|
77 |
uri->uri = g_string_new("");
|
leo_sobral@2
|
78 |
uri->user = g_string_new("");
|
leo_sobral@2
|
79 |
return uri;
|
leo_sobral@2
|
80 |
}
|
leo_sobral@2
|
81 |
|
leo_sobral@2
|
82 |
const MythURI *
|
leo_sobral@2
|
83 |
myth_uri_new( gchar *value )
|
leo_sobral@2
|
84 |
{
|
leo_sobral@2
|
85 |
|
leo_sobral@2
|
86 |
MythURI *uri = myth_uri_init();
|
leo_sobral@2
|
87 |
|
leo_sobral@2
|
88 |
gchar *protocol;
|
leo_sobral@2
|
89 |
gint uriLen;
|
leo_sobral@2
|
90 |
gint currIdx;
|
leo_sobral@2
|
91 |
gint protoIdx;
|
leo_sobral@2
|
92 |
gint atIdx;
|
leo_sobral@2
|
93 |
gint colonIdx;
|
leo_sobral@2
|
94 |
gint shashIdx;
|
leo_sobral@2
|
95 |
gchar *host;
|
leo_sobral@2
|
96 |
gint eblacketIdx;
|
leo_sobral@2
|
97 |
GString *hostStr;
|
leo_sobral@2
|
98 |
GString *portStr;
|
leo_sobral@2
|
99 |
gint hostLen;
|
leo_sobral@2
|
100 |
gint sharpIdx;
|
leo_sobral@2
|
101 |
gint questionIdx;
|
leo_sobral@2
|
102 |
gint queryLen;
|
leo_sobral@2
|
103 |
|
leo_sobral@2
|
104 |
uriLen = strlen(value);
|
leo_sobral@2
|
105 |
uri->uri = g_string_new( value );
|
leo_sobral@2
|
106 |
|
leo_sobral@2
|
107 |
currIdx = 0;
|
leo_sobral@2
|
108 |
|
leo_sobral@2
|
109 |
/*** Protocol ****/
|
leo_sobral@2
|
110 |
protoIdx = myth_strstr( value, MYTH_URI_PROTOCOL_DELIM );
|
leo_sobral@2
|
111 |
if (0 < protoIdx) {
|
leo_sobral@2
|
112 |
uri->protocol = g_string_append_len( uri->protocol, value, protoIdx );
|
leo_sobral@2
|
113 |
currIdx += protoIdx + strlen( MYTH_URI_PROTOCOL_DELIM );
|
leo_sobral@2
|
114 |
}
|
leo_sobral@2
|
115 |
|
leo_sobral@2
|
116 |
/*** User (Password) ****/
|
leo_sobral@2
|
117 |
atIdx = myth_strstr( value+currIdx, MYTH_URI_USER_DELIM );
|
leo_sobral@2
|
118 |
if ( 0 < atIdx ) {
|
leo_sobral@2
|
119 |
colonIdx = myth_strstr( value+currIdx, MYTH_URI_COLON_DELIM );
|
leo_sobral@2
|
120 |
|
leo_sobral@2
|
121 |
if (0 < colonIdx && colonIdx < atIdx) {
|
leo_sobral@2
|
122 |
uri->user = g_string_append_len( uri->user, value+currIdx, colonIdx );
|
leo_sobral@2
|
123 |
uri->password = g_string_append_len( uri->password, value+currIdx+colonIdx+1, atIdx-(colonIdx+1) );
|
leo_sobral@2
|
124 |
}
|
leo_sobral@2
|
125 |
else
|
leo_sobral@2
|
126 |
uri->user = g_string_append_len( uri->user, value+currIdx, atIdx - currIdx );
|
leo_sobral@2
|
127 |
currIdx += atIdx + 1;
|
leo_sobral@2
|
128 |
}
|
leo_sobral@2
|
129 |
|
leo_sobral@2
|
130 |
/*** Host (Port) ****/
|
leo_sobral@2
|
131 |
shashIdx = myth_strstr( value+currIdx, MYTH_URI_SLASH_DELIM );
|
leo_sobral@2
|
132 |
if ( 0 < shashIdx )
|
leo_sobral@2
|
133 |
uri->host = g_string_append_len( uri->host, value+currIdx, shashIdx );
|
leo_sobral@2
|
134 |
else if ( myth_uri_isabsolute(uri) == TRUE )
|
leo_sobral@2
|
135 |
uri->host = g_string_append_len( uri->host, value+currIdx, strlen(value) - currIdx );
|
leo_sobral@2
|
136 |
host = g_strdup( myth_uri_gethost(uri) );
|
leo_sobral@2
|
137 |
colonIdx = myth_strrchr( host, MYTH_URI_COLON_DELIM, 1 );
|
leo_sobral@2
|
138 |
eblacketIdx = myth_strrchr( host, MYTH_URI_EBLACET_DELIM, 1 );
|
leo_sobral@2
|
139 |
if ( ( 0 < colonIdx ) && ( eblacketIdx < colonIdx ) ) {
|
leo_sobral@2
|
140 |
hostStr = g_string_new( host );
|
leo_sobral@2
|
141 |
|
leo_sobral@2
|
142 |
hostLen = hostStr->len;
|
leo_sobral@2
|
143 |
/**** host ****/
|
leo_sobral@2
|
144 |
uri->host = g_string_erase( uri->host, 0, hostLen );
|
leo_sobral@2
|
145 |
uri->host = g_string_insert_len( uri->host, 0, hostStr->str, colonIdx );
|
leo_sobral@2
|
146 |
//host = myth_uri_gethost( uri );
|
leo_sobral@2
|
147 |
if (0 < hostLen) {
|
leo_sobral@2
|
148 |
if (host[0] == '[' && host[hostLen-1] == ']')
|
leo_sobral@2
|
149 |
uri->host = g_string_append_len( uri->host, hostStr->str+1, colonIdx-2 );
|
leo_sobral@2
|
150 |
}
|
leo_sobral@2
|
151 |
/**** port ****/
|
leo_sobral@2
|
152 |
portStr = g_string_new("");
|
leo_sobral@2
|
153 |
portStr = g_string_append_len( portStr, hostStr->str+colonIdx+1, hostLen-colonIdx-1 );
|
leo_sobral@2
|
154 |
uri->port = atoi( portStr->str );
|
leo_sobral@2
|
155 |
g_string_free( portStr, TRUE );
|
leo_sobral@2
|
156 |
g_string_free( hostStr, FALSE );
|
leo_sobral@2
|
157 |
}
|
leo_sobral@2
|
158 |
else {
|
leo_sobral@2
|
159 |
uri->port = MYTH_URI_KNKOWN_PORT;
|
leo_sobral@2
|
160 |
protocol = myth_uri_getprotocol(uri);
|
leo_sobral@2
|
161 |
if ( strcmp(protocol, MYTH_URI_PROTOCOL_HTTP) == 0 )
|
leo_sobral@2
|
162 |
uri->port = MYTH_URI_DEFAULT_HTTP_PORT;
|
leo_sobral@2
|
163 |
if ( strcmp(protocol, MYTH_URI_PROTOCOL_FTP) == 0 )
|
leo_sobral@2
|
164 |
uri->port = MYTH_URI_DEFAULT_FTP_PORT;
|
leo_sobral@2
|
165 |
}
|
leo_sobral@2
|
166 |
|
leo_sobral@2
|
167 |
if (shashIdx > 0) currIdx += shashIdx;
|
leo_sobral@2
|
168 |
|
leo_sobral@2
|
169 |
/*
|
leo_sobral@2
|
170 |
Handle relative URL
|
leo_sobral@2
|
171 |
*/
|
leo_sobral@2
|
172 |
if (myth_uri_isabsolute(uri) == FALSE)
|
leo_sobral@2
|
173 |
{
|
leo_sobral@2
|
174 |
|
leo_sobral@2
|
175 |
if (shashIdx != 0)
|
leo_sobral@2
|
176 |
{
|
leo_sobral@2
|
177 |
/* Add slash delimiter at the beginning of the URL,
|
leo_sobral@2
|
178 |
if it doesn't exist
|
leo_sobral@2
|
179 |
*/
|
leo_sobral@2
|
180 |
uri->path = g_string_new( MYTH_URI_SLASH_DELIM );
|
leo_sobral@2
|
181 |
}
|
leo_sobral@2
|
182 |
uri->path = g_string_append( uri->path, value );
|
leo_sobral@2
|
183 |
|
leo_sobral@2
|
184 |
} else {
|
leo_sobral@2
|
185 |
/* First set path simply to the rest of URI */
|
leo_sobral@2
|
186 |
g_string_append_len( uri->path, value+currIdx, uriLen-currIdx );
|
leo_sobral@2
|
187 |
}
|
leo_sobral@2
|
188 |
|
leo_sobral@2
|
189 |
/**** Path (Query/Fragment) ****/
|
leo_sobral@2
|
190 |
sharpIdx = myth_strstr(value+currIdx, MYTH_URI_SHARP_DELIM);
|
leo_sobral@2
|
191 |
if (0 < sharpIdx) {
|
leo_sobral@2
|
192 |
uri->path = g_string_append_len( uri->path, value+currIdx, sharpIdx);
|
leo_sobral@2
|
193 |
uri->fragment = g_string_append_len( uri->fragment,
|
leo_sobral@2
|
194 |
value+currIdx+sharpIdx+1, uriLen-(currIdx+sharpIdx+1));
|
leo_sobral@2
|
195 |
}
|
leo_sobral@2
|
196 |
|
leo_sobral@2
|
197 |
questionIdx = myth_strstr( value+currIdx, MYTH_URI_QUESTION_DELIM );
|
leo_sobral@2
|
198 |
if ( 0 < questionIdx ) {
|
leo_sobral@2
|
199 |
uri->path = g_string_append_len( uri->path, value+currIdx, questionIdx );
|
leo_sobral@2
|
200 |
queryLen = uriLen-(currIdx+questionIdx+1);
|
leo_sobral@2
|
201 |
if ( 0 < sharpIdx )
|
leo_sobral@2
|
202 |
queryLen -= uriLen - (currIdx+sharpIdx+1);
|
leo_sobral@2
|
203 |
uri->query = g_string_append_len( uri->query, value+currIdx+questionIdx+1, queryLen );
|
leo_sobral@2
|
204 |
}
|
leo_sobral@2
|
205 |
|
leo_sobral@2
|
206 |
return uri;
|
leo_sobral@2
|
207 |
|
leo_sobral@2
|
208 |
}
|