3 * by Bertrand Baudet <bertrand_baudet@yahoo.com>
4 * (C) 2001, MPlayer team.
16 url_new(const char* url
) {
19 char *ptr1
=NULL
, *ptr2
=NULL
, *ptr3
=NULL
;
21 if( url
==NULL
) return NULL
;
23 // Create the URL container
24 Curl
= (URL_t
*)malloc(sizeof(URL_t
));
26 mp_msg(MSGT_NETWORK
,MSGL_FATAL
,"Memory allocation failed!\n");
29 // Initialisation of the URL container members
30 memset( Curl
, 0, sizeof(URL_t
) );
32 // Copy the url in the URL container
33 Curl
->url
= strdup(url
);
34 if( Curl
->url
==NULL
) {
35 mp_msg(MSGT_NETWORK
,MSGL_FATAL
,"Memory allocation failed!\n");
40 // extract the protocol
41 ptr1
= strstr(url
, "://");
43 mp_msg(MSGT_NETWORK
,MSGL_V
,"Not an URL!\n");
48 Curl
->protocol
= (char*)malloc(pos1
+1);
49 strncpy(Curl
->protocol
, url
, pos1
);
50 if( Curl
->protocol
==NULL
) {
51 mp_msg(MSGT_NETWORK
,MSGL_FATAL
,"Memory allocation failed!\n");
55 Curl
->protocol
[pos1
] = '\0';
61 // check if a username:password is given
62 ptr2
= strstr(ptr1
, "@");
63 ptr3
= strstr(ptr1
, "/");
64 if( ptr3
!=NULL
&& ptr3
<ptr2
) {
65 // it isn't really a username but rather a part of the path
69 // We got something, at least a username...
71 Curl
->username
= (char*)malloc(len
+1);
72 if( Curl
->username
==NULL
) {
73 mp_msg(MSGT_NETWORK
,MSGL_FATAL
,"Memory allocation failed!\n");
77 strncpy(Curl
->username
, ptr1
, len
);
78 Curl
->username
[len
] = '\0';
80 ptr3
= strstr(ptr1
, ":");
81 if( ptr3
!=NULL
&& ptr3
<ptr2
) {
82 // We also have a password
83 int len2
= ptr2
-ptr3
-1;
84 Curl
->username
[ptr3
-ptr1
]='\0';
85 Curl
->password
= (char*)malloc(len2
+1);
86 if( Curl
->password
==NULL
) {
87 mp_msg(MSGT_NETWORK
,MSGL_FATAL
,"Memory allocation failed!\n");
91 strncpy( Curl
->password
, ptr3
+1, len2
);
92 Curl
->password
[len2
]='\0';
98 // before looking for a port number check if we have an IPv6 type numeric address
99 // in IPv6 URL the numeric address should be inside square braces.
100 ptr2
= strstr(ptr1
, "[");
101 ptr3
= strstr(ptr1
, "]");
102 if( ptr2
!=NULL
&& ptr3
!=NULL
) {
103 // we have an IPv6 numeric address
112 // look if the port is given
113 ptr2
= strstr(ptr2
, ":");
114 // If the : is after the first / it isn't the port
115 ptr3
= strstr(ptr1
, "/");
116 if(ptr3
&& ptr3
- ptr2
< 0) ptr2
= NULL
;
119 // Look if a path is given
122 // So we have an URL like http://www.hostname.com
125 // We have an URL like http://www.hostname.com/file.txt
129 // We have an URL beginning like http://www.hostname.com:1212
130 // Get the port number
131 Curl
->port
= atoi(ptr2
+1);
134 if( strstr(ptr1
, "]")!=NULL
) pos2
--;
135 // copy the hostname in the URL container
136 Curl
->hostname
= (char*)malloc(pos2
-pos1
+1);
137 if( Curl
->hostname
==NULL
) {
138 mp_msg(MSGT_NETWORK
,MSGL_FATAL
,"Memory allocation failed!\n");
142 strncpy(Curl
->hostname
, ptr1
, pos2
-pos1
);
143 Curl
->hostname
[pos2
-pos1
] = '\0';
145 // Look if a path is given
146 ptr2
= strstr(ptr1
, "/");
148 // A path/filename is given
149 // check if it's not a trailing '/'
150 if( strlen(ptr2
)>1 ) {
151 // copy the path/filename in the URL container
152 Curl
->file
= strdup(ptr2
);
153 if( Curl
->file
==NULL
) {
154 mp_msg(MSGT_NETWORK
,MSGL_FATAL
,"Memory allocation failed!\n");
160 // Check if a filename was given or set, else set it with '/'
161 if( Curl
->file
==NULL
) {
162 Curl
->file
= (char*)malloc(2);
163 if( Curl
->file
==NULL
) {
164 mp_msg(MSGT_NETWORK
,MSGL_FATAL
,"Memory allocation failed!\n");
168 strcpy(Curl
->file
, "/");
175 url_free(URL_t
* url
) {
177 if(url
->url
) free(url
->url
);
178 if(url
->protocol
) free(url
->protocol
);
179 if(url
->hostname
) free(url
->hostname
);
180 if(url
->file
) free(url
->file
);
181 if(url
->username
) free(url
->username
);
182 if(url
->password
) free(url
->password
);
187 /* Replace escape sequences in an URL (or a part of an URL) */
188 /* works like strcpy(), but without return argument */
189 /* unescape_url_string comes from ASFRecorder */
191 url_unescape_string(char *outbuf
, const char *inbuf
)
197 unsigned char c1
= *inbuf
++;
198 unsigned char c2
= *inbuf
++;
199 if ( ((c1
>='0' && c1
<='9') || (c1
>='A' && c1
<='F')) &&
200 ((c2
>='0' && c2
<='9') || (c2
>='A' && c2
<='F')) ) {
201 if (c1
>='0' && c1
<='9') c1
-='0';
203 if (c2
>='0' && c2
<='9') c2
-='0';
212 /* Replace specific characters in the URL string by an escape sequence */
213 /* works like strcpy(), but without return argument */
214 /* escape_url_string comes from ASFRecorder */
216 url_escape_string(char *outbuf
, const char *inbuf
) {
220 if( (c
>= 'A' && c
<= 'Z') ||
221 (c
>= 'a' && c
<= 'z') ||
222 (c
>= '0' && c
<= '9') ||
223 (c
>= 0x7f) || /* fareast languages(Chinese, Korean, Japanese) */
224 c
=='-' || c
=='_' || c
=='.' || c
=='!' || c
=='~' || /* mark characters */
225 c
=='*' || c
=='\'' || c
=='(' || c
==')' || c
=='%' || /* do not touch escape character */
226 c
==';' || c
=='/' || c
=='?' || c
==':' || c
=='@' || /* reserved characters */
227 c
=='&' || c
=='=' || c
=='+' || c
=='$' || c
==',' || /* see RFC 2396 */
231 /* all others will be escaped */
232 unsigned char c1
= ((c
& 0xf0) >> 4);
233 unsigned char c2
= (c
& 0x0f);
234 if (c1
< 10) c1
+='0';
236 if (c2
< 10) c2
+='0';
247 url_debug(const URL_t
*url
) {
249 printf("URL pointer NULL\n");
252 if( url
->url
!=NULL
) {
253 printf("url=%s\n", url
->url
);
255 if( url
->protocol
!=NULL
) {
256 printf("protocol=%s\n", url
->protocol
);
258 if( url
->hostname
!=NULL
) {
259 printf("hostname=%s\n", url
->hostname
);
261 printf("port=%d\n", url
->port
);
262 if( url
->file
!=NULL
) {
263 printf("file=%s\n", url
->file
);
265 if( url
->username
!=NULL
) {
266 printf("username=%s\n", url
->username
);
268 if( url
->password
!=NULL
) {
269 printf("password=%s\n", url
->password
);