mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 15:48:49 -05:00
urldata: clean up the use of the protocol specific structs
1 - always allocate the struct in protocol->setup_connection. Some protocol handlers had to get this function added. 2 - always free at the end of a request. This is also an attempt to keep less memory in the handle after it is completed.
This commit is contained in:
parent
e3ee73b70c
commit
4ad8e142da
@ -602,9 +602,8 @@ void Curl_easy_addmulti(struct SessionHandle *data,
|
||||
|
||||
void Curl_easy_initHandleData(struct SessionHandle *data)
|
||||
{
|
||||
memset(&data->req, 0, sizeof(struct SingleRequest));
|
||||
|
||||
data->req.maxdownload = -1;
|
||||
memset(&data->req, 0, sizeof(struct SingleRequest));
|
||||
data->req.maxdownload = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
29
lib/file.c
29
lib/file.c
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -186,31 +186,16 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
|
||||
char *actual_path;
|
||||
#endif
|
||||
|
||||
/* If there already is a protocol-specific struct allocated for this
|
||||
sessionhandle, deal with it */
|
||||
Curl_reset_reqproto(conn);
|
||||
|
||||
real_path = curl_easy_unescape(data, data->state.path, 0, NULL);
|
||||
if(!real_path)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
if(!data->state.proto.file) {
|
||||
file = calloc(1, sizeof(struct FILEPROTO));
|
||||
if(!file) {
|
||||
free(real_path);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
data->state.proto.file = file;
|
||||
}
|
||||
else {
|
||||
/* file is not a protocol that can deal with "persistancy" */
|
||||
file = data->state.proto.file;
|
||||
Curl_safefree(file->freepath);
|
||||
file->path = NULL;
|
||||
if(file->fd != -1)
|
||||
close(file->fd);
|
||||
file->fd = -1;
|
||||
file = calloc(1, sizeof(struct FILEPROTO));
|
||||
if(!file) {
|
||||
free(real_path);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
data->state.proto.file = file;
|
||||
|
||||
#ifdef DOS_FILESYSTEM
|
||||
/* If the first character is a slash, and there's
|
||||
@ -450,7 +435,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
||||
return file_upload(conn);
|
||||
|
||||
/* get the fd from the connection phase */
|
||||
fd = conn->data->state.proto.file->fd;
|
||||
fd = data->state.proto.file->fd;
|
||||
|
||||
/* VMS: This only works reliable for STREAMLF files */
|
||||
if(-1 != fstat(fd, &statbuf)) {
|
||||
|
108
lib/ftp.c
108
lib/ftp.c
@ -225,7 +225,7 @@ const struct Curl_handler Curl_handler_ftps = {
|
||||
|
||||
static const struct Curl_handler Curl_handler_ftp_proxy = {
|
||||
"FTP", /* scheme */
|
||||
ZERO_NULL, /* setup_connection */
|
||||
Curl_http_setup_conn, /* setup_connection */
|
||||
Curl_http, /* do_it */
|
||||
Curl_http_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
@ -251,7 +251,7 @@ static const struct Curl_handler Curl_handler_ftp_proxy = {
|
||||
|
||||
static const struct Curl_handler Curl_handler_ftps_proxy = {
|
||||
"FTPS", /* scheme */
|
||||
ZERO_NULL, /* setup_connection */
|
||||
Curl_http_setup_conn, /* setup_connection */
|
||||
Curl_http, /* do_it */
|
||||
Curl_http_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
@ -3158,56 +3158,6 @@ static CURLcode ftp_block_statemach(struct connectdata *conn)
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate and initialize the struct FTP for the current SessionHandle. If
|
||||
* need be.
|
||||
*/
|
||||
|
||||
#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
|
||||
defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
|
||||
/* workaround icc 9.1 optimizer issue */
|
||||
#pragma optimize("", off)
|
||||
#endif
|
||||
|
||||
static CURLcode ftp_init(struct connectdata *conn)
|
||||
{
|
||||
struct FTP *ftp;
|
||||
|
||||
if(NULL == conn->data->state.proto.ftp) {
|
||||
conn->data->state.proto.ftp = malloc(sizeof(struct FTP));
|
||||
if(NULL == conn->data->state.proto.ftp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
ftp = conn->data->state.proto.ftp;
|
||||
|
||||
/* get some initial data into the ftp struct */
|
||||
ftp->bytecountp = &conn->data->req.bytecount;
|
||||
ftp->transfer = FTPTRANSFER_BODY;
|
||||
ftp->downloadsize = 0;
|
||||
|
||||
/* No need to duplicate user+password, the connectdata struct won't change
|
||||
during a session, but we re-init them here since on subsequent inits
|
||||
since the conn struct may have changed or been replaced.
|
||||
*/
|
||||
ftp->user = conn->user;
|
||||
ftp->passwd = conn->passwd;
|
||||
if(isBadFtpString(ftp->user))
|
||||
return CURLE_URL_MALFORMAT;
|
||||
if(isBadFtpString(ftp->passwd))
|
||||
return CURLE_URL_MALFORMAT;
|
||||
|
||||
conn->proto.ftpc.known_filesize = -1; /* unknown size for now */
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
|
||||
defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
|
||||
/* workaround icc 9.1 optimizer issue */
|
||||
#pragma optimize("", on)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ftp_connect() should do everything that is to be considered a part of
|
||||
* the connection phase.
|
||||
@ -3225,14 +3175,6 @@ static CURLcode ftp_connect(struct connectdata *conn,
|
||||
|
||||
*done = FALSE; /* default to not done yet */
|
||||
|
||||
/* If there already is a protocol-specific struct allocated for this
|
||||
sessionhandle, deal with it */
|
||||
Curl_reset_reqproto(conn);
|
||||
|
||||
result = ftp_init(conn);
|
||||
if(CURLE_OK != result)
|
||||
return result;
|
||||
|
||||
/* We always support persistent connections on ftp */
|
||||
conn->bits.close = FALSE;
|
||||
|
||||
@ -4099,17 +4041,6 @@ static CURLcode ftp_do(struct connectdata *conn, bool *done)
|
||||
*done = FALSE; /* default to false */
|
||||
ftpc->wait_data_conn = FALSE; /* default to no such wait */
|
||||
|
||||
/*
|
||||
Since connections can be re-used between SessionHandles, this might be a
|
||||
connection already existing but on a fresh SessionHandle struct so we must
|
||||
make sure we have a good 'struct FTP' to play with. For new connections,
|
||||
the struct FTP is allocated and setup in the ftp_connect() function.
|
||||
*/
|
||||
Curl_reset_reqproto(conn);
|
||||
retcode = ftp_init(conn);
|
||||
if(retcode)
|
||||
return retcode;
|
||||
|
||||
if(conn->data->set.wildcardmatch) {
|
||||
retcode = wc_statemach(conn);
|
||||
if(conn->data->wildcard.state == CURLWC_SKIP ||
|
||||
@ -4572,11 +4503,12 @@ CURLcode ftp_regular_transfer(struct connectdata *conn,
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode ftp_setup_connection(struct connectdata * conn)
|
||||
static CURLcode ftp_setup_connection(struct connectdata *conn)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
char * type;
|
||||
char *type;
|
||||
char command;
|
||||
struct FTP *ftp;
|
||||
|
||||
if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) {
|
||||
/* Unless we have asked to tunnel ftp operations through the proxy, we
|
||||
@ -4592,18 +4524,18 @@ static CURLcode ftp_setup_connection(struct connectdata * conn)
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* We explicitly mark this connection as persistent here as we're doing
|
||||
* FTP over HTTP and thus we accidentally avoid setting this value
|
||||
* otherwise.
|
||||
*/
|
||||
conn->bits.close = FALSE;
|
||||
/* set it up as a HTTP connection instead */
|
||||
return conn->handler->setup_connection(conn);
|
||||
#else
|
||||
failf(data, "FTP over http proxy requires HTTP support built-in!");
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
#endif
|
||||
}
|
||||
|
||||
conn->data->state.proto.ftp = ftp = malloc(sizeof(struct FTP));
|
||||
if(NULL == ftp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
data->state.path++; /* don't include the initial slash */
|
||||
data->state.slash_removed = TRUE; /* we've skipped the slash */
|
||||
|
||||
@ -4636,6 +4568,24 @@ static CURLcode ftp_setup_connection(struct connectdata * conn)
|
||||
}
|
||||
}
|
||||
|
||||
/* get some initial data into the ftp struct */
|
||||
ftp->bytecountp = &conn->data->req.bytecount;
|
||||
ftp->transfer = FTPTRANSFER_BODY;
|
||||
ftp->downloadsize = 0;
|
||||
|
||||
/* No need to duplicate user+password, the connectdata struct won't change
|
||||
during a session, but we re-init them here since on subsequent inits
|
||||
since the conn struct may have changed or been replaced.
|
||||
*/
|
||||
ftp->user = conn->user;
|
||||
ftp->passwd = conn->passwd;
|
||||
if(isBadFtpString(ftp->user))
|
||||
return CURLE_URL_MALFORMAT;
|
||||
if(isBadFtpString(ftp->passwd))
|
||||
return CURLE_URL_MALFORMAT;
|
||||
|
||||
conn->proto.ftpc.known_filesize = -1; /* unknown size for now */
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
35
lib/http.c
35
lib/http.c
@ -105,7 +105,7 @@ static int https_getsock(struct connectdata *conn,
|
||||
*/
|
||||
const struct Curl_handler Curl_handler_http = {
|
||||
"HTTP", /* scheme */
|
||||
ZERO_NULL, /* setup_connection */
|
||||
Curl_http_setup_conn, /* setup_connection */
|
||||
Curl_http, /* do_it */
|
||||
Curl_http_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
@ -129,7 +129,7 @@ const struct Curl_handler Curl_handler_http = {
|
||||
*/
|
||||
const struct Curl_handler Curl_handler_https = {
|
||||
"HTTPS", /* scheme */
|
||||
ZERO_NULL, /* setup_connection */
|
||||
Curl_http_setup_conn, /* setup_connection */
|
||||
Curl_http, /* do_it */
|
||||
Curl_http_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
@ -149,6 +149,21 @@ const struct Curl_handler Curl_handler_https = {
|
||||
#endif
|
||||
|
||||
|
||||
CURLcode Curl_http_setup_conn(struct connectdata *conn)
|
||||
{
|
||||
/* allocate the HTTP-specific struct for the SessionHandle, only to survive
|
||||
during this request */
|
||||
struct HTTP *http;
|
||||
|
||||
DEBUGASSERT(conn->data->state.proto.http == NULL);
|
||||
|
||||
conn->data->state.proto.http = http = calloc(1, sizeof(struct HTTP));
|
||||
if(!http)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* checkheaders() checks the linked list of custom HTTP headers for a
|
||||
* particular header (prefix).
|
||||
@ -1442,6 +1457,7 @@ CURLcode Curl_http_done(struct connectdata *conn,
|
||||
if(!premature && /* this check is pointless when DONE is called before the
|
||||
entire operation is complete */
|
||||
!conn->bits.retry &&
|
||||
!data->set.connect_only &&
|
||||
((http->readbytecount +
|
||||
data->req.headerbytecount -
|
||||
data->req.deductheadercount)) <= 0) {
|
||||
@ -1655,20 +1671,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
the rest of the request in the PERFORM phase. */
|
||||
*done = TRUE;
|
||||
|
||||
/* If there already is a protocol-specific struct allocated for this
|
||||
sessionhandle, deal with it */
|
||||
Curl_reset_reqproto(conn);
|
||||
|
||||
if(!data->state.proto.http) {
|
||||
/* Only allocate this struct if we don't already have it! */
|
||||
|
||||
http = calloc(1, sizeof(struct HTTP));
|
||||
if(!http)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
data->state.proto.http = http;
|
||||
}
|
||||
else
|
||||
http = data->state.proto.http;
|
||||
http = data->state.proto.http;
|
||||
|
||||
if(!data->state.this_is_a_follow) {
|
||||
/* this is not a followed location, get the original host name */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -66,6 +66,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
|
||||
CURLcode Curl_http(struct connectdata *conn, bool *done);
|
||||
CURLcode Curl_http_done(struct connectdata *, CURLcode, bool premature);
|
||||
CURLcode Curl_http_connect(struct connectdata *conn, bool *done);
|
||||
CURLcode Curl_http_setup_conn(struct connectdata *conn);
|
||||
|
||||
/* The following functions are defined in http_chunks.c */
|
||||
void Curl_httpchunk_init(struct connectdata *conn);
|
||||
|
43
lib/imap.c
43
lib/imap.c
@ -163,7 +163,7 @@ const struct Curl_handler Curl_handler_imaps = {
|
||||
|
||||
static const struct Curl_handler Curl_handler_imap_proxy = {
|
||||
"IMAP", /* scheme */
|
||||
ZERO_NULL, /* setup_connection */
|
||||
Curl_http_setup_conn, /* setup_connection */
|
||||
Curl_http, /* do_it */
|
||||
Curl_http_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
@ -188,7 +188,7 @@ static const struct Curl_handler Curl_handler_imap_proxy = {
|
||||
|
||||
static const struct Curl_handler Curl_handler_imaps_proxy = {
|
||||
"IMAPS", /* scheme */
|
||||
ZERO_NULL, /* setup_connection */
|
||||
Curl_http_setup_conn, /* setup_connection */
|
||||
Curl_http, /* do_it */
|
||||
Curl_http_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
@ -1669,13 +1669,11 @@ static CURLcode imap_init(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct IMAP *imap = data->state.proto.imap;
|
||||
struct IMAP *imap;
|
||||
|
||||
if(!imap) {
|
||||
imap = data->state.proto.imap = calloc(sizeof(struct IMAP), 1);
|
||||
if(!imap)
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
imap = data->state.proto.imap = calloc(sizeof(struct IMAP), 1);
|
||||
if(!imap)
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -1705,15 +1703,6 @@ static CURLcode imap_connect(struct connectdata *conn, bool *done)
|
||||
|
||||
*done = FALSE; /* default to not done yet */
|
||||
|
||||
/* If there already is a protocol-specific struct allocated for this
|
||||
sessionhandle, deal with it */
|
||||
Curl_reset_reqproto(conn);
|
||||
|
||||
/* Initialise the IMAP layer */
|
||||
result = imap_init(conn);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* We always support persistent connections in IMAP */
|
||||
conn->bits.close = FALSE;
|
||||
|
||||
@ -1891,15 +1880,6 @@ static CURLcode imap_do(struct connectdata *conn, bool *done)
|
||||
|
||||
*done = FALSE; /* default to false */
|
||||
|
||||
/* Since connections can be re-used between SessionHandles, there might be a
|
||||
connection already existing but on a fresh SessionHandle struct. As such
|
||||
we make sure we have a good IMAP struct to play with. For new connections
|
||||
the IMAP struct is allocated and setup in the imap_connect() function. */
|
||||
Curl_reset_reqproto(conn);
|
||||
result = imap_init(conn);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* Parse the URL path */
|
||||
result = imap_parse_url_path(conn);
|
||||
if(result)
|
||||
@ -2018,6 +1998,11 @@ static CURLcode imap_setup_connection(struct connectdata *conn)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
/* Initialise the IMAP layer */
|
||||
CURLcode result = imap_init(conn);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) {
|
||||
/* Unless we have asked to tunnel IMAP operations through the proxy, we
|
||||
switch and use HTTP operations only */
|
||||
@ -2033,10 +2018,8 @@ static CURLcode imap_setup_connection(struct connectdata *conn)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* We explicitly mark this connection as persistent here as we're doing
|
||||
IMAP over HTTP and thus we accidentally avoid setting this value
|
||||
otherwise */
|
||||
conn->bits.close = FALSE;
|
||||
/* set it up as an HTTP connection instead */
|
||||
return conn->handler->setup_connection(conn);
|
||||
#else
|
||||
failf(data, "IMAP over http proxy requires HTTP support built-in!");
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
|
43
lib/pop3.c
43
lib/pop3.c
@ -163,7 +163,7 @@ const struct Curl_handler Curl_handler_pop3s = {
|
||||
|
||||
static const struct Curl_handler Curl_handler_pop3_proxy = {
|
||||
"POP3", /* scheme */
|
||||
ZERO_NULL, /* setup_connection */
|
||||
Curl_http_setup_conn, /* setup_connection */
|
||||
Curl_http, /* do_it */
|
||||
Curl_http_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
@ -188,7 +188,7 @@ static const struct Curl_handler Curl_handler_pop3_proxy = {
|
||||
|
||||
static const struct Curl_handler Curl_handler_pop3s_proxy = {
|
||||
"POP3S", /* scheme */
|
||||
ZERO_NULL, /* setup_connection */
|
||||
Curl_http_setup_conn, /* setup_connection */
|
||||
Curl_http, /* do_it */
|
||||
Curl_http_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
@ -1395,13 +1395,11 @@ static CURLcode pop3_init(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct POP3 *pop3 = data->state.proto.pop3;
|
||||
struct POP3 *pop3;
|
||||
|
||||
if(!pop3) {
|
||||
pop3 = data->state.proto.pop3 = calloc(sizeof(struct POP3), 1);
|
||||
if(!pop3)
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
pop3 = data->state.proto.pop3 = calloc(sizeof(struct POP3), 1);
|
||||
if(!pop3)
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -1431,15 +1429,6 @@ static CURLcode pop3_connect(struct connectdata *conn, bool *done)
|
||||
|
||||
*done = FALSE; /* default to not done yet */
|
||||
|
||||
/* If there already is a protocol-specific struct allocated for this
|
||||
sessionhandle, deal with it */
|
||||
Curl_reset_reqproto(conn);
|
||||
|
||||
/* Initialise the POP3 layer */
|
||||
result = pop3_init(conn);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* We always support persistent connections in POP3 */
|
||||
conn->bits.close = FALSE;
|
||||
|
||||
@ -1563,15 +1552,6 @@ static CURLcode pop3_do(struct connectdata *conn, bool *done)
|
||||
|
||||
*done = FALSE; /* default to false */
|
||||
|
||||
/* Since connections can be re-used between SessionHandles, there might be a
|
||||
connection already existing but on a fresh SessionHandle struct. As such
|
||||
we make sure we have a good POP3 struct to play with. For new connections
|
||||
the POP3 struct is allocated and setup in the pop3_connect() function. */
|
||||
Curl_reset_reqproto(conn);
|
||||
result = pop3_init(conn);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* Parse the URL path */
|
||||
result = pop3_parse_url_path(conn);
|
||||
if(result)
|
||||
@ -1685,6 +1665,11 @@ static CURLcode pop3_setup_connection(struct connectdata *conn)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
/* Initialise the POP3 layer */
|
||||
CURLcode result = pop3_init(conn);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) {
|
||||
/* Unless we have asked to tunnel POP3 operations through the proxy, we
|
||||
switch and use HTTP operations only */
|
||||
@ -1700,10 +1685,8 @@ static CURLcode pop3_setup_connection(struct connectdata *conn)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* We explicitly mark this connection as persistent here as we're doing
|
||||
POP3 over HTTP and thus we accidentally avoid setting this value
|
||||
otherwise */
|
||||
conn->bits.close = FALSE;
|
||||
/* set it up as an HTTP connection instead */
|
||||
return conn->handler->setup_connection(conn);
|
||||
#else
|
||||
failf(data, "POP3 over http proxy requires HTTP support built-in!");
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
|
35
lib/rtsp.c
35
lib/rtsp.c
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -81,6 +81,8 @@ static CURLcode rtsp_rtp_readwrite(struct SessionHandle *data,
|
||||
ssize_t *nread,
|
||||
bool *readmore);
|
||||
|
||||
static CURLcode rtsp_setup_connection(struct connectdata *conn);
|
||||
|
||||
|
||||
/* this returns the socket to wait for in the DO and DOING state for the multi
|
||||
interface and then we're always _sending_ a request and thus we wait for
|
||||
@ -104,7 +106,7 @@ CURLcode rtp_client_write(struct connectdata *conn, char *ptr, size_t len);
|
||||
*/
|
||||
const struct Curl_handler Curl_handler_rtsp = {
|
||||
"RTSP", /* scheme */
|
||||
ZERO_NULL, /* setup_connection */
|
||||
rtsp_setup_connection, /* setup_connection */
|
||||
rtsp_do, /* do_it */
|
||||
rtsp_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
@ -122,6 +124,19 @@ const struct Curl_handler Curl_handler_rtsp = {
|
||||
PROTOPT_NONE /* flags */
|
||||
};
|
||||
|
||||
|
||||
static CURLcode rtsp_setup_connection(struct connectdata *conn)
|
||||
{
|
||||
struct RTSP *rtsp;
|
||||
|
||||
conn->data->state.proto.rtsp = rtsp = calloc(1, sizeof(struct RTSP));
|
||||
if(!rtsp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The server may send us RTP data at any point, and RTSPREQ_RECEIVE does not
|
||||
* want to block the application forever while receiving a stream. Therefore,
|
||||
@ -221,7 +236,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
|
||||
struct SessionHandle *data = conn->data;
|
||||
CURLcode result=CURLE_OK;
|
||||
Curl_RtspReq rtspreq = data->set.rtspreq;
|
||||
struct RTSP *rtsp;
|
||||
struct RTSP *rtsp = data->state.proto.rtsp;
|
||||
struct HTTP *http;
|
||||
Curl_send_buffer *req_buffer;
|
||||
curl_off_t postsize = 0; /* for ANNOUNCE and SET_PARAMETER */
|
||||
@ -239,20 +254,6 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
|
||||
|
||||
*done = TRUE;
|
||||
|
||||
Curl_reset_reqproto(conn);
|
||||
|
||||
if(!data->state.proto.rtsp) {
|
||||
/* Only allocate this struct if we don't already have it! */
|
||||
|
||||
rtsp = calloc(1, sizeof(struct RTSP));
|
||||
if(!rtsp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
data->state.proto.rtsp = rtsp;
|
||||
}
|
||||
else {
|
||||
rtsp = data->state.proto.rtsp;
|
||||
}
|
||||
|
||||
http = &(rtsp->http_wrapper);
|
||||
/* Assert that no one has changed the RTSP struct in an evil way */
|
||||
DEBUGASSERT((void *)http == (void *)rtsp);
|
||||
|
44
lib/smtp.c
44
lib/smtp.c
@ -161,7 +161,7 @@ const struct Curl_handler Curl_handler_smtps = {
|
||||
|
||||
static const struct Curl_handler Curl_handler_smtp_proxy = {
|
||||
"SMTP", /* scheme */
|
||||
ZERO_NULL, /* setup_connection */
|
||||
Curl_http_setup_conn, /* setup_connection */
|
||||
Curl_http, /* do_it */
|
||||
Curl_http_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
@ -186,7 +186,7 @@ static const struct Curl_handler Curl_handler_smtp_proxy = {
|
||||
|
||||
static const struct Curl_handler Curl_handler_smtps_proxy = {
|
||||
"SMTPS", /* scheme */
|
||||
ZERO_NULL, /* setup_connection */
|
||||
Curl_http_setup_conn, /* setup_connection */
|
||||
Curl_http, /* do_it */
|
||||
Curl_http_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
@ -1361,13 +1361,11 @@ static CURLcode smtp_init(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct SMTP *smtp = data->state.proto.smtp;
|
||||
struct SMTP *smtp;
|
||||
|
||||
if(!smtp) {
|
||||
smtp = data->state.proto.smtp = calloc(sizeof(struct SMTP), 1);
|
||||
if(!smtp)
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
smtp = data->state.proto.smtp = calloc(sizeof(struct SMTP), 1);
|
||||
if(!smtp)
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -1397,15 +1395,6 @@ static CURLcode smtp_connect(struct connectdata *conn, bool *done)
|
||||
|
||||
*done = FALSE; /* default to not done yet */
|
||||
|
||||
/* If there already is a protocol-specific struct allocated for this
|
||||
sessionhandle, deal with it */
|
||||
Curl_reset_reqproto(conn);
|
||||
|
||||
/* Initialise the SMTP layer */
|
||||
result = smtp_init(conn);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* We always support persistent connections in SMTP */
|
||||
conn->bits.close = FALSE;
|
||||
|
||||
@ -1571,15 +1560,6 @@ static CURLcode smtp_do(struct connectdata *conn, bool *done)
|
||||
|
||||
*done = FALSE; /* default to false */
|
||||
|
||||
/* Since connections can be re-used between SessionHandles, there might be a
|
||||
connection already existing but on a fresh SessionHandle struct. As such
|
||||
we make sure we have a good SMTP struct to play with. For new connections
|
||||
the SMTP struct is allocated and setup in the smtp_connect() function. */
|
||||
Curl_reset_reqproto(conn);
|
||||
result = smtp_init(conn);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = smtp_regular_transfer(conn, done);
|
||||
|
||||
return result;
|
||||
@ -1687,6 +1667,7 @@ static CURLcode smtp_regular_transfer(struct connectdata *conn,
|
||||
static CURLcode smtp_setup_connection(struct connectdata *conn)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
CURLcode result;
|
||||
|
||||
if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) {
|
||||
/* Unless we have asked to tunnel SMTP operations through the proxy, we
|
||||
@ -1702,17 +1683,20 @@ static CURLcode smtp_setup_connection(struct connectdata *conn)
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
#endif
|
||||
}
|
||||
/* set it up as a HTTP connection instead */
|
||||
return conn->handler->setup_connection(conn);
|
||||
|
||||
/* We explicitly mark this connection as persistent here as we're doing
|
||||
SMTP over HTTP and thus we accidentally avoid setting this value
|
||||
otherwise */
|
||||
conn->bits.close = FALSE;
|
||||
#else
|
||||
failf(data, "SMTP over http proxy requires HTTP support built-in!");
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Initialise the SMTP layer */
|
||||
result = smtp_init(conn);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
data->state.path++; /* don't include the initial slash */
|
||||
|
||||
return CURLE_OK;
|
||||
|
47
lib/ssh.c
47
lib/ssh.c
@ -149,13 +149,15 @@ static int ssh_perform_getsock(const struct connectdata *conn,
|
||||
number of sockets */
|
||||
int numsocks);
|
||||
|
||||
static CURLcode ssh_setup_connection(struct connectdata *conn);
|
||||
|
||||
/*
|
||||
* SCP protocol handler.
|
||||
*/
|
||||
|
||||
const struct Curl_handler Curl_handler_scp = {
|
||||
"SCP", /* scheme */
|
||||
ZERO_NULL, /* setup_connection */
|
||||
ssh_setup_connection, /* setup_connection */
|
||||
ssh_do, /* do_it */
|
||||
scp_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
@ -181,7 +183,7 @@ const struct Curl_handler Curl_handler_scp = {
|
||||
|
||||
const struct Curl_handler Curl_handler_sftp = {
|
||||
"SFTP", /* scheme */
|
||||
ZERO_NULL, /* setup_connection */
|
||||
ssh_setup_connection, /* setup_connection */
|
||||
ssh_do, /* do_it */
|
||||
sftp_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
@ -200,7 +202,6 @@ const struct Curl_handler Curl_handler_sftp = {
|
||||
| PROTOPT_NOURLQUERY /* flags */
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
kbd_callback(const char *name, int name_len, const char *instruction,
|
||||
int instruction_len, int num_prompts,
|
||||
@ -2689,25 +2690,14 @@ static CURLcode ssh_block_statemach(struct connectdata *conn,
|
||||
/*
|
||||
* SSH setup and connection
|
||||
*/
|
||||
static CURLcode ssh_init(struct connectdata *conn)
|
||||
static CURLcode ssh_setup_connection(struct connectdata *conn)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct SSHPROTO *ssh;
|
||||
struct ssh_conn *sshc = &conn->proto.sshc;
|
||||
|
||||
sshc->actualcode = CURLE_OK; /* reset error code */
|
||||
sshc->secondCreateDirs =0; /* reset the create dir attempt state
|
||||
variable */
|
||||
|
||||
if(data->state.proto.ssh)
|
||||
return CURLE_OK;
|
||||
|
||||
ssh = calloc(1, sizeof(struct SSHPROTO));
|
||||
conn->data->state.proto.ssh = ssh = calloc(1, sizeof(struct SSHPROTO));
|
||||
if(!ssh)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
data->state.proto.ssh = ssh;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@ -2731,14 +2721,6 @@ static CURLcode ssh_connect(struct connectdata *conn, bool *done)
|
||||
function to make the re-use checks properly be able to check this bit. */
|
||||
conn->bits.close = FALSE;
|
||||
|
||||
/* If there already is a protocol-specific struct allocated for this
|
||||
sessionhandle, deal with it */
|
||||
Curl_reset_reqproto(conn);
|
||||
|
||||
result = ssh_init(conn);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(conn->handler->protocol & CURLPROTO_SCP) {
|
||||
conn->recv[FIRSTSOCKET] = scp_recv;
|
||||
conn->send[FIRSTSOCKET] = scp_send;
|
||||
@ -2856,23 +2838,16 @@ static CURLcode ssh_do(struct connectdata *conn, bool *done)
|
||||
CURLcode res;
|
||||
bool connected = 0;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct ssh_conn *sshc = &conn->proto.sshc;
|
||||
|
||||
*done = FALSE; /* default to false */
|
||||
|
||||
/*
|
||||
Since connections can be re-used between SessionHandles, this might be a
|
||||
connection already existing but on a fresh SessionHandle struct so we must
|
||||
make sure we have a good 'struct SSHPROTO' to play with. For new
|
||||
connections, the struct SSHPROTO is allocated and setup in the
|
||||
ssh_connect() function.
|
||||
*/
|
||||
Curl_reset_reqproto(conn);
|
||||
res = ssh_init(conn);
|
||||
if(res)
|
||||
return res;
|
||||
|
||||
data->req.size = -1; /* make sure this is unknown at this point */
|
||||
|
||||
sshc->actualcode = CURLE_OK; /* reset error code */
|
||||
sshc->secondCreateDirs =0; /* reset the create dir attempt state
|
||||
variable */
|
||||
|
||||
Curl_pgrsSetUploadCounter(data, 0);
|
||||
Curl_pgrsSetDownloadCounter(data, 0);
|
||||
Curl_pgrsSetUploadSize(data, 0);
|
||||
|
12
lib/tftp.c
12
lib/tftp.c
@ -947,10 +947,6 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done)
|
||||
|
||||
blksize = TFTP_BLKSIZE_DEFAULT;
|
||||
|
||||
/* If there already is a protocol-specific struct allocated for this
|
||||
sessionhandle, deal with it */
|
||||
Curl_reset_reqproto(conn);
|
||||
|
||||
state = conn->proto.tftpc = calloc(1, sizeof(tftp_state_data_t));
|
||||
if(!state)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
@ -1307,14 +1303,6 @@ static CURLcode tftp_do(struct connectdata *conn, bool *done)
|
||||
|
||||
*done = FALSE;
|
||||
|
||||
/*
|
||||
Since connections can be re-used between SessionHandles, this might be a
|
||||
connection already existing but on a fresh SessionHandle struct so we must
|
||||
make sure we have a good 'struct TFTP' to play with. For new connections,
|
||||
the struct TFTP is allocated and setup in the tftp_connect() function.
|
||||
*/
|
||||
Curl_reset_reqproto(conn);
|
||||
|
||||
if(!conn->proto.tftpc) {
|
||||
code = tftp_connect(conn, done);
|
||||
if(code)
|
||||
|
92
lib/url.c
92
lib/url.c
@ -148,6 +148,7 @@ static CURLcode parse_url_login(struct SessionHandle *data,
|
||||
static CURLcode parse_login_details(const char *login, const size_t len,
|
||||
char **userptr, char **passwdptr,
|
||||
char **optionsptr);
|
||||
static void free_connection_internals(struct SessionHandle *data);
|
||||
/*
|
||||
* Protocol table.
|
||||
*/
|
||||
@ -417,7 +418,8 @@ CURLcode Curl_close(struct SessionHandle *data)
|
||||
Curl_safefree(data->state.pathbuffer);
|
||||
data->state.path = NULL;
|
||||
|
||||
Curl_safefree(data->state.proto.generic);
|
||||
/* freed here just in case DONE wasn't called */
|
||||
free_connection_internals(data);
|
||||
|
||||
/* Close down all open SSL info and sessions */
|
||||
Curl_ssl_close_all(data);
|
||||
@ -4016,18 +4018,28 @@ static CURLcode setup_range(struct SessionHandle *data)
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* Setup connection internals specific to the requested protocol.
|
||||
* This MUST get called after proxy magic has been figured out.
|
||||
***************************************************************/
|
||||
/*
|
||||
* setup_connection_internals() -
|
||||
*
|
||||
* Setup connection internals specific to the requested protocol in the
|
||||
* SessionHandle. This is inited and setup before the connection is made but
|
||||
* is about the particular protocol that is to be used.
|
||||
*
|
||||
* This MUST get called after proxy magic has been figured out.
|
||||
*/
|
||||
static CURLcode setup_connection_internals(struct connectdata *conn)
|
||||
{
|
||||
const struct Curl_handler * p;
|
||||
CURLcode result;
|
||||
|
||||
conn->socktype = SOCK_STREAM; /* most of them are TCP streams */
|
||||
/* in some case in the multi state-machine, we go back to the CONNECT state
|
||||
and then a second (or third or...) call to this function will be made
|
||||
without doing a DISCONNECT or DONE in between (since the connection is
|
||||
yet in place) and therefore this function needs to first make sure
|
||||
there's no lingering previous data allocated. */
|
||||
free_connection_internals(conn->data);
|
||||
|
||||
/* Scan protocol handler table. */
|
||||
conn->socktype = SOCK_STREAM; /* most of them are TCP streams */
|
||||
|
||||
/* Perform setup complement if some. */
|
||||
p = conn->handler;
|
||||
@ -4045,11 +4057,21 @@ static CURLcode setup_connection_internals(struct connectdata *conn)
|
||||
/* we check for -1 here since if proxy was detected already, this
|
||||
was very likely already set to the proxy port */
|
||||
conn->port = p->defport;
|
||||
conn->remote_port = (unsigned short)conn->given->defport;
|
||||
|
||||
/* only if remote_port was not already parsed off the URL we use the
|
||||
default port number */
|
||||
if(!conn->remote_port)
|
||||
conn->remote_port = (unsigned short)conn->given->defport;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static void free_connection_internals(struct SessionHandle *data)
|
||||
{
|
||||
Curl_safefree(data->state.proto.generic);
|
||||
}
|
||||
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
/****************************************************************
|
||||
* Checks if the host is in the noproxy list. returns true if it matches
|
||||
@ -5217,6 +5239,27 @@ static CURLcode create_conn(struct SessionHandle *data,
|
||||
|
||||
#endif /* CURL_DISABLE_PROXY */
|
||||
|
||||
/*************************************************************
|
||||
* If the protocol is using SSL and HTTP proxy is used, we set
|
||||
* the tunnel_proxy bit.
|
||||
*************************************************************/
|
||||
if((conn->given->flags&PROTOPT_SSL) && conn->bits.httpproxy)
|
||||
conn->bits.tunnel_proxy = TRUE;
|
||||
|
||||
/*************************************************************
|
||||
* Figure out the remote port number and fix it in the URL
|
||||
*************************************************************/
|
||||
result = parse_remote_port(data, conn);
|
||||
if(result != CURLE_OK)
|
||||
return result;
|
||||
|
||||
/* Check for overridden login details and set them accordingly so they
|
||||
they are known when protocol->setup_connection is called! */
|
||||
override_login(data, conn, user, passwd, options);
|
||||
result = set_login(conn, user, passwd, options);
|
||||
if(result != CURLE_OK)
|
||||
return result;
|
||||
|
||||
/*************************************************************
|
||||
* Setup internals depending on protocol. Needs to be done after
|
||||
* we figured out what/if proxy to use.
|
||||
@ -5266,32 +5309,12 @@ static CURLcode create_conn(struct SessionHandle *data,
|
||||
}
|
||||
|
||||
/* since we skip do_init() */
|
||||
Curl_speedinit(data);
|
||||
do_init(conn);
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*************************************************************
|
||||
* If the protocol is using SSL and HTTP proxy is used, we set
|
||||
* the tunnel_proxy bit.
|
||||
*************************************************************/
|
||||
if((conn->given->flags&PROTOPT_SSL) && conn->bits.httpproxy)
|
||||
conn->bits.tunnel_proxy = TRUE;
|
||||
|
||||
/*************************************************************
|
||||
* Figure out the remote port number and fix it in the URL
|
||||
*************************************************************/
|
||||
result = parse_remote_port(data, conn);
|
||||
if(result != CURLE_OK)
|
||||
return result;
|
||||
|
||||
/* Check for overridden login details and set them accordingly */
|
||||
override_login(data, conn, user, passwd, options);
|
||||
result = set_login(conn, user, passwd, options);
|
||||
if(result != CURLE_OK)
|
||||
return result;
|
||||
|
||||
/* Get a cloned copy of the SSL config situation stored in the
|
||||
connection struct. But to get this going nicely, we must first make
|
||||
sure that the strings in the master copy are pointing to the correct
|
||||
@ -5728,6 +5751,7 @@ CURLcode Curl_done(struct connectdata **connp,
|
||||
this was either closed or handed over to the connection
|
||||
cache here, and therefore cannot be used from this point on
|
||||
*/
|
||||
free_connection_internals(data);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -5861,13 +5885,3 @@ CURLcode Curl_do_more(struct connectdata *conn, int *complete)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Called on connect, and if there's already a protocol-specific struct
|
||||
allocated for a different connection, this frees it that it can be setup
|
||||
properly later on. */
|
||||
void Curl_reset_reqproto(struct connectdata *conn)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
Curl_safefree(data->state.proto.generic);
|
||||
data->state.proto.generic = NULL;
|
||||
}
|
||||
|
@ -65,11 +65,6 @@ void Curl_getoff_all_pipelines(struct SessionHandle *data,
|
||||
|
||||
void Curl_close_connections(struct SessionHandle *data);
|
||||
|
||||
/* Called on connect, and if there's already a protocol-specific struct
|
||||
allocated for a different connection, this frees it that it can be setup
|
||||
properly later on. */
|
||||
void Curl_reset_reqproto(struct connectdata *conn);
|
||||
|
||||
#define CURL_DEFAULT_PROXY_PORT 1080 /* default proxy port unless specified */
|
||||
#define CURL_DEFAULT_SOCKS5_GSSAPI_SERVICE "rcmd" /* default socks5 gssapi
|
||||
service */
|
||||
|
@ -1277,9 +1277,10 @@ struct UrlState {
|
||||
/* Protocol specific data.
|
||||
*
|
||||
*************************************************************************
|
||||
* Note that this data will be REMOVED after each request, so anything that
|
||||
* should be kept/stored on a per-connection basis and thus live for the
|
||||
* next request on the same connection MUST be put in the connectdata struct!
|
||||
* Note that this data will be freed after each request is DONE, so anything
|
||||
* that should be kept/stored on a per-connection basis and thus live for
|
||||
* the next request on the same connection MUST be put in the connectdata
|
||||
* struct!
|
||||
*************************************************************************/
|
||||
union {
|
||||
struct HTTP *http;
|
||||
|
Loading…
Reference in New Issue
Block a user