Add Music Manager's curl 7.21.2 source.

Change-Id: I259a43fa52d581524a5ce8ae1711467acb1d9d50
diff --git a/lib/url.c b/lib/url.c
index 357f213..1b65a92 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -137,6 +137,8 @@
 #include "http_ntlm.h"
 #include "socks.h"
 #include "rtsp.h"
+#include "curl_rtmp.h"
+#include "gopher.h"
 
 #define _MPRINTF_REPLACE /* use our functions only */
 #include <curl/mprintf.h>
@@ -150,11 +152,6 @@
 static void conn_free(struct connectdata *conn);
 static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke);
 
-#ifdef CURL_DISABLE_VERBOSE_STRINGS
-#define verboseconnect(x)  do { } while (0)
-#endif
-
-
 /*
  * Protocol table.
  */
@@ -187,11 +184,11 @@
 
 #ifndef CURL_DISABLE_LDAP
   &Curl_handler_ldap,
-#endif
-
-#if !defined(CURL_DISABLE_LDAP) && defined(HAVE_LDAP_SSL)
+#if (defined(USE_OPENLDAP) && defined(USE_SSL)) || \
+   (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL))
   &Curl_handler_ldaps,
 #endif
+#endif
 
 #ifndef CURL_DISABLE_FILE
   &Curl_handler_file,
@@ -231,6 +228,19 @@
   &Curl_handler_rtsp,
 #endif
 
+#ifndef CURL_DISABLE_GOPHER
+  &Curl_handler_gopher,
+#endif
+
+#ifdef USE_LIBRTMP
+  &Curl_handler_rtmp,
+  &Curl_handler_rtmpt,
+  &Curl_handler_rtmpe,
+  &Curl_handler_rtmpte,
+  &Curl_handler_rtmps,
+  &Curl_handler_rtmpts,
+#endif
+
   (struct Curl_handler *) NULL
 };
 
@@ -471,10 +481,20 @@
   }
 #endif
 
+  Curl_expire(data, 0); /* shut off timers */
+
   if(m)
     /* This handle is still part of a multi handle, take care of this first
        and detach this handle from there. */
-    Curl_multi_rmeasy(data->multi, data);
+    curl_multi_remove_handle(data->multi, data);
+
+  /* Destroy the timeout list that is held in the easy handle. It is
+     /normally/ done by curl_multi_remove_handle() but this is "just in
+     case" */
+  if(data->state.timeoutlist) {
+    Curl_llist_destroy(data->state.timeoutlist, NULL);
+    data->state.timeoutlist = NULL;
+  }
 
   data->magic = 0; /* force a clear AFTER the possibly enforced removal from
                       the multi handle, since that function uses the magic
@@ -690,6 +710,8 @@
 
   /* use fread as default function to read input */
   set->fread_func = (curl_read_callback)fread;
+  set->is_fread_set = 0;
+  set->is_fwrite_set = 0;
 
   set->seek_func = ZERO_NULL;
   set->seek_client = ZERO_NULL;
@@ -763,6 +785,10 @@
   res = setstropt(&set->str[STRING_SSL_CAPATH], (char *) CURL_CA_PATH);
 #endif
 
+  set->wildcardmatch  = FALSE;
+  set->chunk_bgn      = ZERO_NULL;
+  set->chunk_end      = ZERO_NULL;
+
   return res;
 }
 
@@ -831,6 +857,9 @@
     data->progress.flags |= PGRS_HIDE;
     data->state.current_speed = -1; /* init to negative == impossible */
 
+    data->wildcard.state = CURLWC_INIT;
+    data->wildcard.filelist = NULL;
+    data->set.fnmatch = ZERO_NULL;
     /* This no longer creates a connection cache here. It is instead made on
        the first call to curl_easy_perform() or when the handle is added to a
        multi stack. */
@@ -1390,19 +1419,6 @@
     data->set.httpversion = va_arg(param, long);
     break;
 
