aboutsummaryrefslogtreecommitdiff
path: root/lib/url.c
diff options
context:
space:
mode:
authorSteve Holme <steve_holme@hotmail.com>2013-04-13 10:49:42 +0100
committerSteve Holme <steve_holme@hotmail.com>2013-04-13 10:49:42 +0100
commit73aa95592f47d461f0246eef1187f5d569aa6afa (patch)
treedcf5efb83c021e87a2b4fb2b45259ef0100f0947 /lib/url.c
parentad3fdbc0a46e8cdb0ce19df17a278309c2cfb2cf (diff)
url: Added support for parsing login options from the URL
As well as parsing the username and password from the URL, added support for parsing the optional options part from the login details, to allow the following supported URL format: schema://username:password;options@example.com/path?q=foobar This will only be used by IMAP, POP3 and SMTP at present but any protocol that may be given login options in the URL will be able to add support for them.
Diffstat (limited to 'lib/url.c')
-rw-r--r--lib/url.c79
1 files changed, 59 insertions, 20 deletions
diff --git a/lib/url.c b/lib/url.c
index 4399162a9..20823d078 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -2452,6 +2452,7 @@ static void conn_free(struct connectdata *conn)
Curl_safefree(conn->user);
Curl_safefree(conn->passwd);
+ Curl_safefree(conn->options);
Curl_safefree(conn->proxyuser);
Curl_safefree(conn->proxypasswd);
Curl_safefree(conn->allocptr.proxyuserpwd);
@@ -4342,24 +4343,27 @@ static CURLcode parse_url_userpass(struct SessionHandle *data,
struct connectdata *conn,
char *user, char *passwd)
{
+ char options[MAX_CURL_OPTIONS_LENGTH];
+
/* At this point, we're hoping all the other special cases have
* been taken care of, so conn->host.name is at most
- * [user[:password]]@]hostname
+ * [user[:password][;options]]@]hostname
*
* We need somewhere to put the embedded details, so do that first.
*/
- char *ptr=strchr(conn->host.name, '@');
+ char *ptr = strchr(conn->host.name, '@');
char *userpass = conn->host.name;
- user[0] =0; /* to make everything well-defined */
- passwd[0]=0;
+ user[0] = 0; /* to make everything well-defined */
+ passwd[0] = 0;
+ options[0] = 0;
/* We will now try to extract the
- * possible user+password pair in a string like:
+ * possible login information in a string like:
* ftp://user:password@ftp.my.site:8021/README */
if(ptr != NULL) {
- /* there's a user+password given here, to the left of the @ */
+ /* There's login information to the left of the @ */
conn->host.name = ++ptr;
@@ -4369,26 +4373,46 @@ static CURLcode parse_url_userpass(struct SessionHandle *data,
* set user/passwd, but doing that first adds more cases here :-(
*/
- conn->bits.userpwd_in_url = TRUE;
if(data->set.use_netrc != CURL_NETRC_REQUIRED) {
- /* We could use the one in the URL */
-
- conn->bits.user_passwd = TRUE; /* enable user+password */
-
+ /* We could use the information in the URL so extract it */
if(*userpass != ':') {
- /* the name is given, get user+password */
- sscanf(userpass, "%" MAX_CURL_USER_LENGTH_TXT "[^:@]:"
- "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]",
- user, passwd);
+ if(*userpass != ';') {
+ /* The user is given so extract the user, password and options */
+ int result = sscanf(userpass,
+ "%" MAX_CURL_USER_LENGTH_TXT "[^:;@]:"
+ "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^;@];"
+ "%" MAX_CURL_OPTIONS_LENGTH_TXT "[^@]",
+ user, passwd, options);
+
+ /* The extract failed so extract the user and options instead */
+ if(result == 1)
+ sscanf(userpass, "%" MAX_CURL_USER_LENGTH_TXT "[^:;@];"
+ "%" MAX_CURL_OPTIONS_LENGTH_TXT "[^@]",
+ user, options);
+ }
+ else {
+ /* No name or password are given so extract the options only */
+ sscanf(userpass, ";%" MAX_CURL_OPTIONS_LENGTH_TXT "[^@]", options);
+ }
}
else
- /* no name given, get the password only */
- sscanf(userpass, ":%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", passwd);
+ /* No name is given so extract the password and options */
+ sscanf(userpass, ":%" MAX_CURL_PASSWORD_LENGTH_TXT "[^;@];"
+ "%" MAX_CURL_OPTIONS_LENGTH_TXT "[^@]",
+ passwd, options);
if(user[0]) {
- char *newname=curl_easy_unescape(data, user, 0, NULL);
+ char *newname;
+
+ /* We have a user in the URL */
+ conn->bits.userpwd_in_url = TRUE;
+ conn->bits.user_passwd = TRUE; /* enable user+password */
+
+ /* Decode the user */
+ newname = curl_easy_unescape(data, user, 0, NULL);
if(!newname)
return CURLE_OUT_OF_MEMORY;
+
if(strlen(newname) < MAX_CURL_USER_LENGTH)
strcpy(user, newname);
@@ -4396,18 +4420,33 @@ static CURLcode parse_url_userpass(struct SessionHandle *data,
the unconverted name, it'll be wrong but what the heck */
free(newname);
}
+
if(passwd[0]) {
- /* we have a password found in the URL, decode it! */
- char *newpasswd=curl_easy_unescape(data, passwd, 0, NULL);
+ /* We have a password in the URL so decode it */
+ char *newpasswd = curl_easy_unescape(data, passwd, 0, NULL);
if(!newpasswd)
return CURLE_OUT_OF_MEMORY;
+
if(strlen(newpasswd) < MAX_CURL_PASSWORD_LENGTH)
strcpy(passwd, newpasswd);
free(newpasswd);
}
+
+ if(options[0]) {
+ /* We have an options list in the URL so decode it */
+ char *newoptions = curl_easy_unescape(data, options, 0, NULL);
+ if(!newoptions)
+ return CURLE_OUT_OF_MEMORY;
+
+ if(strlen(newoptions) < MAX_CURL_OPTIONS_LENGTH)
+ conn->options = newoptions;
+ else
+ free(newoptions);
+ }
}
}
+
return CURLE_OK;
}