1/***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
9 *
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at https://curl.se/docs/copyright.html.
13 *
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ***************************************************************************/
22
23/*
24 * Note:
25 *
26 * Since the URL parser by default only accepts schemes that *this instance*
27 * of libcurl supports, make sure that the test1560 file lists all the schemes
28 * that this test will assume to be present!
29 */
30
31#include "test.h"
32
33#include "testutil.h"
34#include "warnless.h"
35#include "memdebug.h" /* LAST include file */
36
37struct part {
38 CURLUPart part;
39 const char *name;
40};
41
42
43static int checkparts(CURLU *u, const char *in, const char *wanted,
44 unsigned int getflags)
45{
46 int i;
47 CURLUcode rc;
48 char buf[256];
49 char *bufp = &buf[0];
50 size_t len = sizeof(buf);
51 struct part parts[] = {
52 {CURLUPART_SCHEME, "scheme"},
53 {CURLUPART_USER, "user"},
54 {CURLUPART_PASSWORD, "password"},
55 {CURLUPART_OPTIONS, "options"},
56 {CURLUPART_HOST, "host"},
57 {CURLUPART_PORT, "port"},
58 {CURLUPART_PATH, "path"},
59 {CURLUPART_QUERY, "query"},
60 {CURLUPART_FRAGMENT, "fragment"},
61 {0, NULL}
62 };
63 memset(buf, 0, sizeof(buf));
64
65 for(i = 0; parts[i].name; i++) {
66 char *p = NULL;
67 size_t n;
68 rc = curl_url_get(u, parts[i].part, &p, getflags);
69 if(!rc && p) {
70 msnprintf(bufp, len, "%s%s", buf[0]?" | ":"", p);
71 }
72 else
73 msnprintf(bufp, len, "%s[%d]", buf[0]?" | ":"", (int)rc);
74
75 n = strlen(bufp);
76 bufp += n;
77 len -= n;
78 curl_free(p);
79 }
80 if(strcmp(buf, wanted)) {
81 fprintf(stderr, "in: %s\nwanted: %s\ngot: %s\n", in, wanted, buf);
82 return 1;
83 }
84 return 0;
85}
86
87struct redircase {
88 const char *in;
89 const char *set;
90 const char *out;
91 unsigned int urlflags;
92 unsigned int setflags;
93 CURLUcode ucode;
94};
95
96struct setcase {
97 const char *in;
98 const char *set;
99 const char *out;
100 unsigned int urlflags;
101 unsigned int setflags;
102 CURLUcode ucode; /* for the main URL set */
103 CURLUcode pcode; /* for updating parts */
104};
105
106struct testcase {
107 const char *in;
108 const char *out;
109 unsigned int urlflags;
110 unsigned int getflags;
111 CURLUcode ucode;
112};
113
114struct urltestcase {
115 const char *in;
116 const char *out;
117 unsigned int urlflags; /* pass to curl_url() */
118 unsigned int getflags; /* pass to curl_url_get() */
119 CURLUcode ucode;
120};
121
122struct querycase {
123 const char *in;
124 const char *q;
125 const char *out;
126 unsigned int urlflags; /* pass to curl_url() */
127 unsigned int qflags; /* pass to curl_url_get() */
128 CURLUcode ucode;
129};
130
131static struct testcase get_parts_list[] ={
132 {"https://user:password@example.net/get?this=and what", "",
133 CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT},
134 {"https://user:password@example.net/ge t?this=and-what", "",
135 CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT},
136 {"https://user:pass word@example.net/get?this=and-what", "",
137 CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT},
138 {"https://u ser:password@example.net/get?this=and-what", "",
139 CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT},
140 /* no space allowed in scheme */
141 {"htt ps://user:password@example.net/get?this=and-what", "",
142 CURLU_NON_SUPPORT_SCHEME|CURLU_ALLOW_SPACE, 0, CURLUE_MALFORMED_INPUT},
143 {"https://user:password@example.net/get?this=and what",
144 "https | user | password | [13] | example.net | [15] | /get | "
145 "this=and what | [17]",
146 CURLU_ALLOW_SPACE, 0, CURLUE_OK},
147 {"https://user:password@example.net/ge t?this=and-what",
148 "https | user | password | [13] | example.net | [15] | /ge t | "
149 "this=and-what | [17]",
150 CURLU_ALLOW_SPACE, 0, CURLUE_OK},
151 {"https://user:pass word@example.net/get?this=and-what",
152 "https | user | pass word | [13] | example.net | [15] | /get | "
153 "this=and-what | [17]",
154 CURLU_ALLOW_SPACE, 0, CURLUE_OK},
155 {"https://u ser:password@example.net/get?this=and-what",
156 "https | u ser | password | [13] | example.net | [15] | /get | "
157 "this=and-what | [17]",
158 CURLU_ALLOW_SPACE, 0, CURLUE_OK},
159 {"https://user:password@example.net/ge t?this=and-what",
160 "https | user | password | [13] | example.net | [15] | /ge%20t | "
161 "this=and-what | [17]",
162 CURLU_ALLOW_SPACE | CURLU_URLENCODE, 0, CURLUE_OK},
163 {"[::1]",
164 "http | [11] | [12] | [13] | [::1] | [15] | / | [16] | [17]",
165 CURLU_GUESS_SCHEME, 0, CURLUE_OK },
166 {"[::]",
167 "http | [11] | [12] | [13] | [::] | [15] | / | [16] | [17]",
168 CURLU_GUESS_SCHEME, 0, CURLUE_OK },
169 {"https://[::1]",
170 "https | [11] | [12] | [13] | [::1] | [15] | / | [16] | [17]",
171 0, 0, CURLUE_OK },
172 {"user:moo@ftp.example.com/color/#green?no-red",
173 "ftp | user | moo | [13] | ftp.example.com | [15] | /color/ | [16] | "
174 "green?no-red",
175 CURLU_GUESS_SCHEME, 0, CURLUE_OK },
176 {"ftp.user:moo@example.com/color/#green?no-red",
177 "http | ftp.user | moo | [13] | example.com | [15] | /color/ | [16] | "
178 "green?no-red",
179 CURLU_GUESS_SCHEME, 0, CURLUE_OK },
180#ifdef WIN32
181 {"file:/C:\\programs\\foo",
182 "file | [11] | [12] | [13] | [14] | [15] | C:\\programs\\foo | [16] | [17]",
183 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
184 {"file://C:\\programs\\foo",
185 "file | [11] | [12] | [13] | [14] | [15] | C:\\programs\\foo | [16] | [17]",
186 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
187 {"file:///C:\\programs\\foo",
188 "file | [11] | [12] | [13] | [14] | [15] | C:\\programs\\foo | [16] | [17]",
189 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
190#endif
191 {"https://example.com/color/#green?no-red",
192 "https | [11] | [12] | [13] | example.com | [15] | /color/ | [16] | "
193 "green?no-red",
194 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK },
195 {"https://example.com/color/#green#no-red",
196 "https | [11] | [12] | [13] | example.com | [15] | /color/ | [16] | "
197 "green#no-red",
198 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK },
199 {"https://example.com/color/?green#no-red",
200 "https | [11] | [12] | [13] | example.com | [15] | /color/ | green | "
201 "no-red",
202 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK },
203 {"https://example.com/#color/?green#no-red",
204 "https | [11] | [12] | [13] | example.com | [15] | / | [16] | "
205 "color/?green#no-red",
206 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK },
207 {"https://example.#com/color/?green#no-red",
208 "https | [11] | [12] | [13] | example. | [15] | / | [16] | "
209 "com/color/?green#no-red",
210 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK },
211 {"http://[ab.be:1]/x", "",
212 CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT},
213 {"http://[ab.be]/x", "",
214 CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT},
215 /* URL without host name */
216 {"http://a:b@/x", "",
217 CURLU_DEFAULT_SCHEME, 0, CURLUE_NO_HOST},
218 {"boing:80",
219 "https | [11] | [12] | [13] | boing | 80 | / | [16] | [17]",
220 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
221 {"http://[fd00:a41::50]:8080",
222 "http | [11] | [12] | [13] | [fd00:a41::50] | 8080 | / | [16] | [17]",
223 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
224 {"http://[fd00:a41::50]/",
225 "http | [11] | [12] | [13] | [fd00:a41::50] | [15] | / | [16] | [17]",
226 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
227 {"http://[fd00:a41::50]",
228 "http | [11] | [12] | [13] | [fd00:a41::50] | [15] | / | [16] | [17]",
229 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
230 {"https://[::1%252]:1234",
231 "https | [11] | [12] | [13] | [::1] | 1234 | / | [16] | [17]",
232 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
233
234 /* here's "bad" zone id */
235 {"https://[fe80::20c:29ff:fe9c:409b%eth0]:1234",
236 "https | [11] | [12] | [13] | [fe80::20c:29ff:fe9c:409b] | 1234 "
237 "| / | [16] | [17]",
238 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
239 {"https://127.0.0.1:443",
240 "https | [11] | [12] | [13] | 127.0.0.1 | [15] | / | [16] | [17]",
241 0, CURLU_NO_DEFAULT_PORT, CURLUE_OK},
242 {"http://%3a:%3a@ex%0ample/%3f+?+%3f+%23#+%23%3f%g7",
243 "http | : | : | [13] | [6] | [15] | /?+ | ? # | +#?%g7",
244 0, CURLU_URLDECODE, CURLUE_OK},
245 {"http://%3a:%3a@ex%0ample/%3f?%3f%35#%35%3f%g7",
246 "http | %3a | %3a | [13] | ex%0ample | [15] | /%3f | %3f%35 | %35%3f%g7",
247 0, 0, CURLUE_OK},
248 {"http://HO0_-st%41/",
249 "http | [11] | [12] | [13] | HO0_-st%41 | [15] | / | [16] | [17]",
250 0, 0, CURLUE_OK},
251 {"file://hello.html",
252 "",
253 0, 0, CURLUE_MALFORMED_INPUT},
254 {"http://HO0_-st/",
255 "http | [11] | [12] | [13] | HO0_-st | [15] | / | [16] | [17]",
256 0, 0, CURLUE_OK},
257 {"imap://user:pass;option@server/path",
258 "imap | user | pass | option | server | [15] | /path | [16] | [17]",
259 0, 0, CURLUE_OK},
260 {"http://user:pass;option@server/path",
261 "http | user | pass;option | [13] | server | [15] | /path | [16] | [17]",
262 0, 0, CURLUE_OK},
263 {"file:/hello.html",
264 "file | [11] | [12] | [13] | [14] | [15] | /hello.html | [16] | [17]",
265 0, 0, CURLUE_OK},
266 {"file://127.0.0.1/hello.html",
267 "file | [11] | [12] | [13] | [14] | [15] | /hello.html | [16] | [17]",
268 0, 0, CURLUE_OK},
269 {"file:////hello.html",
270 "file | [11] | [12] | [13] | [14] | [15] | //hello.html | [16] | [17]",
271 0, 0, CURLUE_OK},
272 {"file:///hello.html",
273 "file | [11] | [12] | [13] | [14] | [15] | /hello.html | [16] | [17]",
274 0, 0, CURLUE_OK},
275 {"https://127.0.0.1",
276 "https | [11] | [12] | [13] | 127.0.0.1 | 443 | / | [16] | [17]",
277 0, CURLU_DEFAULT_PORT, CURLUE_OK},
278 {"https://127.0.0.1",
279 "https | [11] | [12] | [13] | 127.0.0.1 | [15] | / | [16] | [17]",
280 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
281 {"https://[::1]:1234",
282 "https | [11] | [12] | [13] | [::1] | 1234 | / | [16] | [17]",
283 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
284 {"https://127abc.com",
285 "https | [11] | [12] | [13] | 127abc.com | [15] | / | [16] | [17]",
286 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
287 {"https:// example.com?check", "",
288 CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT},
289 {"https://e x a m p l e.com?check", "",
290 CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT},
291 {"https://example.com?check",
292 "https | [11] | [12] | [13] | example.com | [15] | / | check | [17]",
293 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
294 {"https://example.com:65536",
295 "",
296 CURLU_DEFAULT_SCHEME, 0, CURLUE_BAD_PORT_NUMBER},
297 {"https://example.com:0#moo",
298 "",
299 CURLU_DEFAULT_SCHEME, 0, CURLUE_BAD_PORT_NUMBER},
300 {"https://example.com:01#moo",
301 "https | [11] | [12] | [13] | example.com | 1 | / | "
302 "[16] | moo",
303 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
304 {"https://example.com:1#moo",
305 "https | [11] | [12] | [13] | example.com | 1 | / | "
306 "[16] | moo",
307 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
308 {"http://example.com#moo",
309 "http | [11] | [12] | [13] | example.com | [15] | / | "
310 "[16] | moo",
311 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
312 {"http://example.com",
313 "http | [11] | [12] | [13] | example.com | [15] | / | "
314 "[16] | [17]",
315 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
316 {"http://example.com/path/html",
317 "http | [11] | [12] | [13] | example.com | [15] | /path/html | "
318 "[16] | [17]",
319 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
320 {"http://example.com/path/html?query=name",
321 "http | [11] | [12] | [13] | example.com | [15] | /path/html | "
322 "query=name | [17]",
323 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
324 {"http://example.com/path/html?query=name#anchor",
325 "http | [11] | [12] | [13] | example.com | [15] | /path/html | "
326 "query=name | anchor",
327 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
328 {"http://example.com:1234/path/html?query=name#anchor",
329 "http | [11] | [12] | [13] | example.com | 1234 | /path/html | "
330 "query=name | anchor",
331 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
332 {"http:///user:password@example.com:1234/path/html?query=name#anchor",
333 "http | user | password | [13] | example.com | 1234 | /path/html | "
334 "query=name | anchor",
335 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
336 {"https://user:password@example.com:1234/path/html?query=name#anchor",
337 "https | user | password | [13] | example.com | 1234 | /path/html | "
338 "query=name | anchor",
339 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
340 {"http://user:password@example.com:1234/path/html?query=name#anchor",
341 "http | user | password | [13] | example.com | 1234 | /path/html | "
342 "query=name | anchor",
343 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
344 {"http:/user:password@example.com:1234/path/html?query=name#anchor",
345 "http | user | password | [13] | example.com | 1234 | /path/html | "
346 "query=name | anchor",
347 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
348 {"http:////user:password@example.com:1234/path/html?query=name#anchor",
349 "",
350 CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT},
351 {NULL, NULL, 0, 0, CURLUE_OK},
352};
353
354static struct urltestcase get_url_list[] = {
355 /* IPv4 trickeries */
356 {"https://16843009", "https://1.1.1.1/", 0, 0, CURLUE_OK},
357 {"https://0x7f.1", "https://127.0.0.1/", 0, 0, CURLUE_OK},
358 {"https://0177.1", "https://127.0.0.1/", 0, 0, CURLUE_OK},
359 {"https://0111.02.0x3", "https://73.2.0.3/", 0, 0, CURLUE_OK},
360 {"https://0xff.0xff.0377.255", "https://255.255.255.255/", 0, 0, CURLUE_OK},
361 {"https://1.0xffffff", "https://1.255.255.255/", 0, 0, CURLUE_OK},
362 /* IPv4 numerical overflows or syntax errors will not normalize */
363 {"https://+127.0.0.1", "https://+127.0.0.1/", 0, 0, CURLUE_OK},
364 {"https://127.-0.0.1", "https://127.-0.0.1/", 0, 0, CURLUE_OK},
365 {"https://127.0. 1", "https://127.0.0.1/", 0, 0, CURLUE_MALFORMED_INPUT},
366 {"https://1.0x1000000", "https://1.0x1000000/", 0, 0, CURLUE_OK},
367 {"https://1.2.3.256", "https://1.2.3.256/", 0, 0, CURLUE_OK},
368 {"https://1.2.3.4.5", "https://1.2.3.4.5/", 0, 0, CURLUE_OK},
369 {"https://1.2.0x100.3", "https://1.2.0x100.3/", 0, 0, CURLUE_OK},
370 {"https://4294967296", "https://4294967296/", 0, 0, CURLUE_OK},
371 /* 40 bytes scheme is the max allowed */
372 {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA://hostname/path",
373 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa://hostname/path",
374 CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_OK},
375 /* 41 bytes scheme is not allowed */
376 {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA://hostname/path",
377 "",
378 CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_MALFORMED_INPUT},
379 {"https://[fe80::20c:29ff:fe9c:409b%]:1234",
380 "",
381 0, 0, CURLUE_MALFORMED_INPUT},
382 {"https://[fe80::20c:29ff:fe9c:409b%25]:1234",
383 "https://[fe80::20c:29ff:fe9c:409b%2525]:1234/",
384 0, 0, CURLUE_OK},
385 {"https://[fe80::20c:29ff:fe9c:409b%eth0]:1234",
386 "https://[fe80::20c:29ff:fe9c:409b%25eth0]:1234/",
387 0, 0, CURLUE_OK},
388 {"https://[::%25fakeit]/moo",
389 "https://[::%25fakeit]/moo",
390 0, 0, CURLUE_OK},
391 {"smtp.example.com/path/html",
392 "smtp://smtp.example.com/path/html",
393 CURLU_GUESS_SCHEME, 0, CURLUE_OK},
394 {"https.example.com/path/html",
395 "http://https.example.com/path/html",
396 CURLU_GUESS_SCHEME, 0, CURLUE_OK},
397 {"dict.example.com/path/html",
398 "dict://dict.example.com/path/html",
399 CURLU_GUESS_SCHEME, 0, CURLUE_OK},
400 {"pop3.example.com/path/html",
401 "pop3://pop3.example.com/path/html",
402 CURLU_GUESS_SCHEME, 0, CURLUE_OK},
403 {"ldap.example.com/path/html",
404 "ldap://ldap.example.com/path/html",
405 CURLU_GUESS_SCHEME, 0, CURLUE_OK},
406 {"imap.example.com/path/html",
407 "imap://imap.example.com/path/html",
408 CURLU_GUESS_SCHEME, 0, CURLUE_OK},
409 {"ftp.example.com/path/html",
410 "ftp://ftp.example.com/path/html",
411 CURLU_GUESS_SCHEME, 0, CURLUE_OK},
412 {"example.com/path/html",
413 "http://example.com/path/html",
414 CURLU_GUESS_SCHEME, 0, CURLUE_OK},
415 {"HTTP://test/", "http://test/", 0, 0, CURLUE_OK},
416 {"http://HO0_-st..~./", "http://HO0_-st..~./", 0, 0, CURLUE_OK},
417 {"http:/@example.com: 123/", "", 0, 0, CURLUE_MALFORMED_INPUT},
418 {"http:/@example.com:123 /", "", 0, 0, CURLUE_MALFORMED_INPUT},
419 {"http:/@example.com:123a/", "", 0, 0, CURLUE_BAD_PORT_NUMBER},
420 {"http://host/file\r", "", 0, 0, CURLUE_MALFORMED_INPUT},
421 {"http://host/file\n\x03", "", 0, 0, CURLUE_MALFORMED_INPUT},
422 {"htt\x02://host/file", "",
423 CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_MALFORMED_INPUT},
424 {" http://host/file", "", 0, 0, CURLUE_MALFORMED_INPUT},
425 /* here the password ends at the semicolon and options is 'word' */
426 {"imap://user:pass;word@host/file",
427 "imap://user:pass;word@host/file",
428 0, 0, CURLUE_OK},
429 /* here the password has the semicolon */
430 {"http://user:pass;word@host/file",
431 "http://user:pass;word@host/file",
432 0, 0, CURLUE_OK},
433 {"file:///file.txt#moo",
434 "file:///file.txt#moo",
435 0, 0, CURLUE_OK},
436 {"file:////file.txt",
437 "file:////file.txt",
438 0, 0, CURLUE_OK},
439 {"file:///file.txt",
440 "file:///file.txt",
441 0, 0, CURLUE_OK},
442 {"file:./",
443 "file://",
444 0, 0, CURLUE_MALFORMED_INPUT},
445 {"http://example.com/hello/../here",
446 "http://example.com/hello/../here",
447 CURLU_PATH_AS_IS, 0, CURLUE_OK},
448 {"http://example.com/hello/../here",
449 "http://example.com/here",
450 0, 0, CURLUE_OK},
451 {"http://example.com:80",
452 "http://example.com/",
453 0, CURLU_NO_DEFAULT_PORT, CURLUE_OK},
454 {"tp://example.com/path/html",
455 "",
456 0, 0, CURLUE_UNSUPPORTED_SCHEME},
457 {"http://hello:fool@example.com",
458 "",
459 CURLU_DISALLOW_USER, 0, CURLUE_USER_NOT_ALLOWED},
460 {"http:/@example.com:123",
461 "http://example.com:123/",
462 0, 0, CURLUE_OK},
463 {"http:/:password@example.com",
464 "http://:password@example.com/",
465 0, 0, CURLUE_OK},
466 {"http://user@example.com?#",
467 "http://user@example.com/",
468 0, 0, CURLUE_OK},
469 {"http://user@example.com?",
470 "http://user@example.com/",
471 0, 0, CURLUE_OK},
472 {"http://user@example.com#anchor",
473 "http://user@example.com/#anchor",
474 0, 0, CURLUE_OK},
475 {"example.com/path/html",
476 "https://example.com/path/html",
477 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
478 {"example.com/path/html",
479 "",
480 0, 0, CURLUE_MALFORMED_INPUT},
481 {"http://user:password@example.com:1234/path/html?query=name#anchor",
482 "http://user:password@example.com:1234/path/html?query=name#anchor",
483 0, 0, CURLUE_OK},
484 {"http://example.com:1234/path/html?query=name#anchor",
485 "http://example.com:1234/path/html?query=name#anchor",
486 0, 0, CURLUE_OK},
487 {"http://example.com/path/html?query=name#anchor",
488 "http://example.com/path/html?query=name#anchor",
489 0, 0, CURLUE_OK},
490 {"http://example.com/path/html?query=name",
491 "http://example.com/path/html?query=name",
492 0, 0, CURLUE_OK},
493 {"http://example.com/path/html",
494 "http://example.com/path/html",
495 0, 0, CURLUE_OK},
496 {"tp://example.com/path/html",
497 "tp://example.com/path/html",
498 CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_OK},
499 {"custom-scheme://host?expected=test-good",
500 "custom-scheme://host/?expected=test-good",
501 CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_OK},
502 {"custom-scheme://?expected=test-bad",
503 "",
504 CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_MALFORMED_INPUT},
505 {"custom-scheme://?expected=test-new-good",
506 "custom-scheme:///?expected=test-new-good",
507 CURLU_NON_SUPPORT_SCHEME | CURLU_NO_AUTHORITY, 0, CURLUE_OK},
508 {"custom-scheme://host?expected=test-still-good",
509 "custom-scheme://host/?expected=test-still-good",
510 CURLU_NON_SUPPORT_SCHEME | CURLU_NO_AUTHORITY, 0, CURLUE_OK},
511 {NULL, NULL, 0, 0, 0}
512};
513
514static int checkurl(const char *url, const char *out)
515{
516 if(strcmp(out, url)) {
517 fprintf(stderr, "Wanted: %s\nGot : %s\n",
518 out, url);
519 return 1;
520 }
521 return 0;
522}
523
524/* !checksrc! disable SPACEBEFORECOMMA 1 */
525static struct setcase set_parts_list[] = {
526 {"https://example.com/",
527 "query=Al2cO3tDkcDZ3EWE5Lh+LX8TPHs,", /* contains '+' */
528 "https://example.com/?Al2cO3tDkcDZ3EWE5Lh%2bLX8TPHs",
529 CURLU_URLDECODE, /* decode on get */
530 CURLU_URLENCODE, /* encode on set */
531 CURLUE_OK, CURLUE_OK},
532
533 {"https://example.com/",
534 /* Set a 41 bytes scheme. That's too long so the old scheme remains set. */
535 "scheme=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc,",
536 "https://example.com/",
537 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_MALFORMED_INPUT},
538 {"https://example.com/",
539 /* set a 40 bytes scheme */
540 "scheme=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,",
541 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb://example.com/",
542 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_OK},
543 {"https://[::1%25fake]:1234/",
544 "zoneid=NULL,",
545 "https://[::1]:1234/",
546 0, 0, CURLUE_OK, CURLUE_OK},
547 {"https://host:1234/",
548 "port=NULL,",
549 "https://host/",
550 0, 0, CURLUE_OK, CURLUE_OK},
551 {"https://host:1234/",
552 "port=\"\",",
553 "https://host:1234/",
554 0, 0, CURLUE_OK, CURLUE_BAD_PORT_NUMBER},
555 {"https://host:1234/",
556 "port=56 78,",
557 "https://host:1234/",
558 0, 0, CURLUE_OK, CURLUE_MALFORMED_INPUT},
559 {"https://host:1234/",
560 "port=0,",
561 "https://host:1234/",
562 0, 0, CURLUE_OK, CURLUE_BAD_PORT_NUMBER},
563 {"https://host:1234/",
564 "port=65535,",
565 "https://host:65535/",
566 0, 0, CURLUE_OK, CURLUE_OK},
567 {"https://host:1234/",
568 "port=65536,",
569 "https://host:1234/",
570 0, 0, CURLUE_OK, CURLUE_BAD_PORT_NUMBER},
571 {"https://host/",
572 "path=%4A%4B%4C,",
573 "https://host/%4a%4b%4c",
574 0, 0, CURLUE_OK, CURLUE_OK},
575 {"https://host/mooo?q#f",
576 "path=NULL,query=NULL,fragment=NULL,",
577 "https://host/",
578 0, 0, CURLUE_OK, CURLUE_OK},
579 {"https://user:secret@host/",
580 "user=NULL,password=NULL,",
581 "https://host/",
582 0, 0, CURLUE_OK, CURLUE_OK},
583 {NULL,
584 "scheme=https,user= @:,host=foobar,",
585 "https://%20%20%20%40%3a@foobar/",
586 0, CURLU_URLENCODE, CURLUE_OK, CURLUE_OK},
587 {NULL,
588 "scheme=https,host= ,path= ,user= ,password= ,query= ,fragment= ,",
589 "https://%20:%20@%20%20/%20?+#%20",
590 0, CURLU_URLENCODE, CURLUE_OK, CURLUE_OK},
591 {NULL,
592 "scheme=https,host=foobar,path=/this /path /is /here,",
593 "https://foobar/this%20/path%20/is%20/here",
594 0, CURLU_URLENCODE, CURLUE_OK, CURLUE_OK},
595 {NULL,
596 "scheme=https,host=foobar,path=\xc3\xa4\xc3\xb6\xc3\xbc,",
597 "https://foobar/%c3%a4%c3%b6%c3%bc",
598 0, CURLU_URLENCODE, CURLUE_OK, CURLUE_OK},
599 {"imap://user:secret;opt@host/",
600 "options=updated,scheme=imaps,password=p4ssw0rd,",
601 "imaps://user:p4ssw0rd;updated@host/",
602 0, 0, CURLUE_NO_HOST, CURLUE_OK},
603 {"imap://user:secret;optit@host/",
604 "scheme=https,",
605 "https://user:secret@host/",
606 0, 0, CURLUE_NO_HOST, CURLUE_OK},
607 {"file:///file#anchor",
608 "scheme=https,host=example,",
609 "https://example/file#anchor",
610 0, 0, CURLUE_NO_HOST, CURLUE_OK},
611 {NULL, /* start fresh! */
612 "scheme=file,host=127.0.0.1,path=/no,user=anonymous,",
613 "file:///no",
614 0, 0, CURLUE_OK, CURLUE_OK},
615 {NULL, /* start fresh! */
616 "scheme=ftp,host=127.0.0.1,path=/no,user=anonymous,",
617 "ftp://anonymous@127.0.0.1/no",
618 0, 0, CURLUE_OK, CURLUE_OK},
619 {NULL, /* start fresh! */
620 "scheme=https,host=example.com,",
621 "https://example.com/",
622 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_OK},
623 {"http://user:foo@example.com/path?query#frag",
624 "fragment=changed,",
625 "http://user:foo@example.com/path?query#changed",
626 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_OK},
627 {"http://example.com/",
628 "scheme=foo,", /* not accepted */
629 "http://example.com/",
630 0, 0, CURLUE_OK, CURLUE_UNSUPPORTED_SCHEME},
631 {"http://example.com/",
632 "scheme=https,path=/hello,fragment=snippet,",
633 "https://example.com/hello#snippet",
634 0, 0, CURLUE_OK, CURLUE_OK},
635 {"http://example.com:80",
636 "user=foo,port=1922,",
637 "http://foo@example.com:1922/",
638 0, 0, CURLUE_OK, CURLUE_OK},
639 {"http://example.com:80",
640 "user=foo,password=bar,",
641 "http://foo:bar@example.com:80/",
642 0, 0, CURLUE_OK, CURLUE_OK},
643 {"http://example.com:80",
644 "user=foo,",
645 "http://foo@example.com:80/",
646 0, 0, CURLUE_OK, CURLUE_OK},
647 {"http://example.com",
648 "host=www.example.com,",
649 "http://www.example.com/",
650 0, 0, CURLUE_OK, CURLUE_OK},
651 {"http://example.com:80",
652 "scheme=ftp,",
653 "ftp://example.com:80/",
654 0, 0, CURLUE_OK, CURLUE_OK},
655 {"custom-scheme://host",
656 "host=\"\",",
657 "custom-scheme://host/",
658 CURLU_NON_SUPPORT_SCHEME, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK,
659 CURLUE_MALFORMED_INPUT},
660 {"custom-scheme://host",
661 "host=\"\",",
662 "custom-scheme:///",
663 CURLU_NON_SUPPORT_SCHEME, CURLU_NON_SUPPORT_SCHEME | CURLU_NO_AUTHORITY,
664 CURLUE_OK, CURLUE_OK},
665
666 {NULL, NULL, NULL, 0, 0, 0, 0}
667};
668
669static CURLUPart part2id(char *part)
670{
671 if(!strcmp("url", part))
672 return CURLUPART_URL;
673 if(!strcmp("scheme", part))
674 return CURLUPART_SCHEME;
675 if(!strcmp("user", part))
676 return CURLUPART_USER;
677 if(!strcmp("password", part))
678 return CURLUPART_PASSWORD;
679 if(!strcmp("options", part))
680 return CURLUPART_OPTIONS;
681 if(!strcmp("host", part))
682 return CURLUPART_HOST;
683 if(!strcmp("port", part))
684 return CURLUPART_PORT;
685 if(!strcmp("path", part))
686 return CURLUPART_PATH;
687 if(!strcmp("query", part))
688 return CURLUPART_QUERY;
689 if(!strcmp("fragment", part))
690 return CURLUPART_FRAGMENT;
691 if(!strcmp("zoneid", part))
692 return CURLUPART_ZONEID;
693 return (CURLUPart)9999; /* bad input => bad output */
694}
695
696static CURLUcode updateurl(CURLU *u, const char *cmd, unsigned int setflags)
697{
698 const char *p = cmd;
699 CURLUcode uc;
700
701 /* make sure the last command ends with a comma too! */
702 while(p) {
703 char *e = strchr(p, ',');
704 if(e) {
705 size_t n = e-p;
706 char buf[80];
707 char part[80];
708 char value[80];
709
710 memset(part, 0, sizeof(part)); /* Avoid valgrind false positive. */
711 memset(value, 0, sizeof(value)); /* Avoid valgrind false positive. */
712 memcpy(buf, p, n);
713 buf[n] = 0;
714 if(2 == sscanf(buf, "%79[^=]=%79[^,]", part, value)) {
715 CURLUPart what = part2id(part);
716#if 0
717 /* for debugging this */
718 fprintf(stderr, "%s = %s [%d]\n", part, value, (int)what);
719#endif
720 if(what > CURLUPART_ZONEID)
721 fprintf(stderr, "UNKNOWN part '%s'\n", part);
722
723 if(!strcmp("NULL", value))
724 uc = curl_url_set(u, what, NULL, setflags);
725 else if(!strcmp("\"\"", value))
726 uc = curl_url_set(u, what, "", setflags);
727 else
728 uc = curl_url_set(u, what, value, setflags);
729 if(uc)
730 return uc;
731 }
732 p = e + 1;
733 continue;
734 }
735 break;
736 }
737 return CURLUE_OK;
738}
739
740static struct redircase set_url_list[] = {
741 {"http://example.org/static/favicon/wikipedia.ico",
742 "//fake.example.com/licenses/by-sa/3.0/",
743 "http://fake.example.com/licenses/by-sa/3.0/",
744 0, 0, 0},
745 {"https://example.org/static/favicon/wikipedia.ico",
746 "//fake.example.com/licenses/by-sa/3.0/",
747 "https://fake.example.com/licenses/by-sa/3.0/",
748 0, 0, 0},
749 {"file://localhost/path?query#frag",
750 "foo#another",
751 "file:///foo#another",
752 0, 0, 0},
753 {"http://example.com/path?query#frag",
754 "https://two.example.com/bradnew",
755 "https://two.example.com/bradnew",
756 0, 0, 0},
757 {"http://example.com/path?query#frag",
758 "../../newpage#foo",
759 "http://example.com/newpage#foo",
760 0, 0, 0},
761 {"http://user:foo@example.com/path?query#frag",
762 "../../newpage",
763 "http://user:foo@example.com/newpage",
764 0, 0, 0},
765 {"http://user:foo@example.com/path?query#frag",
766 "../newpage",
767 "http://user:foo@example.com/newpage",
768 0, 0, 0},
769 {NULL, NULL, NULL, 0, 0, 0}
770};
771
772static int set_url(void)
773{
774 int i;
775 int error = 0;
776
777 for(i = 0; set_url_list[i].in && !error; i++) {
778 CURLUcode rc;
779 CURLU *urlp = curl_url();
780 if(!urlp)
781 break;
782 rc = curl_url_set(urlp, CURLUPART_URL, set_url_list[i].in,
783 set_url_list[i].urlflags);
784 if(!rc) {
785 rc = curl_url_set(urlp, CURLUPART_URL, set_url_list[i].set,
786 set_url_list[i].setflags);
787 if(rc) {
788 fprintf(stderr, "%s:%d Set URL %s returned %d\n",
789 __FILE__, __LINE__, set_url_list[i].set,
790 (int)rc);
791 error++;
792 }
793 else {
794 char *url = NULL;
795 rc = curl_url_get(urlp, CURLUPART_URL, &url, 0);
796 if(rc) {
797 fprintf(stderr, "%s:%d Get URL returned %d\n",
798 __FILE__, __LINE__, (int)rc);
799 error++;
800 }
801 else {
802 if(checkurl(url, set_url_list[i].out)) {
803 error++;
804 }
805 }
806 curl_free(url);
807 }
808 }
809 else if(rc != set_url_list[i].ucode) {
810 fprintf(stderr, "Set URL\nin: %s\nreturned %d (expected %d)\n",
811 set_url_list[i].in, (int)rc, set_url_list[i].ucode);
812 error++;
813 }
814 curl_url_cleanup(urlp);
815 }
816 return error;
817}
818
819static int set_parts(void)
820{
821 int i;
822 int error = 0;
823
824 for(i = 0; set_parts_list[i].set && !error; i++) {
825 CURLUcode rc;
826 CURLU *urlp = curl_url();
827 if(!urlp) {
828 error++;
829 break;
830 }
831 if(set_parts_list[i].in)
832 rc = curl_url_set(urlp, CURLUPART_URL, set_parts_list[i].in,
833 set_parts_list[i].urlflags);
834 else
835 rc = CURLUE_OK;
836 if(!rc) {
837 char *url = NULL;
838 CURLUcode uc = updateurl(urlp, set_parts_list[i].set,
839 set_parts_list[i].setflags);
840
841 if(uc != set_parts_list[i].pcode) {
842 fprintf(stderr, "updateurl\nin: %s\nreturned %d (expected %d)\n",
843 set_parts_list[i].set, (int)uc, set_parts_list[i].pcode);
844 error++;
845 }
846
847 rc = curl_url_get(urlp, CURLUPART_URL, &url, 0);
848
849 if(rc) {
850 fprintf(stderr, "%s:%d Get URL returned %d\n",
851 __FILE__, __LINE__, (int)rc);
852 error++;
853 }
854 else if(checkurl(url, set_parts_list[i].out)) {
855 error++;
856 }
857 curl_free(url);
858 }
859 else if(rc != set_parts_list[i].ucode) {
860 fprintf(stderr, "Set parts\nin: %s\nreturned %d (expected %d)\n",
861 set_parts_list[i].in, (int)rc, set_parts_list[i].ucode);
862 error++;
863 }
864 curl_url_cleanup(urlp);
865 }
866 return error;
867}
868
869static int get_url(void)
870{
871 int i;
872 int error = 0;
873 for(i = 0; get_url_list[i].in && !error; i++) {
874 CURLUcode rc;
875 CURLU *urlp = curl_url();
876 if(!urlp) {
877 error++;
878 break;
879 }
880 rc = curl_url_set(urlp, CURLUPART_URL, get_url_list[i].in,
881 get_url_list[i].urlflags);
882 if(!rc) {
883 char *url = NULL;
884 rc = curl_url_get(urlp, CURLUPART_URL, &url, get_url_list[i].getflags);
885
886 if(rc) {
887 fprintf(stderr, "%s:%d returned %d\n",
888 __FILE__, __LINE__, (int)rc);
889 error++;
890 }
891 else {
892 if(checkurl(url, get_url_list[i].out)) {
893 error++;
894 }
895 }
896 curl_free(url);
897 }
898 else if(rc != get_url_list[i].ucode) {
899 fprintf(stderr, "Get URL\nin: %s\nreturned %d (expected %d)\n",
900 get_url_list[i].in, (int)rc, get_url_list[i].ucode);
901 error++;
902 }
903 curl_url_cleanup(urlp);
904 }
905 return error;
906}
907
908static int get_parts(void)
909{
910 int i;
911 int error = 0;
912 for(i = 0; get_parts_list[i].in && !error; i++) {
913 CURLUcode rc;
914 CURLU *urlp = curl_url();
915 if(!urlp) {
916 error++;
917 break;
918 }
919 rc = curl_url_set(urlp, CURLUPART_URL,
920 get_parts_list[i].in,
921 get_parts_list[i].urlflags);
922 if(rc != get_parts_list[i].ucode) {
923 fprintf(stderr, "Get parts\nin: %s\nreturned %d (expected %d)\n",
924 get_parts_list[i].in, (int)rc, get_parts_list[i].ucode);
925 error++;
926 }
927 else if(get_parts_list[i].ucode) {
928 /* the expected error happened */
929 }
930 else if(checkparts(urlp, get_parts_list[i].in, get_parts_list[i].out,
931 get_parts_list[i].getflags))
932 error++;
933 curl_url_cleanup(urlp);
934 }
935 return error;
936}
937
938static struct querycase append_list[] = {
939 {"HTTP://test/?s", "name=joe\x02", "http://test/?s&name=joe%02",
940 0, CURLU_URLENCODE, CURLUE_OK},
941 {"HTTP://test/?size=2#f", "name=joe=", "http://test/?size=2&name=joe%3d#f",
942 0, CURLU_URLENCODE, CURLUE_OK},
943 {"HTTP://test/?size=2#f", "name=joe doe",
944 "http://test/?size=2&name=joe+doe#f",
945 0, CURLU_URLENCODE, CURLUE_OK},
946 {"HTTP://test/", "name=joe", "http://test/?name=joe", 0, 0, CURLUE_OK},
947 {"HTTP://test/?size=2", "name=joe", "http://test/?size=2&name=joe",
948 0, 0, CURLUE_OK},
949 {"HTTP://test/?size=2&", "name=joe", "http://test/?size=2&name=joe",
950 0, 0, CURLUE_OK},
951 {"HTTP://test/?size=2#f", "name=joe", "http://test/?size=2&name=joe#f",
952 0, 0, CURLUE_OK},
953 {NULL, NULL, NULL, 0, 0, 0}
954};
955
956static int append(void)
957{
958 int i;
959 int error = 0;
960 for(i = 0; append_list[i].in && !error; i++) {
961 CURLUcode rc;
962 CURLU *urlp = curl_url();
963 if(!urlp) {
964 error++;
965 break;
966 }
967 rc = curl_url_set(urlp, CURLUPART_URL,
968 append_list[i].in,
969 append_list[i].urlflags);
970 if(rc)
971 error++;
972 else
973 rc = curl_url_set(urlp, CURLUPART_QUERY,
974 append_list[i].q,
975 append_list[i].qflags | CURLU_APPENDQUERY);
976 if(error)
977 ;
978 else if(rc != append_list[i].ucode) {
979 fprintf(stderr, "Append\nin: %s\nreturned %d (expected %d)\n",
980 append_list[i].in, (int)rc, append_list[i].ucode);
981 error++;
982 }
983 else if(append_list[i].ucode) {
984 /* the expected error happened */
985 }
986 else {
987 char *url;
988 rc = curl_url_get(urlp, CURLUPART_URL, &url, 0);
989 if(rc) {
990 fprintf(stderr, "%s:%d Get URL returned %d\n",
991 __FILE__, __LINE__, (int)rc);
992 error++;
993 }
994 else {
995 if(checkurl(url, append_list[i].out)) {
996 error++;
997 }
998 curl_free(url);
999 }
1000 }
1001 curl_url_cleanup(urlp);
1002 }
1003 return error;
1004}
1005
1006static int scopeid(void)
1007{
1008 CURLU *u = curl_url();
1009 int error = 0;
1010 CURLUcode rc;
1011 char *url;
1012
1013 rc = curl_url_set(u, CURLUPART_URL,
1014 "https://[fe80::20c:29ff:fe9c:409b%25eth0]/hello.html", 0);
1015 if(rc != CURLUE_OK) {
1016 fprintf(stderr, "%s:%d curl_url_set returned %d\n",
1017 __FILE__, __LINE__, (int)rc);
1018 error++;
1019 }
1020
1021 rc = curl_url_get(u, CURLUPART_HOST, &url, 0);
1022 if(rc != CURLUE_OK) {
1023 fprintf(stderr, "%s:%d curl_url_get CURLUPART_HOST returned %d\n",
1024 __FILE__, __LINE__, (int)rc);
1025 error++;
1026 }
1027 else {
1028 printf("we got %s\n", url);
1029 curl_free(url);
1030 }
1031
1032 rc = curl_url_set(u, CURLUPART_HOST, "[::1]", 0);
1033 if(rc != CURLUE_OK) {
1034 fprintf(stderr, "%s:%d curl_url_set CURLUPART_HOST returned %d\n",
1035 __FILE__, __LINE__, (int)rc);
1036 error++;
1037 }
1038
1039 rc = curl_url_get(u, CURLUPART_URL, &url, 0);
1040 if(rc != CURLUE_OK) {
1041 fprintf(stderr, "%s:%d curl_url_get CURLUPART_URL returned %d\n",
1042 __FILE__, __LINE__, (int)rc);
1043 error++;
1044 }
1045 else {
1046 printf("we got %s\n", url);
1047 curl_free(url);
1048 }
1049
1050 rc = curl_url_set(u, CURLUPART_HOST, "example.com", 0);
1051 if(rc != CURLUE_OK) {
1052 fprintf(stderr, "%s:%d curl_url_set CURLUPART_HOST returned %d\n",
1053 __FILE__, __LINE__, (int)rc);
1054 error++;
1055 }
1056
1057 rc = curl_url_get(u, CURLUPART_URL, &url, 0);
1058 if(rc != CURLUE_OK) {
1059 fprintf(stderr, "%s:%d curl_url_get CURLUPART_URL returned %d\n",
1060 __FILE__, __LINE__, (int)rc);
1061 error++;
1062 }
1063 else {
1064 printf("we got %s\n", url);
1065 curl_free(url);
1066 }
1067
1068 rc = curl_url_set(u, CURLUPART_HOST,
1069 "[fe80::20c:29ff:fe9c:409b%25eth0]", 0);
1070 if(rc != CURLUE_OK) {
1071 fprintf(stderr, "%s:%d curl_url_set CURLUPART_HOST returned %d\n",
1072 __FILE__, __LINE__, (int)rc);
1073 error++;
1074 }
1075
1076 rc = curl_url_get(u, CURLUPART_URL, &url, 0);
1077 if(rc != CURLUE_OK) {
1078 fprintf(stderr, "%s:%d curl_url_get CURLUPART_URL returned %d\n",
1079 __FILE__, __LINE__, (int)rc);
1080 error++;
1081 }
1082 else {
1083 printf("we got %s\n", url);
1084 curl_free(url);
1085 }
1086
1087 rc = curl_url_get(u, CURLUPART_HOST, &url, 0);
1088 if(rc != CURLUE_OK) {
1089 fprintf(stderr, "%s:%d curl_url_get CURLUPART_HOST returned %d\n",
1090 __FILE__, __LINE__, (int)rc);
1091 error++;
1092 }
1093 else {
1094 printf("we got %s\n", url);
1095 curl_free(url);
1096 }
1097
1098 rc = curl_url_get(u, CURLUPART_ZONEID, &url, 0);
1099 if(rc != CURLUE_OK) {
1100 fprintf(stderr, "%s:%d curl_url_get CURLUPART_ZONEID returned %d\n",
1101 __FILE__, __LINE__, (int)rc);
1102 error++;
1103 }
1104 else {
1105 printf("we got %s\n", url);
1106 curl_free(url);
1107 }
1108
1109 rc = curl_url_set(u, CURLUPART_ZONEID, "clown", 0);
1110 if(rc != CURLUE_OK) {
1111 fprintf(stderr, "%s:%d curl_url_set CURLUPART_ZONEID returned %d\n",
1112 __FILE__, __LINE__, (int)rc);
1113 error++;
1114 }
1115
1116 rc = curl_url_get(u, CURLUPART_URL, &url, 0);
1117 if(rc != CURLUE_OK) {
1118 fprintf(stderr, "%s:%d curl_url_get CURLUPART_URL returned %d\n",
1119 __FILE__, __LINE__, (int)rc);
1120 error++;
1121 }
1122 else {
1123 printf("we got %s\n", url);
1124 curl_free(url);
1125 }
1126
1127 curl_url_cleanup(u);
1128
1129 return error;
1130}
1131
1132int test(char *URL)
1133{
1134 (void)URL; /* not used */
1135
1136 if(scopeid())
1137 return 6;
1138
1139 if(append())
1140 return 5;
1141
1142 if(set_url())
1143 return 1;
1144
1145 if(set_parts())
1146 return 2;
1147
1148 if(get_url())
1149 return 3;
1150
1151 if(get_parts())
1152 return 4;
1153
1154 printf("success\n");
1155 return 0;
1156}
1157