-  case CURLOPT_CUSTOMREQUEST:
-    /*
-     * Set a custom string to use as request
-     */
-    result = setstropt(&data->set.str[STRING_CUSTOMREQUEST],
-                       va_arg(param, char *));
-
-    /* we don't set
-       data->set.httpreq = HTTPREQ_CUSTOM;
-       here, we continue as if we were using the already set type
-       and this just changes the actual request keyword */
-    break;
-
   case CURLOPT_HTTPAUTH:
     /*
      * Set HTTP Authentication type BITMASK.
@@ -1434,6 +1450,21 @@
   }
   break;
 
+#endif   /* CURL_DISABLE_HTTP */
+
+  case CURLOPT_CUSTOMREQUEST:
+    /*
+     * Set a custom string to use as request
+     */
+    result = setstropt(&data->set.str[STRING_CUSTOMREQUEST],
+                       va_arg(param, char *));
+
+    /* we don't set
+       data->set.httpreq = HTTPREQ_CUSTOM;
+       here, we continue as if we were using the already set type
+       and this just changes the actual request keyword */
+    break;
+
 #ifndef CURL_DISABLE_PROXY
   case CURLOPT_HTTPPROXYTUNNEL:
     /*
@@ -1478,7 +1509,6 @@
     data->set.proxyauth = auth;
   }
   break;
-#endif   /* CURL_DISABLE_HTTP */
 
   case CURLOPT_PROXY:
     /*
@@ -1518,7 +1548,7 @@
       break;
     }
     break;
-#endif
+#endif   /* CURL_DISABLE_PROXY */
 
 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
   case CURLOPT_SOCKS5_GSSAPI_SERVICE:
@@ -1825,18 +1855,26 @@
      * Set data write callback
      */
     data->set.fwrite_func = va_arg(param, curl_write_callback);
-    if(!data->set.fwrite_func)
+    if(!data->set.fwrite_func) {
+      data->set.is_fwrite_set = 0;
       /* When set to NULL, reset to our internal default function */
       data->set.fwrite_func = (curl_write_callback)fwrite;
+    }
+    else
+      data->set.is_fwrite_set = 1;
     break;
   case CURLOPT_READFUNCTION:
     /*
      * Read data callback
      */
     data->set.fread_func = va_arg(param, curl_read_callback);
-    if(!data->set.fread_func)
+    if(!data->set.fread_func) {
+      data->set.is_fread_set = 0;
       /* When set to NULL, reset to our internal default function */
       data->set.fread_func = (curl_read_callback)fread;
+    }
+    else
+      data->set.is_fread_set = 1;
     break;
   case CURLOPT_SEEKFUNCTION:
     /*
@@ -2440,6 +2478,25 @@
     /* Set the user defined RTP write function */
     data->set.fwrite_rtp = va_arg(param, curl_write_callback);
     break;
+
+  case CURLOPT_WILDCARDMATCH:
+    data->set.wildcardmatch = (bool)(0 != va_arg(param, long));
+    break;
+  case CURLOPT_CHUNK_BGN_FUNCTION:
+    data->set.chunk_bgn = va_arg(param, curl_chunk_bgn_callback);
+    break;
+  case CURLOPT_CHUNK_END_FUNCTION:
+    data->set.chunk_end = va_arg(param, curl_chunk_end_callback);
+    break;
+  case CURLOPT_FNMATCH_FUNCTION:
+    data->set.fnmatch = va_arg(param, curl_fnmatch_callback);
+    break;
+  case CURLOPT_CHUNK_DATA:
+    data->wildcard.customptr = va_arg(param, void *);
+    break;
+  case CURLOPT_FNMATCH_DATA:
+    data->set.fnmatch_data = va_arg(param, void *);
+    break;
   default:
     /* unknown tag and its companion, just ignore: */
     result = CURLE_FAILED_INIT; /* correct this */
@@ -2524,7 +2581,6 @@
                   NULL, Curl_scan_cache_used);
 #endif
 
-  Curl_expire(data, 0); /* shut off timers */
   Curl_hostcache_prune(data); /* kill old DNS cache entries */
 
   {
@@ -2643,11 +2699,10 @@
   }
   else if (sval & CURL_CSELECT_IN) {
     /* readable with no error. could be closed or could be alive */
-    long connectinfo = 0;
-    Curl_getconnectinfo(check->data, &connectinfo, &check);
-    if(connectinfo != -1) {
+    curl_socket_t connectinfo =
+      Curl_getconnectinfo(check->data, &check);
+    if(connectinfo != CURL_SOCKET_BAD)
       ret_val = FALSE;
-    }
   }
 
   return ret_val;
