lib1560.c 33 KB

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