xref: /curl/docs/libcurl/libcurl-url.md (revision e3fe0200)
1---
2c: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
3SPDX-License-Identifier: curl
4Title: libcurl
5Section: 3
6Source: libcurl
7See-also:
8  - CURLOPT_URL (3)
9  - curl_url (3)
10  - curl_url_cleanup (3)
11  - curl_url_dup (3)
12  - curl_url_get (3)
13  - curl_url_set (3)
14  - curl_url_strerror (3)
15Protocol:
16  - All
17---
18
19# NAME
20
21libcurl-url - URL interface overview
22
23# DESCRIPTION
24
25The URL interface provides functions for parsing and generating URLs.
26
27# INCLUDE
28
29You still only include \<curl/curl.h\> in your code.
30
31# CREATE
32
33Create a handle that holds URL info and resources with curl_url(3):
34~~~c
35  CURLU *h = curl_url();
36~~~
37
38# CLEANUP
39
40When done with it, clean it up with curl_url_cleanup(3)
41~~~c
42  curl_url_cleanup(h);
43~~~
44
45# DUPLICATE
46
47When you need a copy of a handle, just duplicate it with curl_url_dup(3):
48~~~c
49  CURLU *nh = curl_url_dup(h);
50~~~
51
52# PARSING
53
54By setting a URL to the handle with curl_url_set(3), the URL is parsed
55and stored in the handle. If the URL is not syntactically correct it returns
56an error instead.
57~~~c
58  rc = curl_url_set(h, CURLUPART_URL,
59                    "https://example.com:449/foo/bar?name=moo", 0);
60~~~
61
62The zero in the fourth argument is a bitmask for changing specific features.
63
64If successful, this stores the URL in its individual parts within the handle.
65
66# REDIRECT
67
68When a handle already contains info about a URL, setting a relative URL makes
69it "redirect" to that.
70~~~c
71  rc = curl_url_set(h, CURLUPART_URL, "../test?another", 0);
72~~~
73
74# GET URL
75
76The **CURLU** handle represents a URL and you can easily extract that with
77curl_url_get(3):
78~~~c
79  char *url;
80  rc = curl_url_get(h, CURLUPART_URL, &url, 0);
81  curl_free(url);
82~~~
83The zero in the fourth argument is a bitmask for changing specific features.
84
85# GET PARTS
86
87When a URL has been parsed or parts have been set, you can extract those
88pieces from the handle at any time.
89
90~~~c
91  rc = curl_url_get(h, CURLUPART_FRAGMENT, &fragment, 0);
92  rc = curl_url_get(h, CURLUPART_HOST, &host, 0);
93  rc = curl_url_get(h, CURLUPART_PASSWORD, &password, 0);
94  rc = curl_url_get(h, CURLUPART_PATH, &path, 0);
95  rc = curl_url_get(h, CURLUPART_PORT, &port, 0);
96  rc = curl_url_get(h, CURLUPART_QUERY, &query, 0);
97  rc = curl_url_get(h, CURLUPART_SCHEME, &scheme, 0);
98  rc = curl_url_get(h, CURLUPART_USER, &user, 0);
99  rc = curl_url_get(h, CURLUPART_ZONEID, &zoneid, 0);
100~~~
101
102Extracted parts are not URL decoded unless the user also asks for it with the
103*CURLU_URLDECODE* flag set in the fourth bitmask argument.
104
105Remember to free the returned string with curl_free(3) when you are done
106with it!
107
108# SET PARTS
109
110A user set individual URL parts, either after having parsed a full URL or
111instead of parsing such.
112
113~~~c
114  rc = curl_url_set(urlp, CURLUPART_FRAGMENT, "anchor", 0);
115  rc = curl_url_set(urlp, CURLUPART_HOST, "www.example.com", 0);
116  rc = curl_url_set(urlp, CURLUPART_PASSWORD, "doe", 0);
117  rc = curl_url_set(urlp, CURLUPART_PATH, "/index.html", 0);
118  rc = curl_url_set(urlp, CURLUPART_PORT, "443", 0);
119  rc = curl_url_set(urlp, CURLUPART_QUERY, "name=john", 0);
120  rc = curl_url_set(urlp, CURLUPART_SCHEME, "https", 0);
121  rc = curl_url_set(urlp, CURLUPART_USER, "john", 0);
122  rc = curl_url_set(urlp, CURLUPART_ZONEID, "eth0", 0);
123~~~
124
125Set parts are not URL encoded unless the user asks for it with the
126*CURLU_URLENCODE* flag.
127
128# CURLU_APPENDQUERY
129
130An application can append a string to the right end of the query part with the
131*CURLU_APPENDQUERY* flag to curl_url_set(3).
132
133Imagine a handle that holds the URL "https://example.com/?shoes=2". An
134application can then add the string "hat=1" to the query part like this:
135
136~~~c
137  rc = curl_url_set(urlp, CURLUPART_QUERY, "hat=1", CURLU_APPENDQUERY);
138~~~
139
140It notices the lack of an ampersand (&) separator and injects one, and the
141handle's full URL then equals "https://example.com/?shoes=2&hat=1".
142
143The appended string can of course also get URL encoded on add, and if asked to
144URL encode, the encoding process skips the '=' character. For example, append
145"candy=N&N" to what we already have, and URL encode it to deal with the
146ampersand in the data:
147
148~~~c
149  rc = curl_url_set(urlp, CURLUPART_QUERY, "candy=N&N",
150                    CURLU_APPENDQUERY | CURLU_URLENCODE);
151~~~
152
153Now the URL looks like
154
155~~~c
156  https://example.com/?shoes=2&hat=1&candy=N%26N
157~~~
158
159# AVAILABILITY
160
161The URL API was introduced in libcurl 7.62.0.
162
163A URL with a literal IPv6 address can be parsed even when IPv6 support is not
164enabled.
165