1--- 2c: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 3SPDX-License-Identifier: curl 4Title: curl_url_set 5Section: 3 6Source: libcurl 7See-also: 8 - CURLOPT_CURLU (3) 9 - curl_url (3) 10 - curl_url_cleanup (3) 11 - curl_url_dup (3) 12 - curl_url_get (3) 13 - curl_url_strerror (3) 14Protocol: 15 - All 16--- 17 18# NAME 19 20curl_url_set - set a URL part 21 22# SYNOPSIS 23 24~~~c 25#include <curl/curl.h> 26 27CURLUcode curl_url_set(CURLU *url, 28 CURLUPart part, 29 const char *content, 30 unsigned int flags); 31~~~ 32 33# DESCRIPTION 34 35The *url* handle to work on, passed in as the first argument, must be a 36handle previously created by curl_url(3) or curl_url_dup(3). 37 38This function sets or updates individual URL components, or parts, held by the 39URL object the handle identifies. 40 41The *part* argument should identify the particular URL part (see list below) 42to set or change, with *content* pointing to a null-terminated string with the 43new contents for that URL part. The contents should be in the form and 44encoding they would use in a URL: URL encoded. 45 46When setting a part in the URL object that was previously already set, it 47replaces the data that was previously stored for that part with the new 48*content*. 49 50The caller does not have to keep *content* around after a successful call 51as this function copies the content. 52 53Setting a part to a NULL pointer removes that part's contents from the *CURLU* 54handle. 55 56This function has an 8 MB maximum length limit for all provided input strings. 57In the real world, excessively long fields in URLs cause problems even if this 58function accepts them. 59 60When setting or updating contents of individual URL parts, curl_url_set(3) 61might accept data that would not be otherwise possible to set in the string 62when it gets populated as a result of a full URL parse. Beware. If done so, 63extracting a full URL later on from such components might render an invalid 64URL. 65 66The *flags* argument is a bitmask with independent features. 67 68# PARTS 69 70## CURLUPART_URL 71 72Allows the full URL of the handle to be replaced. If the handle already is 73populated with a URL, the new URL can be relative to the previous. 74 75When successfully setting a new URL, relative or absolute, the handle contents 76is replaced with the components of the newly set URL. 77 78Pass a pointer to a null-terminated string to the *url* parameter. The 79string must point to a correctly formatted "RFC 3986+" URL or be a NULL 80pointer. 81 82By default, this API only accepts setting URLs using schemes for protocols 83that are supported built-in. To make libcurl parse URLs generically even for 84schemes it does not know about, the **CURLU_NON_SUPPORT_SCHEME** flags bit 85must be set. Otherwise, this function returns *CURLUE_UNSUPPORTED_SCHEME* for 86URL schemes it does not recognize. 87 88Unless *CURLU_NO_AUTHORITY* is set, a blank hostname is not allowed in 89the URL. 90 91## CURLUPART_SCHEME 92 93Scheme cannot be URL decoded on set. libcurl only accepts setting schemes up 94to 40 bytes long. 95 96## CURLUPART_USER 97 98If only the user part is set and not the password, the URL is represented with 99a blank password. 100 101## CURLUPART_PASSWORD 102 103If only the password part is set and not the user, the URL is represented with 104a blank user. 105 106## CURLUPART_OPTIONS 107 108The options field is an optional field that might follow the password in the 109userinfo part. It is only recognized/used when parsing URLs for the following 110schemes: pop3, smtp and imap. This function however allows users to 111independently set this field. 112 113## CURLUPART_HOST 114 115The hostname. If it is International Domain Name (IDN) the string must then be 116encoded as your locale says or UTF-8 (when WinIDN is used). If it is a 117bracketed IPv6 numeric address it may contain a zone id (or you can use 118*CURLUPART_ZONEID*). 119 120Note that if you set an IPv6 address, it gets ruined and causes an error if 121you also set the CURLU_URLENCODE flag. 122 123Unless *CURLU_NO_AUTHORITY* is set, a blank hostname is not allowed to set. 124 125## CURLUPART_ZONEID 126 127If the hostname is a numeric IPv6 address, this field can also be set. 128 129## CURLUPART_PORT 130 131The port number cannot be URL encoded on set. The given port number is 132provided as a string and the decimal number in it must be between 0 and 13365535. Anything else returns an error. 134 135## CURLUPART_PATH 136 137If a path is set in the URL without a leading slash, a slash is prepended 138automatically. 139 140## CURLUPART_QUERY 141 142The query part gets spaces converted to pluses when asked to URL encode on set 143with the *CURLU_URLENCODE* bit. 144 145If used together with the *CURLU_APPENDQUERY* bit, the provided part is 146appended on the end of the existing query. 147 148The question mark in the URL is not part of the actual query contents. 149 150## CURLUPART_FRAGMENT 151 152The hash sign in the URL is not part of the actual fragment contents. 153 154# FLAGS 155 156The flags argument is zero, one or more bits set in a bitmask. 157 158## CURLU_APPENDQUERY 159 160Can be used when setting the *CURLUPART_QUERY* component. The provided new 161part is then appended at the end of the existing query - and if the previous 162part did not end with an ampersand (&), an ampersand gets inserted before the 163new appended part. 164 165When *CURLU_APPENDQUERY* is used together with *CURLU_URLENCODE*, the 166first '=' symbol is not URL encoded. 167 168## CURLU_NON_SUPPORT_SCHEME 169 170If set, allows curl_url_set(3) to set a non-supported scheme. 171 172## CURLU_URLENCODE 173 174When set, curl_url_set(3) URL encodes the part on entry, except for 175**scheme**, **port** and **URL**. 176 177When setting the path component with URL encoding enabled, the slash character 178is skipped. 179 180The query part gets space-to-plus converted before the URL conversion is 181applied. 182 183This URL encoding is charset unaware and converts the input in a byte-by-byte 184manner. 185 186## CURLU_DEFAULT_SCHEME 187 188If set, allows the URL to be set without a scheme and then sets that to the 189default scheme: HTTPS. Overrides the *CURLU_GUESS_SCHEME* option if both 190are set. 191 192## CURLU_GUESS_SCHEME 193 194If set, allows the URL to be set without a scheme and it instead "guesses" 195which scheme that was intended based on the hostname. If the outermost 196subdomain name matches DICT, FTP, IMAP, LDAP, POP3 or SMTP then that scheme is 197used, otherwise it picks HTTP. Conflicts with the *CURLU_DEFAULT_SCHEME* 198option which takes precedence if both are set. 199 200## CURLU_NO_AUTHORITY 201 202If set, skips authority checks. The RFC allows individual schemes to omit the 203host part (normally the only mandatory part of the authority), but libcurl 204cannot know whether this is permitted for custom schemes. Specifying the flag 205permits empty authority sections, similar to how file scheme is handled. 206 207## CURLU_PATH_AS_IS 208 209When set for **CURLUPART_URL**, this skips the normalization of the 210path. That is the procedure where libcurl otherwise removes sequences of 211dot-slash and dot-dot etc. The same option used for transfers is called 212CURLOPT_PATH_AS_IS(3). 213 214## CURLU_ALLOW_SPACE 215 216If set, the URL parser allows space (ASCII 32) where possible. The URL syntax 217does normally not allow spaces anywhere, but they should be encoded as %20 218or '+'. When spaces are allowed, they are still not allowed in the scheme. 219When space is used and allowed in a URL, it is stored as-is unless 220*CURLU_URLENCODE* is also set, which then makes libcurl URL encode the 221space before stored. This affects how the URL is constructed when 222curl_url_get(3) is subsequently used to extract the full URL or 223individual parts. (Added in 7.78.0) 224 225## CURLU_DISALLOW_USER 226 227If set, the URL parser does not accept embedded credentials for the 228**CURLUPART_URL**, and instead returns **CURLUE_USER_NOT_ALLOWED** for 229such URLs. 230 231# EXAMPLE 232 233~~~c 234int main(void) 235{ 236 CURLUcode rc; 237 CURLU *url = curl_url(); 238 rc = curl_url_set(url, CURLUPART_URL, "https://example.com", 0); 239 if(!rc) { 240 /* change it to an FTP URL */ 241 rc = curl_url_set(url, CURLUPART_SCHEME, "ftp", 0); 242 } 243 curl_url_cleanup(url); 244} 245~~~ 246 247# AVAILABILITY 248 249Added in 7.62.0. CURLUPART_ZONEID was added in 7.65.0. 250 251# RETURN VALUE 252 253Returns a *CURLUcode* error value, which is CURLUE_OK (0) if everything 254went fine. See the libcurl-errors(3) man page for the full list with 255descriptions. 256 257The input string passed to curl_url_set(3) must be shorter than eight 258million bytes. Otherwise this function returns **CURLUE_MALFORMED_INPUT**. 259 260If this function returns an error, no URL part is set. 261