1 /***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 1998 - 2018, 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.haxx.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
37 struct part {
38 CURLUPart part;
39 const char *name;
40 };
41
42
checkparts(CURLU * u,const char * in,const char * wanted,unsigned int getflags)43 static 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 buf[0] = 0;
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
87 struct 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
96 struct setcase {
97 const char *in;
98 const char *set;
99 const char *out;
100 unsigned int urlflags;
101 unsigned int setflags;
102 CURLUcode ucode;
103 };
104
105 struct testcase {
106 const char *in;
107 const char *out;
108 unsigned int urlflags;
109 unsigned int getflags;
110 CURLUcode ucode;
111 };
112
113 struct urltestcase {
114 const char *in;
115 const char *out;
116 unsigned int urlflags; /* pass to curl_url() */
117 unsigned int getflags; /* pass to curl_url_get() */
118 CURLUcode ucode;
119 };
120
121 struct querycase {
122 const char *in;
123 const char *q;
124 const char *out;
125 unsigned int urlflags; /* pass to curl_url() */
126 unsigned int qflags; /* pass to curl_url_get() */
127 CURLUcode ucode;
128 };
129
130 static struct testcase get_parts_list[] ={
131 #ifdef WIN32
132 {"file:/C:\\programs\\foo",
133 "file | [11] | [12] | [13] | [14] | [15] | C:\\programs\\foo | [16] | [17]",
134 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
135 {"file://C:\\programs\\foo",
136 "file | [11] | [12] | [13] | [14] | [15] | C:\\programs\\foo | [16] | [17]",
137 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
138 {"file:///C:\\programs\\foo",
139 "file | [11] | [12] | [13] | [14] | [15] | C:\\programs\\foo | [16] | [17]",
140 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
141 #endif
142 {"boing:80",
143 "https | [11] | [12] | [13] | boing | 80 | / | [16] | [17]",
144 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
145 {"http://[fd00:a41::50]:8080",
146 "http | [11] | [12] | [13] | [fd00:a41::50] | 8080 | / | [16] | [17]",
147 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
148 {"http://[fd00:a41::50]/",
149 "http | [11] | [12] | [13] | [fd00:a41::50] | [15] | / | [16] | [17]",
150 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
151 {"http://[fd00:a41::50]",
152 "http | [11] | [12] | [13] | [fd00:a41::50] | [15] | / | [16] | [17]",
153 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
154 {"https://[::1%252]:1234",
155 "https | [11] | [12] | [13] | [::1%252] | 1234 | / | [16] | [17]",
156 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
157 {"https://127.0.0.1:443",
158 "https | [11] | [12] | [13] | 127.0.0.1 | [15] | / | [16] | [17]",
159 0, CURLU_NO_DEFAULT_PORT, CURLUE_OK},
160 {"http://%3a:%3a@ex%0ample/%3f+?+%3f+%23#+%23%3f%g7",
161 "http | : | : | [13] | [6] | [15] | /?+ | ? # | +#?%g7",
162 0, CURLU_URLDECODE, CURLUE_OK},
163 {"http://%3a:%3a@ex%0ample/%3f?%3f%35#%35%3f%g7",
164 "http | %3a | %3a | [13] | ex%0ample | [15] | /%3f | %3f%35 | %35%3f%g7",
165 0, 0, CURLUE_OK},
166 {"http://HO0_-st%41/",
167 "http | [11] | [12] | [13] | HO0_-st%41 | [15] | / | [16] | [17]",
168 0, 0, CURLUE_OK},
169 {"file://hello.html",
170 "",
171 0, 0, CURLUE_MALFORMED_INPUT},
172 {"http://HO0_-st/",
173 "http | [11] | [12] | [13] | HO0_-st | [15] | / | [16] | [17]",
174 0, 0, CURLUE_OK},
175 {"imap://user:pass;option@server/path",
176 "imap | user | pass | option | server | [15] | /path | [16] | [17]",
177 0, 0, CURLUE_OK},
178 {"http://user:pass;option@server/path",
179 "http | user | pass;option | [13] | server | [15] | /path | [16] | [17]",
180 0, 0, CURLUE_OK},
181 {"file:/hello.html",
182 "file | [11] | [12] | [13] | [14] | [15] | /hello.html | [16] | [17]",
183 0, 0, CURLUE_OK},
184 {"file://127.0.0.1/hello.html",
185 "file | [11] | [12] | [13] | [14] | [15] | /hello.html | [16] | [17]",
186 0, 0, CURLUE_OK},
187 {"file:////hello.html",
188 "file | [11] | [12] | [13] | [14] | [15] | //hello.html | [16] | [17]",
189 0, 0, CURLUE_OK},
190 {"file:///hello.html",
191 "file | [11] | [12] | [13] | [14] | [15] | /hello.html | [16] | [17]",
192 0, 0, CURLUE_OK},
193 {"https://127.0.0.1",
194 "https | [11] | [12] | [13] | 127.0.0.1 | 443 | / | [16] | [17]",
195 0, CURLU_DEFAULT_PORT, CURLUE_OK},
196 {"https://127.0.0.1",
197 "https | [11] | [12] | [13] | 127.0.0.1 | [15] | / | [16] | [17]",
198 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
199 {"https://[::1]:1234",
200 "https | [11] | [12] | [13] | [::1] | 1234 | / | [16] | [17]",
201 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
202 {"https://127abc.com",
203 "https | [11] | [12] | [13] | 127abc.com | [15] | / | [16] | [17]",
204 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
205 {"https:// example.com?check",
206 "",
207 CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT},
208 {"https://e x a m p l e.com?check",
209 "",
210 CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT},
211 {"https://example.com?check",
212 "https | [11] | [12] | [13] | example.com | [15] | / | check | [17]",
213 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
214 {"https://example.com:65536",
215 "",
216 CURLU_DEFAULT_SCHEME, 0, CURLUE_BAD_PORT_NUMBER},
217 {"https://example.com:0#moo",
218 "",
219 CURLU_DEFAULT_SCHEME, 0, CURLUE_BAD_PORT_NUMBER},
220 {"https://example.com:01#moo",
221 "https | [11] | [12] | [13] | example.com | 1 | / | "
222 "[16] | moo",
223 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
224 {"https://example.com:1#moo",
225 "https | [11] | [12] | [13] | example.com | 1 | / | "
226 "[16] | moo",
227 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
228 {"http://example.com#moo",
229 "http | [11] | [12] | [13] | example.com | [15] | / | "
230 "[16] | moo",
231 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
232 {"http://example.com",
233 "http | [11] | [12] | [13] | example.com | [15] | / | "
234 "[16] | [17]",
235 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
236 {"http://example.com/path/html",
237 "http | [11] | [12] | [13] | example.com | [15] | /path/html | "
238 "[16] | [17]",
239 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
240 {"http://example.com/path/html?query=name",
241 "http | [11] | [12] | [13] | example.com | [15] | /path/html | "
242 "query=name | [17]",
243 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
244 {"http://example.com/path/html?query=name#anchor",
245 "http | [11] | [12] | [13] | example.com | [15] | /path/html | "
246 "query=name | anchor",
247 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
248 {"http://example.com:1234/path/html?query=name#anchor",
249 "http | [11] | [12] | [13] | example.com | 1234 | /path/html | "
250 "query=name | anchor",
251 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
252 {"http:///user:password@example.com:1234/path/html?query=name#anchor",
253 "http | user | password | [13] | example.com | 1234 | /path/html | "
254 "query=name | anchor",
255 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
256 {"https://user:password@example.com:1234/path/html?query=name#anchor",
257 "https | user | password | [13] | example.com | 1234 | /path/html | "
258 "query=name | anchor",
259 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
260 {"http://user:password@example.com:1234/path/html?query=name#anchor",
261 "http | user | password | [13] | example.com | 1234 | /path/html | "
262 "query=name | anchor",
263 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
264 {"http:/user:password@example.com:1234/path/html?query=name#anchor",
265 "http | user | password | [13] | example.com | 1234 | /path/html | "
266 "query=name | anchor",
267 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
268 {"http:////user:password@example.com:1234/path/html?query=name#anchor",
269 "",
270 CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT},
271 {NULL, NULL, 0, 0, CURLUE_OK},
272 };
273
274 static struct urltestcase get_url_list[] = {
275 {"smtp.example.com/path/html",
276 "smtp://smtp.example.com/path/html",
277 CURLU_GUESS_SCHEME, 0, CURLUE_OK},
278 {"https.example.com/path/html",
279 "http://https.example.com/path/html",
280 CURLU_GUESS_SCHEME, 0, CURLUE_OK},
281 {"dict.example.com/path/html",
282 "dict://dict.example.com/path/html",
283 CURLU_GUESS_SCHEME, 0, CURLUE_OK},
284 {"pop3.example.com/path/html",
285 "pop3://pop3.example.com/path/html",
286 CURLU_GUESS_SCHEME, 0, CURLUE_OK},
287 {"ldap.example.com/path/html",
288 "ldap://ldap.example.com/path/html",
289 CURLU_GUESS_SCHEME, 0, CURLUE_OK},
290 {"imap.example.com/path/html",
291 "imap://imap.example.com/path/html",
292 CURLU_GUESS_SCHEME, 0, CURLUE_OK},
293 {"ftp.example.com/path/html",
294 "ftp://ftp.example.com/path/html",
295 CURLU_GUESS_SCHEME, 0, CURLUE_OK},
296 {"example.com/path/html",
297 "http://example.com/path/html",
298 CURLU_GUESS_SCHEME, 0, CURLUE_OK},
299 {"HTTP://test/", "http://test/", 0, 0, CURLUE_OK},
300 {"http://HO0_-st..~./", "http://HO0_-st..~./", 0, 0, CURLUE_OK},
301 {"http:/@example.com: 123/", "", 0, 0, CURLUE_BAD_PORT_NUMBER},
302 {"http:/@example.com:123 /", "", 0, 0, CURLUE_BAD_PORT_NUMBER},
303 {"http:/@example.com:123a/", "", 0, 0, CURLUE_BAD_PORT_NUMBER},
304 {"http://host/file\r", "", 0, 0, CURLUE_MALFORMED_INPUT},
305 {"http://host/file\n\x03", "", 0, 0, CURLUE_MALFORMED_INPUT},
306 {"htt\x02://host/file", "",
307 CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_MALFORMED_INPUT},
308 {" http://host/file", "", 0, 0, CURLUE_MALFORMED_INPUT},
309 /* here the password ends at the semicolon and options is 'word' */
310 {"imap://user:pass;word@host/file",
311 "imap://user:pass;word@host/file",
312 0, 0, CURLUE_OK},
313 /* here the password has the semicolon */
314 {"http://user:pass;word@host/file",
315 "http://user:pass;word@host/file",
316 0, 0, CURLUE_OK},
317 {"file:///file.txt#moo",
318 "file:///file.txt#moo",
319 0, 0, CURLUE_OK},
320 {"file:////file.txt",
321 "file:////file.txt",
322 0, 0, CURLUE_OK},
323 {"file:///file.txt",
324 "file:///file.txt",
325 0, 0, CURLUE_OK},
326 {"file:./",
327 "file://",
328 0, 0, CURLUE_MALFORMED_INPUT},
329 {"http://example.com/hello/../here",
330 "http://example.com/hello/../here",
331 CURLU_PATH_AS_IS, 0, CURLUE_OK},
332 {"http://example.com/hello/../here",
333 "http://example.com/here",
334 0, 0, CURLUE_OK},
335 {"http://example.com:80",
336 "http://example.com/",
337 0, CURLU_NO_DEFAULT_PORT, CURLUE_OK},
338 {"tp://example.com/path/html",
339 "",
340 0, 0, CURLUE_UNSUPPORTED_SCHEME},
341 {"http://hello:fool@example.com",
342 "",
343 CURLU_DISALLOW_USER, 0, CURLUE_USER_NOT_ALLOWED},
344 {"http:/@example.com:123",
345 "http://example.com:123/",
346 0, 0, CURLUE_OK},
347 {"http:/:password@example.com",
348 "http://:password@example.com/",
349 0, 0, CURLUE_OK},
350 {"http://user@example.com?#",
351 "http://user@example.com/",
352 0, 0, CURLUE_OK},
353 {"http://user@example.com?",
354 "http://user@example.com/",
355 0, 0, CURLUE_OK},
356 {"http://user@example.com#anchor",
357 "http://user@example.com/#anchor",
358 0, 0, CURLUE_OK},
359 {"example.com/path/html",
360 "https://example.com/path/html",
361 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
362 {"example.com/path/html",
363 "",
364 0, 0, CURLUE_MALFORMED_INPUT},
365 {"http://user:password@example.com:1234/path/html?query=name#anchor",
366 "http://user:password@example.com:1234/path/html?query=name#anchor",
367 0, 0, CURLUE_OK},
368 {"http://example.com:1234/path/html?query=name#anchor",
369 "http://example.com:1234/path/html?query=name#anchor",
370 0, 0, CURLUE_OK},
371 {"http://example.com/path/html?query=name#anchor",
372 "http://example.com/path/html?query=name#anchor",
373 0, 0, CURLUE_OK},
374 {"http://example.com/path/html?query=name",
375 "http://example.com/path/html?query=name",
376 0, 0, CURLUE_OK},
377 {"http://example.com/path/html",
378 "http://example.com/path/html",
379 0, 0, CURLUE_OK},
380 {"tp://example.com/path/html",
381 "tp://example.com/path/html",
382 CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_OK},
383 {NULL, NULL, 0, 0, 0}
384 };
385
checkurl(const char * url,const char * out)386 static int checkurl(const char *url, const char *out)
387 {
388 if(strcmp(out, url)) {
389 fprintf(stderr, "Wanted: %s\nGot : %s\n",
390 out, url);
391 return 1;
392 }
393 return 0;
394 }
395
396 /* !checksrc! disable SPACEBEFORECOMMA 1 */
397 static struct setcase set_parts_list[] = {
398 {"https://host/",
399 "path=%4A%4B%4C,",
400 "https://host/%4a%4b%4c",
401 0, 0, CURLUE_NO_HOST},
402 {"https://host/mooo?q#f",
403 "path=NULL,query=NULL,fragment=NULL,",
404 "https://host/",
405 0, 0, CURLUE_NO_HOST},
406 {"https://user:secret@host/",
407 "user=NULL,password=NULL,",
408 "https://host/",
409 0, 0, CURLUE_NO_HOST},
410 {NULL,
411 "scheme=https,user= @:,host=foobar,",
412 "https://%20%20%20%40%3a@foobar/",
413 0, CURLU_URLENCODE, CURLUE_OK},
414 {NULL,
415 "scheme=https,host= ,path= ,user= ,password= ,query= ,fragment= ,",
416 "https://%20:%20@%20%20/%20?+#%20",
417 0, CURLU_URLENCODE, CURLUE_OK},
418 {NULL,
419 "scheme=https,host=foobar,path=/this /path /is /here,",
420 "https://foobar/this%20/path%20/is%20/here",
421 0, CURLU_URLENCODE, CURLUE_OK},
422 {"imap://user:secret;opt@host/",
423 "options=updated,scheme=imaps,password=p4ssw0rd,",
424 "imaps://user:p4ssw0rd;updated@host/",
425 0, 0, CURLUE_NO_HOST},
426 {"imap://user:secret;optit@host/",
427 "scheme=https,",
428 "https://user:secret@host/",
429 0, 0, CURLUE_NO_HOST},
430 {"file:///file#anchor",
431 "scheme=https,host=example,",
432 "https://example/file#anchor",
433 0, 0, CURLUE_NO_HOST},
434 {NULL, /* start fresh! */
435 "scheme=file,host=127.0.0.1,path=/no,user=anonymous,",
436 "file:///no",
437 0, 0, CURLUE_OK},
438 {NULL, /* start fresh! */
439 "scheme=ftp,host=127.0.0.1,path=/no,user=anonymous,",
440 "ftp://anonymous@127.0.0.1/no",
441 0, 0, CURLUE_OK},
442 {NULL, /* start fresh! */
443 "scheme=https,host=example.com,",
444 "https://example.com/",
445 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK},
446 {"http://user:foo@example.com/path?query#frag",
447 "fragment=changed,",
448 "http://user:foo@example.com/path?query#changed",
449 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK},
450 {"http://example.com/",
451 "scheme=foo,", /* not accepted */
452 "http://example.com/",
453 0, 0, CURLUE_OK},
454 {"http://example.com/",
455 "scheme=https,path=/hello,fragment=snippet,",
456 "https://example.com/hello#snippet",
457 0, 0, CURLUE_OK},
458 {"http://example.com:80",
459 "user=foo,port=1922,",
460 "http://foo@example.com:1922/",
461 0, 0, CURLUE_OK},
462 {"http://example.com:80",
463 "user=foo,password=bar,",
464 "http://foo:bar@example.com:80/",
465 0, 0, CURLUE_OK},
466 {"http://example.com:80",
467 "user=foo,",
468 "http://foo@example.com:80/",
469 0, 0, CURLUE_OK},
470 {"http://example.com",
471 "host=www.example.com,",
472 "http://www.example.com/",
473 0, 0, CURLUE_OK},
474 {"http://example.com:80",
475 "scheme=ftp,",
476 "ftp://example.com:80/",
477 0, 0, CURLUE_OK},
478 {NULL, NULL, NULL, 0, 0, 0}
479 };
480
part2id(char * part)481 static CURLUPart part2id(char *part)
482 {
483 if(!strcmp("url", part))
484 return CURLUPART_URL;
485 if(!strcmp("scheme", part))
486 return CURLUPART_SCHEME;
487 if(!strcmp("user", part))
488 return CURLUPART_USER;
489 if(!strcmp("password", part))
490 return CURLUPART_PASSWORD;
491 if(!strcmp("options", part))
492 return CURLUPART_OPTIONS;
493 if(!strcmp("host", part))
494 return CURLUPART_HOST;
495 if(!strcmp("port", part))
496 return CURLUPART_PORT;
497 if(!strcmp("path", part))
498 return CURLUPART_PATH;
499 if(!strcmp("query", part))
500 return CURLUPART_QUERY;
501 if(!strcmp("fragment", part))
502 return CURLUPART_FRAGMENT;
503 return 9999; /* bad input => bad output */
504 }
505
updateurl(CURLU * u,const char * cmd,unsigned int setflags)506 static void updateurl(CURLU *u, const char *cmd, unsigned int setflags)
507 {
508 const char *p = cmd;
509
510 /* make sure the last command ends with a comma too! */
511 while(p) {
512 char *e = strchr(p, ',');
513 if(e) {
514 size_t n = e-p;
515 char buf[80];
516 char part[80];
517 char value[80];
518 memcpy(buf, p, n);
519 buf[n] = 0;
520 if(2 == sscanf(buf, "%79[^=]=%79[^,]", part, value)) {
521 CURLUPart what = part2id(part);
522 #if 0
523 /* for debugging this */
524 fprintf(stderr, "%s = %s [%d]\n", part, value, (int)what);
525 #endif
526 if(!strcmp("NULL", value))
527 curl_url_set(u, what, NULL, setflags);
528 else
529 curl_url_set(u, what, value, setflags);
530 }
531 p = e + 1;
532 continue;
533 }
534 break;
535 }
536
537 }
538
539 static struct redircase set_url_list[] = {
540 {"file://localhost/path?query#frag",
541 "foo#another",
542 "file:///foo#another",
543 0, 0, 0},
544 {"http://example.com/path?query#frag",
545 "https://two.example.com/bradnew",
546 "https://two.example.com/bradnew",
547 0, 0, 0},
548 {"http://example.com/path?query#frag",
549 "../../newpage#foo",
550 "http://example.com/newpage#foo",
551 0, 0, 0},
552 {"http://user:foo@example.com/path?query#frag",
553 "../../newpage",
554 "http://user:foo@example.com/newpage",
555 0, 0, 0},
556 {"http://user:foo@example.com/path?query#frag",
557 "../newpage",
558 "http://user:foo@example.com/newpage",
559 0, 0, 0},
560 {NULL, NULL, NULL, 0, 0, 0}
561 };
562
set_url(void)563 static int set_url(void)
564 {
565 int i;
566 CURLUcode rc;
567 CURLU *urlp;
568 int error = 0;
569
570 for(i = 0; set_url_list[i].in && !error; i++) {
571 char *url = NULL;
572 urlp = curl_url();
573 if(!urlp)
574 break;
575 rc = curl_url_set(urlp, CURLUPART_URL, set_url_list[i].in,
576 set_url_list[i].urlflags);
577 if(!rc) {
578 rc = curl_url_set(urlp, CURLUPART_URL, set_url_list[i].set,
579 set_url_list[i].setflags);
580 if(rc) {
581 fprintf(stderr, "%s:%d Set URL %s returned %d\n",
582 __FILE__, __LINE__, set_url_list[i].set,
583 (int)rc);
584 error++;
585 }
586 else {
587 rc = curl_url_get(urlp, CURLUPART_URL, &url, 0);
588 if(rc) {
589 fprintf(stderr, "%s:%d Get URL returned %d\n",
590 __FILE__, __LINE__, (int)rc);
591 error++;
592 }
593 else {
594 if(checkurl(url, set_url_list[i].out)) {
595 error++;
596 }
597 }
598 }
599 curl_free(url);
600 }
601 else if(rc != set_url_list[i].ucode) {
602 fprintf(stderr, "Set URL\nin: %s\nreturned %d (expected %d)\n",
603 set_url_list[i].in, (int)rc, set_url_list[i].ucode);
604 error++;
605 }
606 curl_url_cleanup(urlp);
607 }
608 return error;
609 }
610
set_parts(void)611 static int set_parts(void)
612 {
613 int i;
614 CURLUcode rc;
615 int error = 0;
616
617 for(i = 0; set_parts_list[i].set && !error; i++) {
618 char *url = NULL;
619 CURLU *urlp = curl_url();
620 if(!urlp) {
621 error++;
622 break;
623 }
624 if(set_parts_list[i].in)
625 rc = curl_url_set(urlp, CURLUPART_URL, set_parts_list[i].in,
626 set_parts_list[i].urlflags);
627 else
628 rc = CURLUE_OK;
629 if(!rc) {
630 updateurl(urlp, set_parts_list[i].set, set_parts_list[i].setflags);
631 rc = curl_url_get(urlp, CURLUPART_URL, &url, 0);
632
633 if(rc) {
634 fprintf(stderr, "%s:%d Get URL returned %d\n",
635 __FILE__, __LINE__, (int)rc);
636 error++;
637 }
638 else if(checkurl(url, set_parts_list[i].out)) {
639 error++;
640 }
641 }
642 else if(rc != set_parts_list[i].ucode) {
643 fprintf(stderr, "Set parts\nin: %s\nreturned %d (expected %d)\n",
644 set_parts_list[i].in, (int)rc, set_parts_list[i].ucode);
645 error++;
646 }
647 curl_free(url);
648 curl_url_cleanup(urlp);
649 }
650 return error;
651 }
652
get_url(void)653 static int get_url(void)
654 {
655 int i;
656 CURLUcode rc;
657 int error = 0;
658 for(i = 0; get_url_list[i].in && !error; i++) {
659 char *url = NULL;
660 CURLU *urlp = curl_url();
661 if(!urlp) {
662 error++;
663 break;
664 }
665 rc = curl_url_set(urlp, CURLUPART_URL, get_url_list[i].in,
666 get_url_list[i].urlflags);
667 if(!rc) {
668 rc = curl_url_get(urlp, CURLUPART_URL, &url, get_url_list[i].getflags);
669
670 if(rc) {
671 fprintf(stderr, "%s:%d returned %d\n",
672 __FILE__, __LINE__, (int)rc);
673 error++;
674 }
675 else {
676 if(checkurl(url, get_url_list[i].out)) {
677 error++;
678 }
679 }
680 }
681 else if(rc != get_url_list[i].ucode) {
682 fprintf(stderr, "Get URL\nin: %s\nreturned %d (expected %d)\n",
683 get_url_list[i].in, (int)rc, get_url_list[i].ucode);
684 error++;
685 }
686 curl_free(url);
687 curl_url_cleanup(urlp);
688 }
689 return error;
690 }
691
get_parts(void)692 static int get_parts(void)
693 {
694 int i;
695 CURLUcode rc;
696 CURLU *urlp;
697 int error = 0;
698 for(i = 0; get_parts_list[i].in && !error; i++) {
699 urlp = curl_url();
700 if(!urlp) {
701 error++;
702 break;
703 }
704 rc = curl_url_set(urlp, CURLUPART_URL,
705 get_parts_list[i].in,
706 get_parts_list[i].urlflags);
707 if(rc != get_parts_list[i].ucode) {
708 fprintf(stderr, "Get parts\nin: %s\nreturned %d (expected %d)\n",
709 get_parts_list[i].in, (int)rc, get_parts_list[i].ucode);
710 error++;
711 }
712 else if(get_parts_list[i].ucode) {
713 /* the expected error happened */
714 }
715 else if(checkparts(urlp, get_parts_list[i].in, get_parts_list[i].out,
716 get_parts_list[i].getflags))
717 error++;
718 curl_url_cleanup(urlp);
719 }
720 return error;
721 }
722
723 static struct querycase append_list[] = {
724 {"HTTP://test/?s", "name=joe\x02", "http://test/?s&name=joe%02",
725 0, CURLU_URLENCODE, CURLUE_OK},
726 {"HTTP://test/?size=2#f", "name=joe=", "http://test/?size=2&name=joe%3d#f",
727 0, CURLU_URLENCODE, CURLUE_OK},
728 {"HTTP://test/?size=2#f", "name=joe doe",
729 "http://test/?size=2&name=joe+doe#f",
730 0, CURLU_URLENCODE, CURLUE_OK},
731 {"HTTP://test/", "name=joe", "http://test/?name=joe", 0, 0, CURLUE_OK},
732 {"HTTP://test/?size=2", "name=joe", "http://test/?size=2&name=joe",
733 0, 0, CURLUE_OK},
734 {"HTTP://test/?size=2&", "name=joe", "http://test/?size=2&name=joe",
735 0, 0, CURLUE_OK},
736 {"HTTP://test/?size=2#f", "name=joe", "http://test/?size=2&name=joe#f",
737 0, 0, CURLUE_OK},
738 {NULL, NULL, NULL, 0, 0, 0}
739 };
740
append(void)741 static int append(void)
742 {
743 int i;
744 CURLUcode rc;
745 CURLU *urlp;
746 int error = 0;
747 for(i = 0; append_list[i].in && !error; i++) {
748 urlp = curl_url();
749 if(!urlp) {
750 error++;
751 break;
752 }
753 rc = curl_url_set(urlp, CURLUPART_URL,
754 append_list[i].in,
755 append_list[i].urlflags);
756 if(rc)
757 error++;
758 else
759 rc = curl_url_set(urlp, CURLUPART_QUERY,
760 append_list[i].q,
761 append_list[i].qflags | CURLU_APPENDQUERY);
762 if(error)
763 ;
764 else if(rc != append_list[i].ucode) {
765 fprintf(stderr, "Append\nin: %s\nreturned %d (expected %d)\n",
766 append_list[i].in, (int)rc, append_list[i].ucode);
767 error++;
768 }
769 else if(append_list[i].ucode) {
770 /* the expected error happened */
771 }
772 else {
773 char *url;
774 rc = curl_url_get(urlp, CURLUPART_URL, &url, 0);
775 if(rc) {
776 fprintf(stderr, "%s:%d Get URL returned %d\n",
777 __FILE__, __LINE__, (int)rc);
778 error++;
779 }
780 else {
781 if(checkurl(url, append_list[i].out)) {
782 error++;
783 }
784 curl_free(url);
785 }
786 }
787 curl_url_cleanup(urlp);
788 }
789 return error;
790 }
791
test(char * URL)792 int test(char *URL)
793 {
794 (void)URL; /* not used */
795
796 if(append())
797 return 5;
798
799 if(set_url())
800 return 1;
801
802 if(set_parts())
803 return 2;
804
805 if(get_url())
806 return 3;
807
808 if(get_parts())
809 return 4;
810
811 printf("success\n");
812 return 0;
813 }
814