removed handles and states from the main structs
authorDaniel Stenberg <daniel@haxx.se>
Fri, 9 Mar 2001 15:18:25 +0000 (15:18 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 9 Mar 2001 15:18:25 +0000 (15:18 +0000)
renamed prefixes from curl_ to Curl_
made persistant connections work with http proxies (at least partly)

lib/url.c

index 9b53fbc..cb0bbe6 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -122,18 +122,7 @@ static unsigned int ConnectionStore(struct UrlData *data,
                                     struct connectdata *conn);
 
 
-/* does nothing, returns OK */
-CURLcode curl_init(void)
-{
-  return CURLE_OK;
-}
-
-/* does nothing */
-void curl_free(void)
-{
-}
-
-CURLcode curl_close(CURL *curl)
+CURLcode Curl_close(CURL *curl)
 {
   struct UrlData *data=(struct UrlData *)curl;
   
@@ -178,10 +167,6 @@ CURLcode curl_close(CURL *curl)
   free(data->connects);
 
   free(data);
-
-  /* global cleanup */
-  curl_free();
-
   return CURLE_OK;
 }
 
@@ -197,7 +182,7 @@ int my_getpass(void *clientp, char *prompt, char* buffer, int buflen )
 }
 
 
-CURLcode curl_open(CURL **curl, char *url)
+CURLcode Curl_open(CURL **curl, char *url)
 {
   /* We don't yet support specifying the URL at this point */
   struct UrlData *data;
@@ -206,8 +191,6 @@ CURLcode curl_open(CURL **curl, char *url)
   data = (struct UrlData *)malloc(sizeof(struct UrlData));
   if(data) {
     memset(data, 0, sizeof(struct UrlData));
-    data->handle = STRUCT_OPEN;
-    data->interf = CURLI_NORMAL; /* normal interface by default */
 
     /* We do some initial setup here, all those fields that can't be just 0 */
 
@@ -258,7 +241,7 @@ CURLcode curl_open(CURL **curl, char *url)
   return CURLE_OUT_OF_MEMORY;
 }
 
-CURLcode curl_setopt(CURL *curl, CURLoption option, ...)
+CURLcode Curl_setopt(CURL *curl, CURLoption option, ...)
 {
   struct UrlData *data = curl;
   va_list param;
@@ -510,10 +493,8 @@ RETSIGTYPE alarmfunc(int signal)
 }
 #endif
 
-CURLcode curl_disconnect(CURLconnect *c_connect)
+CURLcode Curl_disconnect(struct connectdata *conn)
 {
-  struct connectdata *conn = c_connect;
-
   if(conn->curl_disconnect)
     /* This is set if protocol-specific cleanups should be made */
     conn->curl_disconnect(conn);
@@ -570,6 +551,9 @@ CURLcode curl_disconnect(CURLconnect *c_connect)
   if(conn->allocptr.host)
     free(conn->allocptr.host);
 
+  if(conn->proxyhost)
+    free(conn->proxyhost);
+
   free(conn); /* free all the connection oriented data */
 
   return CURLE_OK;
@@ -623,24 +607,26 @@ ConnectionExists(struct UrlData *data,
     if(!check)
       /* NULL pointer means not filled-in entry */
       continue;
-    if(strequal(needle->protostr, check->protostr) &&
-       strequal(needle->name, check->name) &&
-       (needle->port == check->port) ) {
-      if(strequal(needle->protostr, "FTP")) {
-        /* This is FTP, verify that we're using the same name and
-           password as well */
-        if(!strequal(needle->data->user, check->proto.ftp->user) ||
-           !strequal(needle->data->passwd, check->proto.ftp->passwd)) {
-          /* one of them was different */
-          continue;
-        }
-      }
-      {
+    if(!needle->bits.httpproxy) {
+      /* The requested connection does not use a HTTP proxy */
+
+      if(strequal(needle->protostr, check->protostr) &&
+         strequal(needle->name, check->name) &&
+         (needle->port == check->port) ) {
         bool dead;
+        if(strequal(needle->protostr, "FTP")) {
+          /* This is FTP, verify that we're using the same name and
+             password as well */
+          if(!strequal(needle->data->user, check->proto.ftp->user) ||
+             !strequal(needle->data->passwd, check->proto.ftp->passwd)) {
+            /* one of them was different */
+            continue;
+          }
+        }
         dead = SocketIsDead(check->firstsocket);
         if(dead) {
           infof(data, "Connection %d seems to be dead!\n", i);
-          curl_disconnect(check); /* disconnect resources */
+          Curl_disconnect(check); /* disconnect resources */
           data->connects[i]=NULL; /* nothing here */
           continue; /* try another one now */
         }
@@ -648,6 +634,16 @@ ConnectionExists(struct UrlData *data,
       *usethis = check;
       return TRUE; /* yes, we found one to use! */
     }
+    else { /* The requested needle connection is using a proxy,
+              is the checked one using the same? */
+      if(check->bits.httpproxy &&
+         strequal(needle->proxyhost, check->proxyhost) &&
+         needle->port == check->port) {
+        /* This is the same proxy connection, use it! */
+        *usethis = check;
+        return TRUE;
+      }
+    }
   }
   return FALSE; /* no matching connecting exists */
 }
@@ -690,7 +686,7 @@ ConnectionKillOne(struct UrlData *data)
   if(connindex >= 0) {
 
     /* the winner gets the honour of being disconnected */
-    result = curl_disconnect(data->connects[connindex]);
+    result = Curl_disconnect(data->connects[connindex]);
 
     /* clean the array entry */
     data->connects[connindex] = NULL;
@@ -811,7 +807,7 @@ static CURLcode ConnectPlease(struct UrlData *data,
        
           size = sizeof(add);
           if(getsockname(conn->firstsocket, (struct sockaddr *) &add,
-                         (int *)&size)<0) {
+                         (socklen_t *)&size)<0) {
             failf(data, "getsockname() failed");
             return CURLE_HTTP_PORT_FAILED;
           }
@@ -945,15 +941,14 @@ static CURLcode ConnectPlease(struct UrlData *data,
   return CURLE_OK;
 }
 
-static CURLcode _connect(CURL *curl,
-                         CURLconnect **in_connect,
-                         bool allow_port) /* allow data->use_port ? */
+static CURLcode Connect(struct UrlData *data,
+                        struct connectdata **in_connect,
+                        bool allow_port) /* allow data->use_port ? */
 {
   char *tmp;
   char *buf;
   CURLcode result;
   char resumerange[40]="";
-  struct UrlData *data = curl;
   struct connectdata *conn;
   struct connectdata *conn_temp;
   char endbracket;
@@ -966,9 +961,6 @@ static CURLcode _connect(CURL *curl,
    * Check input data
    *************************************************************/
 
-  if(!data || (data->handle != STRUCT_OPEN))
-    return CURLE_BAD_FUNCTION_ARGUMENT; /* TBD: make error codes */
-
   if(!data->url)
     return CURLE_URL_MALFORMAT;
 
@@ -991,13 +983,12 @@ static CURLcode _connect(CURL *curl,
   memset(conn, 0, sizeof(struct connectdata));
 
   /* and we setup a few fields in case we end up actually using this struct */
-  conn->handle = STRUCT_CONNECT; /* this is a connection handle */
   conn->data = data;           /* remember our daddy */
-  conn->state = CONN_INIT;     /* init state */
   conn->upload_bufsize = UPLOAD_BUFSIZE; /* default upload buffer size */
   conn->firstsocket = -1;     /* no file descriptor */
   conn->secondarysocket = -1; /* no file descriptor */
   conn->connectindex = -1;    /* no index */
+  conn->bits.httpproxy = data->bits.httpproxy; /* proxy-or-not status */
 
   /* Default protocol-indepent behaveiour doesn't support persistant
      connections, so we set this to force-close. Protocols that support
@@ -1567,6 +1558,62 @@ static CURLcode _connect(CURL *curl,
     conn->remote_port = atoi(tmp);
   }
 
+  if(data->bits.httpproxy) {
+    /* If this is supposed to use a proxy, we need to figure out the proxy
+       host name name, so that we can re-use an existing connection
+       that may exist registered to the same proxy host. */
+
+#ifdef ENABLE_IPV6
+    failf(data, "proxy yet to be supported");
+    return CURLE_OUT_OF_MEMORY;
+#else
+    char *prox_portno;
+    char *endofprot;
+
+    /* We need to make a duplicate of the proxy so that we can modify the
+       string safely. */
+    char *proxydup=strdup(data->proxy);
+
+    /* We use 'proxyptr' to point to the proxy name from now on... */
+    char *proxyptr=proxydup;
+
+    if(NULL == proxydup) {
+      failf(data, "memory shortage");
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    /* Daniel Dec 10, 1998:
+       We do the proxy host string parsing here. We want the host name and the
+       port name. Accept a protocol:// prefix, even though it should just be
+       ignored. */
+
+    /* 1. skip the protocol part if present */
+    endofprot=strstr(proxyptr, "://");
+    if(endofprot) {
+      proxyptr = endofprot+3;
+    }
+
+    /* allow user to specify proxy.server.com:1080 if desired */
+    prox_portno = strchr (proxyptr, ':');
+    if (prox_portno) {
+      *prox_portno = 0x0; /* cut off number from host name */
+      prox_portno ++;
+      /* now set the local port number */
+      conn->port = atoi(prox_portno);
+    }
+    else if(data->proxyport) {
+      /* None given in the proxy string, then get the default one if it is
+         given */
+      conn->port = data->proxyport;
+    }
+
+    /* now, clone the cleaned proxy host name */
+    conn->proxyhost = strdup(proxyptr);
+
+    free(proxydup); /* free the duplicate pointer and not the modified */
+#endif /* end of IPv4-section */
+  }
+
   /*************************************************************
    * Check the current list of connections to see if we can
    * re-use an already existing one or if we have to create a
@@ -1581,6 +1628,8 @@ static CURLcode _connect(CURL *curl,
      * existing one.
      */
     char *path = conn->path; /* setup the current path pointer properly */
+    if(conn->proxyhost)
+      free(conn->proxyhost);
     free(conn);              /* we don't need this new one */
     conn = conn_temp;        /* use this connection from now on */
     free(conn->path);        /* free the previous path pointer */
@@ -1591,6 +1640,8 @@ static CURLcode _connect(CURL *curl,
     conn->maxdownload = 0;   /* might have been used previously! */
     conn->bits.reuse = TRUE; /* yes, we're re-using here */
 
+    *in_connect = conn;      /* return this instead! */
+
     infof(data, "Re-using existing connection! (#%d)\n", conn->connectindex);
   }
   else {
@@ -1628,59 +1679,13 @@ static CURLcode _connect(CURL *curl,
   else if(!conn->hp) {
     /* This is a proxy that hasn't been resolved yet. It may be resolved
        if we're reusing an existing connection. */
-#ifdef ENABLE_IPV6
-    failf(data, "proxy yet to be supported");
-    return CURLE_OUT_OF_MEMORY;
-#else
-    char *prox_portno;
-    char *endofprot;
-
-    /* We need to make a duplicate of the proxy so that we can modify the
-       string safely. */
-    char *proxydup=strdup(data->proxy);
-
-    /* We use 'proxyptr' to point to the proxy name from now on... */
-    char *proxyptr=proxydup;
-
-    if(NULL == proxydup) {
-      failf(data, "memory shortage");
-      return CURLE_OUT_OF_MEMORY;
-    }
-
-    /* Daniel Dec 10, 1998:
-       We do the proxy host string parsing here. We want the host name and the
-       port name. Accept a protocol:// prefix, even though it should just be
-       ignored. */
-
-    /* 1. skip the protocol part if present */
-    endofprot=strstr(proxyptr, "://");
-    if(endofprot) {
-      proxyptr = endofprot+3;
-    }
-
-    /* allow user to specify proxy.server.com:1080 if desired */
-    prox_portno = strchr (proxyptr, ':');
-    if (prox_portno) {
-      *prox_portno = 0x0; /* cut off number from host name */
-      prox_portno ++;
-      /* now set the local port number */
-      conn->port = atoi(prox_portno);
-    }
-    else if(data->proxyport) {
-      /* None given in the proxy string, then get the default one if it is
-         given */
-      conn->port = data->proxyport;
-    }
 
     /* resolve proxy */
-    conn->hp = Curl_gethost(data, proxyptr, &conn->hostent_buf);
+    conn->hp = Curl_gethost(data, conn->proxyhost, &conn->hostent_buf);
     if(!conn->hp) {
-      failf(data, "Couldn't resolve proxy '%s'", proxyptr);
+      failf(data, "Couldn't resolve proxy '%s'", conn->proxyhost);
       return CURLE_COULDNT_RESOLVE_PROXY;
     }
-
-    free(proxydup); /* free the duplicate pointer and not the modified */
-#endif
   }
   Curl_pgrsTime(data, TIMER_NAMELOOKUP);
 
@@ -1784,25 +1789,24 @@ static CURLcode _connect(CURL *curl,
   return CURLE_OK;
 }
 
-CURLcode curl_connect(CURL *curl, CURLconnect **in_connect,
+CURLcode Curl_connect(struct UrlData *data,
+                      struct connectdata **in_connect,
                       bool allow_port)
 {
   CURLcode code;
   struct connectdata *conn;
 
   /* call the stuff that needs to be called */
-  code = _connect(curl, in_connect, allow_port);
+  code = Connect(data, in_connect, allow_port);
 
   if(CURLE_OK != code) {
     /* We're not allowed to return failure with memory left allocated
        in the connectdata struct, free those here */
     conn = (struct connectdata *)*in_connect;
     if(conn) {
-      struct UrlData *data;
       int index;
-      data = conn->data;
       index = conn->connectindex; /* get the index */
-      curl_disconnect(conn);      /* close the connection */
+      Curl_disconnect(conn);      /* close the connection */
       data->connects[index]=NULL; /* clear the pointer */
     }
   }
@@ -1810,41 +1814,12 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect,
 }
 
 
-/*
- * NAME curl_connect()
- *
- * DESCRIPTION
- *
- * Connects to the peer server and performs the initial setup. This function
- * writes a connect handle to its second argument that is a unique handle for
- * this connect. This allows multiple connects from the same handle returned
- * by curl_open().
- *
- * EXAMPLE
- *
- * CURLCode result;
- * CURL curl;
- * CURLconnect connect;
- * result = curl_connect(curl, &connect);
- */
-
-
-
-
-CURLcode curl_done(CURLconnect *c_connect)
+CURLcode Curl_done(struct connectdata *conn)
 {
-  struct connectdata *conn = c_connect;
   struct UrlData *data;
   CURLcode result;
   int index;
 
-  if(!conn || (conn->handle!= STRUCT_CONNECT)) {
-    return CURLE_BAD_FUNCTION_ARGUMENT;
-  }
-  if(conn->state != CONN_DO) {
-    /* This can only be called after a curl_do() */
-    return CURLE_BAD_CALLING_ORDER;
-  }
   data = conn->data;
 
   /* this calls the protocol-specific function pointer previously set */
@@ -1855,48 +1830,25 @@ CURLcode curl_done(CURLconnect *c_connect)
 
   Curl_pgrsDone(data); /* done with the operation */
 
-  conn->state = CONN_DONE;
-
   /* if bits.close is TRUE, it means that the connection should be closed
      in spite of all our efforts to be nice */
   if((CURLE_OK == result) && conn->bits.close) {
     index = conn->connectindex;     /* get the index */
-    result = curl_disconnect(conn); /* close the connection */
+    result = Curl_disconnect(conn); /* close the connection */
     data->connects[index]=NULL;     /* clear the pointer */
   }
 
   return result;
 }
 
-CURLcode curl_do(CURLconnect *in_conn)
+CURLcode Curl_do(struct connectdata *conn)
 {
-  struct connectdata *conn = in_conn;
-  CURLcode result;
+  CURLcode result=CURLE_OK;
 
-  if(!conn || (conn->handle!= STRUCT_CONNECT)) {
-    return CURLE_BAD_FUNCTION_ARGUMENT;
-  }
-  switch(conn->state) {
-  case CONN_INIT:
-  case CONN_DONE:
-    /* these two states are OK */
-    break;
-  default:
-    /* anything else is bad */
-    return CURLE_BAD_CALLING_ORDER;
-  }
-
-  if(conn->curl_do) {
+  if(conn->curl_do)
     /* generic protocol-specific function pointer set in curl_connect() */
     result = conn->curl_do(conn);
-    if(result) {
-      conn->state = CONN_ERROR;
-      return result;
-    }
-  }
-
-  conn->state = CONN_DO; /* we have entered this state */
 
-  return CURLE_OK;
+  return result;
 }