mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
Karl M added the CURLOPT_CONNECT_ONLY and CURLINFO_LASTSOCKET options that
an app can use to let libcurl only connect to a remote host and then extract the socket from libcurl. libcurl will then not attempt to do any transfer at all after the connect is done.
This commit is contained in:
parent
b0bc2f00d2
commit
87bcb6f377
5
CHANGES
5
CHANGES
@ -7,6 +7,11 @@
|
|||||||
Changelog
|
Changelog
|
||||||
|
|
||||||
Daniel (11 February 2006)
|
Daniel (11 February 2006)
|
||||||
|
- Karl M added the CURLOPT_CONNECT_ONLY and CURLINFO_LASTSOCKET options that
|
||||||
|
an app can use to let libcurl only connect to a remote host and then extract
|
||||||
|
the socket from libcurl. libcurl will then not attempt to do any transfer at
|
||||||
|
all after the connect is done.
|
||||||
|
|
||||||
- Kent Boortz improved the configure check for GnuTLS to properly set LIBS
|
- Kent Boortz improved the configure check for GnuTLS to properly set LIBS
|
||||||
instead of LDFLAGS.
|
instead of LDFLAGS.
|
||||||
|
|
||||||
|
@ -2,21 +2,22 @@ Curl and libcurl 7.15.2
|
|||||||
|
|
||||||
Public curl release number: 92
|
Public curl release number: 92
|
||||||
Releases counted from the very beginning: 119
|
Releases counted from the very beginning: 119
|
||||||
Available command line options: 109
|
Available command line options: 111
|
||||||
Available curl_easy_setopt() options: 125
|
Available curl_easy_setopt() options: 129
|
||||||
Number of public functions in libcurl: 46
|
Number of public functions in libcurl: 46
|
||||||
Amount of public web site mirrors: 30
|
Amount of public web site mirrors: 31
|
||||||
Number of known libcurl bindings: 32
|
Number of known libcurl bindings: 32
|
||||||
Number of contributors: 474
|
Number of contributors: 474
|
||||||
|
|
||||||
This release includes the following changes:
|
This release includes the following changes:
|
||||||
|
|
||||||
|
o CURLOPT_CONNECT_ONLY and CURLINFO_LASTSOCKET added
|
||||||
o CURLOPT_LOCALPORT and CURLOPT_LOCALPORTRANGE (--local-port) added
|
o CURLOPT_LOCALPORT and CURLOPT_LOCALPORTRANGE (--local-port) added
|
||||||
o Dropped support for the LPRT ftp command
|
o Dropped support for the LPRT ftp command
|
||||||
o Gopher is now officially abandoned as a protocol (lib)curl tries to support.
|
o Gopher is now officially abandoned as a protocol (lib)curl tries to support
|
||||||
o curl_global_init() and curl_global_cleanup() are now using a refcount so
|
o curl_global_init() and curl_global_cleanup() are now using a refcount so
|
||||||
that it is now legal to call them multiple times. See updated info for
|
that it is now legal to call them multiple times. See updated info for
|
||||||
details.
|
details
|
||||||
|
|
||||||
This release includes the following bugfixes:
|
This release includes the following bugfixes:
|
||||||
|
|
||||||
@ -60,7 +61,7 @@ advice from friends like these:
|
|||||||
|
|
||||||
Dov Murik, Jean Jacques Drouin, Andres Garcia, Yang Tse, Gisle Vanem, Dan
|
Dov Murik, Jean Jacques Drouin, Andres Garcia, Yang Tse, Gisle Vanem, Dan
|
||||||
Fandrich, Alexander Lazic, Michael Jahn, Andrew Benham, Bryan Henderson,
|
Fandrich, Alexander Lazic, Michael Jahn, Andrew Benham, Bryan Henderson,
|
||||||
David Shaw, Jon Turner, Duane Cathey, Michal Marek, Philippe Vaucher,
|
David Shaw, Jon Turner, Duane Cathey, Michal Marek, Philippe Vaucher, Kent
|
||||||
Kent Boortz
|
Boortz, Karl M
|
||||||
|
|
||||||
Thanks! (and sorry if I forgot to mention someone)
|
Thanks! (and sorry if I forgot to mention someone)
|
||||||
|
@ -141,6 +141,12 @@ cookies cURL knows (expired ones, too). Don't forget to
|
|||||||
cookies (cookies for the handle have not been enabled or simply none have been
|
cookies (cookies for the handle have not been enabled or simply none have been
|
||||||
received) 'struct curl_slist *' will be set to point to NULL. (Added in
|
received) 'struct curl_slist *' will be set to point to NULL. (Added in
|
||||||
7.14.1)
|
7.14.1)
|
||||||
|
.IP CURLINFO_LASTSOCKET
|
||||||
|
Pass a pointer to a long to receive the last socket used by this curl
|
||||||
|
session. If the socket is no longer valid, -1 is returned. When you finish
|
||||||
|
working with the socket, you must call curl_easy_cleanup() as usual and let
|
||||||
|
libcurl close the socket and cleanup other resources associated with the
|
||||||
|
handle. (Added in 7.15.2)
|
||||||
.SH TIMES
|
.SH TIMES
|
||||||
.NF
|
.NF
|
||||||
An overview of the six time values available from curl_easy_getinfo()
|
An overview of the six time values available from curl_easy_getinfo()
|
||||||
|
@ -1044,6 +1044,14 @@ Resolve to ipv4 addresses.
|
|||||||
.IP CURL_IPRESOLVE_V6
|
.IP CURL_IPRESOLVE_V6
|
||||||
Resolve to ipv6 addresses.
|
Resolve to ipv6 addresses.
|
||||||
.RE
|
.RE
|
||||||
|
.SH CURLOPT_CONNECT_ONLY
|
||||||
|
Pass a long. A non-zero parameter tells the library to perform any required
|
||||||
|
proxy authentication and connection setup, but no data transfer.
|
||||||
|
|
||||||
|
This option is useful with the \fICURLINFO_LASTSOCKET\fP option to
|
||||||
|
\fIcurl_easy_getinfo(3)\fP. The library can set up the connection and then the
|
||||||
|
application can obtain the most recently used socket for special data
|
||||||
|
transfers. (Added in 7.15.2)
|
||||||
.SH SSL and SECURITY OPTIONS
|
.SH SSL and SECURITY OPTIONS
|
||||||
.IP CURLOPT_SSLCERT
|
.IP CURLOPT_SSLCERT
|
||||||
Pass a pointer to a zero terminated string as parameter. The string should be
|
Pass a pointer to a zero terminated string as parameter. The string should be
|
||||||
|
@ -923,6 +923,10 @@ typedef enum {
|
|||||||
*/
|
*/
|
||||||
CINIT(LOCALPORTRANGE, LONG, 140),
|
CINIT(LOCALPORTRANGE, LONG, 140),
|
||||||
|
|
||||||
|
/* no transfer, set up connection and let application use the socket by
|
||||||
|
extracting it with CURLINFO_LASTSOCKET */
|
||||||
|
CINIT(CONNECT_ONLY, LONG, 141),
|
||||||
|
|
||||||
CURLOPT_LASTENTRY /* the last unused */
|
CURLOPT_LASTENTRY /* the last unused */
|
||||||
} CURLoption;
|
} CURLoption;
|
||||||
|
|
||||||
@ -1277,9 +1281,10 @@ typedef enum {
|
|||||||
CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26,
|
CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26,
|
||||||
CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27,
|
CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27,
|
||||||
CURLINFO_COOKIELIST = CURLINFO_SLIST + 28,
|
CURLINFO_COOKIELIST = CURLINFO_SLIST + 28,
|
||||||
|
CURLINFO_LASTSOCKET = CURLINFO_LONG + 29,
|
||||||
/* Fill in new entries below here! */
|
/* Fill in new entries below here! */
|
||||||
|
|
||||||
CURLINFO_LASTONE = 28
|
CURLINFO_LASTONE = 29
|
||||||
} CURLINFO;
|
} CURLINFO;
|
||||||
|
|
||||||
/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
|
/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
|
||||||
|
@ -527,6 +527,8 @@ CURL *curl_easy_duphandle(CURL *incurl)
|
|||||||
memset(outcurl->state.connects, 0,
|
memset(outcurl->state.connects, 0,
|
||||||
sizeof(struct connectdata *)*outcurl->state.numconnects);
|
sizeof(struct connectdata *)*outcurl->state.numconnects);
|
||||||
|
|
||||||
|
outcurl->state.lastconnect = -1;
|
||||||
|
|
||||||
outcurl->progress.flags = data->progress.flags;
|
outcurl->progress.flags = data->progress.flags;
|
||||||
outcurl->progress.callback = data->progress.callback;
|
outcurl->progress.callback = data->progress.callback;
|
||||||
|
|
||||||
|
@ -1689,7 +1689,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
|||||||
ftp_pasv_verbose(conn, conninfo, newhost, connectport);
|
ftp_pasv_verbose(conn, conninfo, newhost, connectport);
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_HTTP
|
#ifndef CURL_DISABLE_HTTP
|
||||||
if(conn->bits.tunnel_proxy) {
|
if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
|
||||||
/* FIX: this MUST wait for a proper connect first if 'connected' is
|
/* FIX: this MUST wait for a proper connect first if 'connected' is
|
||||||
* FALSE */
|
* FALSE */
|
||||||
|
|
||||||
@ -2786,7 +2786,7 @@ CURLcode Curl_ftp_connect(struct connectdata *conn,
|
|||||||
ftp->response_time = 3600; /* set default response time-out */
|
ftp->response_time = 3600; /* set default response time-out */
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_HTTP
|
#ifndef CURL_DISABLE_HTTP
|
||||||
if (conn->bits.tunnel_proxy) {
|
if (conn->bits.tunnel_proxy && conn->bits.httpproxy) {
|
||||||
/* BLOCKING */
|
/* BLOCKING */
|
||||||
/* We want "seamless" FTP operations through HTTP proxy tunnel */
|
/* We want "seamless" FTP operations through HTTP proxy tunnel */
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@ -187,6 +187,14 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
|
|||||||
case CURLINFO_COOKIELIST:
|
case CURLINFO_COOKIELIST:
|
||||||
*param_slistp = Curl_cookie_list(data);
|
*param_slistp = Curl_cookie_list(data);
|
||||||
break;
|
break;
|
||||||
|
case CURLINFO_LASTSOCKET:
|
||||||
|
if((data->state.lastconnect != -1) &&
|
||||||
|
(data->state.connects[data->state.lastconnect] != NULL))
|
||||||
|
*param_longp = data->state.connects[data->state.lastconnect]->
|
||||||
|
sock[FIRSTSOCKET];
|
||||||
|
else
|
||||||
|
*param_longp = -1;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
@ -1361,7 +1361,7 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
|
|||||||
* after the connect has occured, can we start talking SSL
|
* after the connect has occured, can we start talking SSL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if(conn->bits.tunnel_proxy) {
|
if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
|
||||||
|
|
||||||
/* either SSL over proxy, or explicitly asked for */
|
/* either SSL over proxy, or explicitly asked for */
|
||||||
result = Curl_proxyCONNECT(conn, FIRSTSOCKET,
|
result = Curl_proxyCONNECT(conn, FIRSTSOCKET,
|
||||||
|
75
lib/multi.c
75
lib/multi.c
@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@ -522,40 +522,49 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CURLM_STATE_DO:
|
case CURLM_STATE_DO:
|
||||||
/* Perform the protocol's DO action */
|
if(easy->easy_handle->set.connect_only) {
|
||||||
easy->result = Curl_do(&easy->easy_conn, &dophase_done);
|
/* keep connection open for application to use the socket */
|
||||||
|
easy->easy_conn->bits.close = FALSE;
|
||||||
if(CURLE_OK == easy->result) {
|
multistate(easy, CURLM_STATE_DONE);
|
||||||
|
easy->result = CURLE_OK;
|
||||||
if(!dophase_done) {
|
result = CURLM_OK;
|
||||||
/* DO was not completed in one function call, we must continue
|
|
||||||
DOING... */
|
|
||||||
multistate(easy, CURLM_STATE_DOING);
|
|
||||||
result = CURLM_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* after DO, go PERFORM... or DO_MORE */
|
|
||||||
else if(easy->easy_conn->bits.do_more) {
|
|
||||||
/* we're supposed to do more, but we need to sit down, relax
|
|
||||||
and wait a little while first */
|
|
||||||
multistate(easy, CURLM_STATE_DO_MORE);
|
|
||||||
result = CURLM_OK;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* we're done with the DO, now PERFORM */
|
|
||||||
easy->result = Curl_readwrite_init(easy->easy_conn);
|
|
||||||
if(CURLE_OK == easy->result) {
|
|
||||||
multistate(easy, CURLM_STATE_PERFORM);
|
|
||||||
result = CURLM_CALL_MULTI_PERFORM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* failure detected */
|
/* Perform the protocol's DO action */
|
||||||
Curl_posttransfer(easy->easy_handle);
|
easy->result = Curl_do(&easy->easy_conn, &dophase_done);
|
||||||
Curl_done(&easy->easy_conn, easy->result);
|
|
||||||
Curl_disconnect(easy->easy_conn); /* close the connection */
|
if(CURLE_OK == easy->result) {
|
||||||
easy->easy_conn = NULL; /* no more connection */
|
|
||||||
|
if(!dophase_done) {
|
||||||
|
/* DO was not completed in one function call, we must continue
|
||||||
|
DOING... */
|
||||||
|
multistate(easy, CURLM_STATE_DOING);
|
||||||
|
result = CURLM_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* after DO, go PERFORM... or DO_MORE */
|
||||||
|
else if(easy->easy_conn->bits.do_more) {
|
||||||
|
/* we're supposed to do more, but we need to sit down, relax
|
||||||
|
and wait a little while first */
|
||||||
|
multistate(easy, CURLM_STATE_DO_MORE);
|
||||||
|
result = CURLM_OK;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* we're done with the DO, now PERFORM */
|
||||||
|
easy->result = Curl_readwrite_init(easy->easy_conn);
|
||||||
|
if(CURLE_OK == easy->result) {
|
||||||
|
multistate(easy, CURLM_STATE_PERFORM);
|
||||||
|
result = CURLM_CALL_MULTI_PERFORM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* failure detected */
|
||||||
|
Curl_posttransfer(easy->easy_handle);
|
||||||
|
Curl_done(&easy->easy_conn, easy->result);
|
||||||
|
Curl_disconnect(easy->easy_conn); /* close the connection */
|
||||||
|
easy->easy_conn = NULL; /* no more connection */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2159,6 +2159,12 @@ CURLcode Curl_perform(struct SessionHandle *data)
|
|||||||
|
|
||||||
if(res == CURLE_OK) {
|
if(res == CURLE_OK) {
|
||||||
bool do_done;
|
bool do_done;
|
||||||
|
if(data->set.connect_only) {
|
||||||
|
/* keep connection open for application to use the socket */
|
||||||
|
conn->bits.close = FALSE;
|
||||||
|
res = Curl_done(&conn, CURLE_OK);
|
||||||
|
break;
|
||||||
|
}
|
||||||
res = Curl_do(&conn, &do_done);
|
res = Curl_do(&conn, &do_done);
|
||||||
|
|
||||||
/* for non 3rd party transfer only */
|
/* for non 3rd party transfer only */
|
||||||
|
25
lib/url.c
25
lib/url.c
@ -352,6 +352,9 @@ CURLcode Curl_open(struct SessionHandle **curl)
|
|||||||
memset(data->state.connects, 0,
|
memset(data->state.connects, 0,
|
||||||
sizeof(struct connectdata *)*data->state.numconnects);
|
sizeof(struct connectdata *)*data->state.numconnects);
|
||||||
|
|
||||||
|
/* most recent connection is not yet defined */
|
||||||
|
data->state.lastconnect = -1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* libcurl 7.10 introduced SSL verification *by default*! This needs to be
|
* libcurl 7.10 introduced SSL verification *by default*! This needs to be
|
||||||
* switched off unless wanted.
|
* switched off unless wanted.
|
||||||
@ -432,6 +435,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
|||||||
are being removed! */
|
are being removed! */
|
||||||
for(i=newconnects; i< data->state.numconnects; i++)
|
for(i=newconnects; i< data->state.numconnects; i++)
|
||||||
Curl_disconnect(data->state.connects[i]);
|
Curl_disconnect(data->state.connects[i]);
|
||||||
|
|
||||||
|
/* If the most recent connection is no longer valid, mark it invalid. */
|
||||||
|
if(data->state.lastconnect <= newconnects)
|
||||||
|
data->state.lastconnect = -1;
|
||||||
}
|
}
|
||||||
if(newconnects) {
|
if(newconnects) {
|
||||||
newptr= (struct connectdata **)
|
newptr= (struct connectdata **)
|
||||||
@ -453,8 +460,9 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
|||||||
/* zero makes NO cache at all */
|
/* zero makes NO cache at all */
|
||||||
if(data->state.connects)
|
if(data->state.connects)
|
||||||
free(data->state.connects);
|
free(data->state.connects);
|
||||||
data->state.connects=NULL;
|
data->state.connects = NULL;
|
||||||
data->state.numconnects=0;
|
data->state.numconnects = 0;
|
||||||
|
data->state.lastconnect = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1471,6 +1479,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
|||||||
data->set.ignorecl = va_arg(param, long)?TRUE:FALSE;
|
data->set.ignorecl = va_arg(param, long)?TRUE:FALSE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CURLOPT_CONNECT_ONLY:
|
||||||
|
/*
|
||||||
|
* No data transfer, set up connection and let application use the socket
|
||||||
|
*/
|
||||||
|
data->set.connect_only = va_arg(param, long)?TRUE:FALSE;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* unknown tag and its companion, just ignore: */
|
/* unknown tag and its companion, just ignore: */
|
||||||
result = CURLE_FAILED_INIT; /* correct this */
|
result = CURLE_FAILED_INIT; /* correct this */
|
||||||
@ -3811,10 +3826,14 @@ CURLcode Curl_done(struct connectdata **connp,
|
|||||||
if(!result && res2)
|
if(!result && res2)
|
||||||
result = res2;
|
result = res2;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
|
/* remember the most recently used connection */
|
||||||
|
data->state.lastconnect = conn->connectindex;
|
||||||
|
|
||||||
infof(data, "Connection #%ld to host %s left intact\n",
|
infof(data, "Connection #%ld to host %s left intact\n",
|
||||||
conn->connectindex,
|
conn->connectindex,
|
||||||
conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
|
conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -856,6 +856,7 @@ struct UrlState {
|
|||||||
set, it holds an allocated connection. */
|
set, it holds an allocated connection. */
|
||||||
struct connectdata **connects;
|
struct connectdata **connects;
|
||||||
long numconnects; /* size of the 'connects' array */
|
long numconnects; /* size of the 'connects' array */
|
||||||
|
int lastconnect; /* index of most recent connect or -1 if undefined */
|
||||||
|
|
||||||
char *headerbuff; /* allocated buffer to store headers in */
|
char *headerbuff; /* allocated buffer to store headers in */
|
||||||
size_t headersize; /* size of the allocation */
|
size_t headersize; /* size of the allocation */
|
||||||
@ -1083,6 +1084,7 @@ struct UserDefined {
|
|||||||
bool ignorecl; /* ignore content length */
|
bool ignorecl; /* ignore content length */
|
||||||
bool ftp_skip_ip; /* skip the IP address the FTP server passes on to
|
bool ftp_skip_ip; /* skip the IP address the FTP server passes on to
|
||||||
us */
|
us */
|
||||||
|
bool connect_only; /* make connection, let application use the socket */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user