aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/url.c270
1 files changed, 111 insertions, 159 deletions
diff --git a/lib/url.c b/lib/url.c
index 9b53fbc2f..cb0bbe60b 100644
--- 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;
}