@@ -3085,7 +3140,7 @@
 /* after a TCP connection to the proxy has been verified, this function does
    the next magic step.
 
-   Note: this function (and its sub-functions) calls failf()
+   Note: this function's sub-functions call failf()
 
 */
 CURLcode Curl_connected_proxy(struct connectdata *conn)
@@ -3093,12 +3148,6 @@
   CURLcode result = CURLE_OK;
   struct SessionHandle *data = conn->data;
 
-  if(conn->bits.tcpconnect)
-    /* allow this to get called again from the multi interface when TCP is
-       found connected in the state machine, even though it has already been
-       called if the connection happened "instantly" */
-    return CURLE_OK;
-
   switch(data->set.proxytype) {
 #ifndef CURL_DISABLE_PROXY
   case CURLPROXY_SOCKS5:
@@ -3169,11 +3218,12 @@
  * verboseconnect() displays verbose information after a connect
  */
 #ifndef CURL_DISABLE_VERBOSE_STRINGS
-static void verboseconnect(struct connectdata *conn)
+void Curl_verboseconnect(struct connectdata *conn)
 {
-  infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n",
-        conn->bits.proxy ? conn->proxy.dispname : conn->host.dispname,
-        conn->ip_addr_str, conn->port, conn->connectindex);
+  if(conn->data->set.verbose)
+    infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n",
+          conn->bits.proxy ? conn->proxy.dispname : conn->host.dispname,
+          conn->ip_addr_str, conn->port, conn->connectindex);
 }
 #endif
 
@@ -3264,9 +3314,7 @@
   if(!conn->bits.tcpconnect) {
 
     Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
-
-    if(data->set.verbose)
-      verboseconnect(conn);
+    Curl_verboseconnect(conn);
   }
 
   if(!conn->bits.protoconnstart) {
@@ -4133,7 +4181,7 @@
      * set user/passwd, but doing that first adds more cases here :-(
      */
 
-    conn->bits.userpwd_in_url = 1;
+    conn->bits.userpwd_in_url = TRUE;
     if(data->set.use_netrc != CURL_NETRC_REQUIRED) {
       /* We could use the one in the URL */
 
@@ -4224,18 +4272,23 @@
     if(conn->bits.httpproxy) {
       /* we need to create new URL with the new port number */
       char *url;
-      /* FTPS connections have the FTP bit set too, so they match as well */
-      bool isftp = (bool)(0 != (conn->protocol & PROT_FTP));
+      char type[12]="";
+
+      if(conn->bits.type_set)
+        snprintf(type, sizeof(type), ";type=%c",
+                 data->set.prefer_ascii?'A':
+                 (data->set.ftp_list_only?'D':'I'));
 
       /*
-       * This synthesized URL isn't always right--suffixes like ;type=A
-       * are stripped off. It would be better to work directly from the
-       * original URL and simply replace the port part of it.
+       * This synthesized URL isn't always right--suffixes like ;type=A are
+       * stripped off. It would be better to work directly from the original
+       * URL and simply replace the port part of it.
        */
-      url = aprintf("%s://%s%s%s:%hu%s%s", conn->handler->scheme,
+      url = aprintf("%s://%s%s%s:%hu%s%s%s", conn->handler->scheme,
                     conn->bits.ipv6_ip?"[":"", conn->host.name,
                     conn->bits.ipv6_ip?"]":"", conn->remote_port,
-                    isftp?"/":"", data->state.path);
+                    data->state.slash_removed?"/":"", data->state.path,
+                    type);
       if(!url)
         return CURLE_OUT_OF_MEMORY;
 
@@ -4267,6 +4320,11 @@
       *portptr = '\0'; /* cut off the name there */
       conn->remote_port = curlx_ultous(port);
     }
+    else if(!port)
+      /* Browser behavior adaptation. If there's a colon with no digits after,
+         just cut off the name there which makes us ignore the colon and just
+         use the default port. Firefox and Chrome both do that. */
+      *portptr = '\0';
   }
   return CURLE_OK;
 }
@@ -4347,30 +4405,7 @@
                                bool *async)
 {
   CURLcode result=CURLE_OK;
-  long shortest = 0; /* default to no timeout */
-
-  /*************************************************************
-   * Set timeout if that is being used
-   *************************************************************/
-  if(data->set.timeout || data->set.connecttimeout) {
-
-    /* We set the timeout on the name resolving phase first, separately from
-     * the download/upload part to allow a maximum time on everything. This is
-     * a signal-based timeout, why it won't work and shouldn't be used in
-     * multi-threaded environments. */
-
-    shortest = data->set.timeout; /* default to this timeout value */
-    if(shortest && data->set.connecttimeout &&
-       (data->set.connecttimeout < shortest))
-      /* if both are set, pick the shortest */
-      shortest = data->set.connecttimeout;
-    else if(!shortest)
-      /* if timeout is not set, use the connect timeout */
-      shortest = data->set.connecttimeout;
-  /* We can expect the conn->created time to be "now", as that was just
-     recently set in the beginning of this function and nothing slow
-     has been done since then until now. */
-  }
+  long timeout_ms = Curl_timeleft(conn, NULL, TRUE);
 
   /*************************************************************
    * Resolve the name of the server or proxy
@@ -4397,7 +4432,7 @@
 
       /* Resolve target host right on */
       rc = Curl_resolv_timeout(conn, conn->host.name, (int)conn->port,
-                               &hostaddr, shortest);
+                               &hostaddr, timeout_ms);
       if(rc == CURLRESOLV_PENDING)
         *async = TRUE;
 
