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 | |
37 | struct part { |
38 | CURLUPart part; |
39 | const char *name; |
40 | }; |
41 | |
42 | |
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 | 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 | |
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; /* for the main URL set */ |
103 | CURLUcode pcode; /* for updating parts */ |
104 | }; |
105 | |
106 | struct testcase { |
107 | const char *in; |
108 | const char *out; |
109 | unsigned int urlflags; |
110 | unsigned int getflags; |
111 | CURLUcode ucode; |
112 | }; |
113 | |
114 | struct 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 | |
122 | struct 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 | |
131 | static 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 | |
354 | static 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 | |
514 | static 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 */ |
525 | static 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 | |
669 | static 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 | |
696 | static 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 | |
740 | static 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 | |
772 | static 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 | |
819 | static 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 | |
869 | static 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 | |
908 | static 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 | |
938 | static 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 | |
956 | static 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 | |
1006 | static 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 | |
1132 | int 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 | |