Newer
Older
free(proxydup); /* free the duplicate pointer and not the modified */
}
/*************************************************************
* Check the current list of connections to see if we can
* re-use an already existing one or if we have to create a
* new one.
*************************************************************/
/* reuse_fresh is set TRUE if we are told to use a fresh connection
by force */
if(!data->bits.reuse_fresh &&
ConnectionExists(data, conn, &conn_temp)) {
/*
* We already have a connection for this, we got the former connection
* in the conn_temp variable and thus we need to cleanup the one we
* just allocated before we can move along and use the previously
* existing one.
*/
Daniel Stenberg
committed
struct connectdata *old_conn = conn;
char *path = old_conn->path; /* setup the current path pointer properly */
if(old_conn->proxyhost)
free(old_conn->proxyhost);
conn = conn_temp; /* use this connection from now on */
Daniel Stenberg
committed
/* we need these pointers if we speak over a proxy */
conn->name = conn->gname;
conn->hostname = old_conn->gname;
Daniel Stenberg
committed
conn->path = path; /* use this one */
/* The 'ppath' may have been advanced a few steps from the 'path' start
point. We must also advance our new pointer as many steps as the
previous one was! This was the cause of the multiple ftp file bug
found on May 9 2001 libcurl 7.7.3 */
conn->ppath = (old_conn->ppath - old_conn->path)+path;
free(old_conn->path); /* free the previous path pointer */
/* re-use init */
conn->bits.reuse = TRUE; /* yes, we're re-using here */
conn->bits.chunk = FALSE; /* always assume not chunked unless told otherwise */
conn->maxdownload = -1; /* might have been used previously! */
Daniel Stenberg
committed
free(old_conn); /* we don't need this anymore */
*in_connect = conn; /* return this instead! */
infof(data, "Re-using existing connection! (#%d)\n", conn->connectindex);
}
else {
/*
* This is a brand new connection, so let's store it in the connection
* cache of ours!
*/
ConnectionStore(data, conn);
}
/*************************************************************
* Resolve the name of the server or proxy
*************************************************************/
/* If not connecting via a proxy, extract the port from the URL, if it is
* there, thus overriding any defaults that might have been set above. */
conn->port = conn->remote_port; /* it is the same port */
/* Resolve target host right on */
/* it might already be set if reusing a connection */
conn->hp = Curl_getaddrinfo(data, conn->name, conn->port);
/* it might already be set if reusing a connection */
conn->hp = Curl_gethost(data, conn->name, &conn->hostent_buf);
failf(data, "Couldn't resolve host '%s'", conn->name);
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
/* it might already be set if reusing a connection */
conn->hp = Curl_getaddrinfo(data, conn->proxyhost, conn->port);
#else
conn->hp = Curl_gethost(data, conn->proxyhost, &conn->hostent_buf);
failf(data, "Couldn't resolve proxy '%s'", conn->proxyhost);
return CURLE_COULDNT_RESOLVE_PROXY;
Curl_pgrsTime(data, TIMER_NAMELOOKUP);
/*************************************************************
* Proxy authentication
*************************************************************/
Daniel Stenberg
committed
if(conn->bits.proxy_user_passwd) {
snprintf(data->buffer, BUFSIZE, "%s:%s",
data->proxyuser, data->proxypasswd);
if(Curl_base64_encode(data->buffer, strlen(data->buffer),
&authorization) >= 0) {
if(conn->allocptr.proxyuserpwd)
free(conn->allocptr.proxyuserpwd);
conn->allocptr.proxyuserpwd =
aprintf("Proxy-authorization: Basic %s\015\012", authorization);
/*************************************************************
* Send user-agent to HTTP proxies even if the target protocol
* isn't HTTP.
*************************************************************/
if((conn->protocol&PROT_HTTP) || data->bits.httpproxy) {
if(conn->allocptr.uagent)
free(conn->allocptr.uagent);
conn->allocptr.uagent =
aprintf("User-Agent: %s\015\012", data->useragent);
if(-1 == conn->firstsocket) {
/* Connect only if not already connected! */
result = ConnectPlease(data, conn);
if(CURLE_OK != result)
return result;
if(conn->curl_connect) {
/* is there a connect() procedure? */
/* set start time here for timeout purposes in the
* connect procedure, it is later set again for the
* progress meter purpose */
conn->now = Curl_tvnow();
/* Call the protocol-specific connect function */
result = conn->curl_connect(conn);
if(result != CURLE_OK)
return result; /* pass back errors */
}
Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected */
conn->now = Curl_tvnow(); /* time this *after* the connect is done */
/* Figure out the ip-number and display the first host name it shows: */
#ifdef ENABLE_IPV6
{
char hbuf[NI_MAXHOST];
#ifdef NI_WITHSCOPEID
const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
#else
const int niflags = NI_NUMERICHOST;
#endif
if (getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0,
niflags)) {
snprintf(hbuf, sizeof(hbuf), "?");
}
if (ai->ai_canonname) {
infof(data, "Connected to %s (%s)\n", ai->ai_canonname, hbuf);
} else {
infof(data, "Connected to %s\n", hbuf);
}
}
#else
(void) memcpy(&in.s_addr, *conn->hp->h_addr_list, sizeof (in.s_addr));
infof(data, "Connected to %s (%s)\n", conn->hp->h_name, inet_ntoa(in));
#ifdef __EMX__
/* 20000330 mgs
* the check is quite a hack...
* we're calling _fsetmode to fix the problem with fwrite converting newline
* characters (you get mangled text files, and corrupted binary files when
* you download to stdout and redirect it to a file). */
if ((data->out)->_handle == NULL) {
_fsetmode(stdout, "b");
}
#endif
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(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;
Daniel Stenberg
committed
if(conn) {
Curl_disconnect(conn); /* close the connection */
Daniel Stenberg
committed
*in_connect = NULL; /* return a NULL */
}
CURLcode Curl_done(struct connectdata *conn)
Daniel Stenberg
committed
struct UrlData *data=conn->data;
/* cleanups done even if the connection is re-used */
if(conn->bits.rangestringalloc) {
free(conn->range);
conn->bits.rangestringalloc = FALSE;
}
/* this calls the protocol-specific function pointer previously set */
if(conn->curl_done)
result = conn->curl_done(conn);
else
result = CURLE_OK;
Curl_pgrsDone(conn); /* done with the operation */
/* if data->bits.reuse_forbid is TRUE, it means the libcurl client has
forced us to close this no matter what we think.
if conn->bits.close is TRUE, it means that the connection should be
closed in spite of all our efforts to be nice, due to protocol
restrictions in our or the server's end */
if(data->bits.reuse_forbid ||
((CURLE_OK == result) && conn->bits.close))
result = Curl_disconnect(conn); /* close the connection */
else
infof(data, "Connection (#%d) left alive\n", conn->connectindex);
CURLcode Curl_do(struct connectdata *conn)
CURLcode result=CURLE_OK;
/* generic protocol-specific function pointer set in curl_connect() */
result = conn->curl_do(conn);