@@ -4418,7 +4453,7 @@
 
       /* resolve proxy */
       rc = Curl_resolv_timeout(conn, conn->proxy.name, (int)conn->port,
-                               &hostaddr, shortest);
+                               &hostaddr, timeout_ms);
 
       if(rc == CURLRESOLV_PENDING)
         *async = TRUE;
@@ -4707,7 +4742,7 @@
     proxy = NULL;
   }
   /* proxy must be freed later unless NULL */
-  if(proxy && *proxy) {
+  if(proxy) {
     long bits = conn->protocol & (PROT_HTTPS|PROT_SSL);
 
     if((conn->proxytype == CURLPROXY_HTTP) ||
@@ -4750,6 +4785,11 @@
     return result;
   }
 
+  conn->recv[FIRSTSOCKET] = Curl_recv_plain;
+  conn->send[FIRSTSOCKET] = Curl_send_plain;
+  conn->recv[SECONDARYSOCKET] = Curl_recv_plain;
+  conn->send[SECONDARYSOCKET] = Curl_send_plain;
+
   /***********************************************************************
    * file: is a special case in that it doesn't need a network connection
    ***********************************************************************/
@@ -4779,9 +4819,8 @@
         return result;
       }
 
-      result = Curl_setup_transfer(conn, -1, -1, FALSE,
-                                   NULL, /* no download */
-                                   -1, NULL); /* no upload */
+      Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
+                          -1, NULL); /* no upload */
     }
 
     return result;
@@ -4986,8 +5025,8 @@
       Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */
       conn->bits.tcpconnect = TRUE;
       *protocol_done = TRUE;
-      if(data->set.verbose)
-        verboseconnect(conn);
+      Curl_verboseconnect(conn);
+      Curl_updateconninfo(conn, conn->sock[FIRSTSOCKET]);
     }
     /* Stop the loop now */
     break;
@@ -5093,8 +5132,6 @@
   conn = *connp;
   data = conn->data;
 
-  Curl_expire(data, 0); /* stop timer */
-
   if(conn->bits.done)
     /* Stop if Curl_done() has already been called */
     return CURLE_OK;
@@ -5248,10 +5285,8 @@
 static void do_complete(struct connectdata *conn)
 {
   conn->data->req.chunk=FALSE;
-  conn->data->req.trailerhdrpresent=FALSE;
-
   conn->data->req.maxfd = (conn->sockfd>conn->writesockfd?
-                               conn->sockfd:conn->writesockfd)+1;
+                           conn->sockfd:conn->writesockfd)+1;
 }
 
 CURLcode Curl_do(struct connectdata **connp, bool *done)