protocol handler: added flags field

The protocol handler struct got a 'flags' field for special information
and characteristics of the given protocol.

This now enables us to move away central protocol information such as
CLOSEACTION and DUALCHANNEL from single defines in a central place, out
to each protocol's definition. It also made us stop abusing the protocol
field for other info than the protocol, and we could start cleaning up
other protocol-specific things by adding flags bits to set in the
handler struct.

The "protocol" field connectdata struct was removed as well and the code
now refers directly to the conn->handler->protocol field instead. To
make things work properly, the code now always store a conn->given
pointer that points out the original handler struct so that the code can
learn details from the original protocol even if conn->handler is
modified along the way - for example when switching to go over a HTTP
proxy.
This commit is contained in:
Daniel Stenberg 2011-03-14 22:22:22 +01:00
Родитель ed8749e308
Коммит 8831000bc0
19 изменённых файлов: 166 добавлений и 132 удалений

Просмотреть файл

@ -74,7 +74,8 @@ const struct Curl_handler Curl_handler_rtmp = {
ZERO_NULL, /* perform_getsock */
rtmp_disconnect, /* disconnect */
PORT_RTMP, /* defport */
PROT_RTMP /* protocol */
PROT_RTMP, /* protocol */
PROTOPT_NONE /* flags*/
};
const struct Curl_handler Curl_handler_rtmpt = {
@ -91,7 +92,8 @@ const struct Curl_handler Curl_handler_rtmpt = {
ZERO_NULL, /* perform_getsock */
rtmp_disconnect, /* disconnect */
PORT_RTMPT, /* defport */
PROT_RTMPT /* protocol */
PROT_RTMPT, /* protocol */
PROTOPT_NONE /* flags*/
};
const struct Curl_handler Curl_handler_rtmpe = {
@ -108,7 +110,8 @@ const struct Curl_handler Curl_handler_rtmpe = {
ZERO_NULL, /* perform_getsock */
rtmp_disconnect, /* disconnect */
PORT_RTMP, /* defport */
PROT_RTMPE /* protocol */
PROT_RTMPE, /* protocol */
PROTOPT_NONE /* flags*/
};
const struct Curl_handler Curl_handler_rtmpte = {
@ -125,7 +128,8 @@ const struct Curl_handler Curl_handler_rtmpte = {
ZERO_NULL, /* perform_getsock */
rtmp_disconnect, /* disconnect */
PORT_RTMPT, /* defport */
PROT_RTMPTE /* protocol */
PROT_RTMPTE, /* protocol */
PROTOPT_NONE /* flags*/
};
const struct Curl_handler Curl_handler_rtmps = {
@ -142,7 +146,8 @@ const struct Curl_handler Curl_handler_rtmps = {
ZERO_NULL, /* perform_getsock */
rtmp_disconnect, /* disconnect */
PORT_RTMPS, /* defport */
PROT_RTMPS /* protocol */
PROT_RTMPS, /* protocol */
PROTOPT_NONE /* flags*/
};
const struct Curl_handler Curl_handler_rtmpts = {
"RTMPTS", /* scheme */
@ -158,7 +163,8 @@ const struct Curl_handler Curl_handler_rtmpts = {
ZERO_NULL, /* perform_getsock */
rtmp_disconnect, /* disconnect */
PORT_RTMPS, /* defport */
PROT_RTMPTS /* protocol */
PROT_RTMPTS, /* protocol */
PROTOPT_NONE /* flags*/
};
static CURLcode rtmp_setup(struct connectdata *conn)

Просмотреть файл

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2011, 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
@ -108,7 +108,8 @@ const struct Curl_handler Curl_handler_dict = {
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
PORT_DICT, /* defport */
PROT_DICT /* protocol */
PROT_DICT, /* protocol */
PROTOPT_NONE /* flags */
};
static char *unescape_word(struct SessionHandle *data, const char *inputbuff)

Просмотреть файл

@ -127,7 +127,8 @@ const struct Curl_handler Curl_handler_file = {
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
0, /* defport */
PROT_FILE /* protocol */
PROT_FILE, /* protocol */
PROTOPT_BANPROXY /* flags */
};

Просмотреть файл

@ -179,7 +179,8 @@ const struct Curl_handler Curl_handler_ftp = {
ZERO_NULL, /* perform_getsock */
ftp_disconnect, /* disconnect */
PORT_FTP, /* defport */
PROT_FTP /* protocol */
PROT_FTP, /* protocol */
PROTOPT_DUAL | PROTOPT_CLOSEACTION /* flags */
};
@ -202,7 +203,8 @@ const struct Curl_handler Curl_handler_ftps = {
ZERO_NULL, /* perform_getsock */
ftp_disconnect, /* disconnect */
PORT_FTPS, /* defport */
PROT_FTP | PROT_FTPS | PROT_SSL /* protocol */
PROT_FTP | PROT_FTPS, /* protocol */
PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION /* flags */
};
#endif
@ -225,7 +227,8 @@ static const struct Curl_handler Curl_handler_ftp_proxy = {
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
PORT_FTP, /* defport */
PROT_HTTP /* protocol */
PROT_HTTP, /* protocol */
PROTOPT_NONE /* flags */
};
@ -248,7 +251,8 @@ static const struct Curl_handler Curl_handler_ftps_proxy = {
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
PORT_FTPS, /* defport */
PROT_HTTP /* protocol */
PROT_HTTP, /* protocol */
PROTOPT_NONE /* flags */
};
#endif
#endif
@ -2480,7 +2484,6 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
/* Curl_ssl_connect is BLOCKING */
result = Curl_ssl_connect(conn, FIRSTSOCKET);
if(CURLE_OK == result) {
conn->protocol |= PROT_FTPS;
conn->ssl[SECONDARYSOCKET].use = FALSE; /* clear-text data */
result = ftp_state_user(conn);
}
@ -2949,7 +2952,7 @@ static CURLcode ftp_connect(struct connectdata *conn,
}
#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_PROXY */
if(conn->protocol & PROT_FTPS) {
if(conn->handler->protocol & PROT_FTPS) {
/* BLOCKING */
/* FTPS is simply ftp with SSL for the control channel */
/* now, perform the SSL initialization for this socket */

Просмотреть файл

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2011, 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
@ -113,7 +113,8 @@ const struct Curl_handler Curl_handler_gopher = {
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
PORT_GOPHER, /* defport */
PROT_GOPHER /* protocol */
PROT_GOPHER, /* protocol */
PROTOPT_NONE /* flags */
};
static CURLcode gopher_do(struct connectdata *conn, bool *done)

Просмотреть файл

@ -143,6 +143,7 @@ const struct Curl_handler Curl_handler_http = {
ZERO_NULL, /* disconnect */
PORT_HTTP, /* defport */
PROT_HTTP, /* protocol */
PROTOPT_NONE /* flags */
};
#ifdef USE_SSL
@ -163,7 +164,8 @@ const struct Curl_handler Curl_handler_https = {
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
PORT_HTTPS, /* defport */
PROT_HTTP | PROT_HTTPS | PROT_SSL /* protocol */
PROT_HTTP | PROT_HTTPS, /* protocol */
PROTOPT_SSL /* flags */
};
#endif
@ -345,7 +347,7 @@ CURLcode Curl_http_perhapsrewind(struct connectdata *conn)
curl_off_t bytessent;
curl_off_t expectsend = -1; /* default is unknown */
if(!http || !(conn->protocol & PROT_HTTP))
if(!http || !(conn->handler->protocol & PROT_HTTP))
/* If this is still NULL, we have not reach very far and we can
safely skip this rewinding stuff, or this is attempted to get used
when HTTP isn't activated */
@ -1026,7 +1028,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
}
#endif /* CURL_DOES_CONVERSIONS */
if(conn->protocol & PROT_HTTPS) {
if(conn->handler->protocol & PROT_HTTPS) {
/* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
when we speak HTTPS, as if only a fraction of it is sent now, this data
needs to fit into the normal read-callback buffer later on and that
@ -1773,7 +1775,7 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
}
#endif /* CURL_DISABLE_PROXY */
if(conn->protocol & PROT_HTTPS) {
if(conn->handler->protocol & PROT_HTTPS) {
/* perform SSL initialization */
if(data->state.used_interface == Curl_if_multi) {
result = https_connecting(conn, done);
@ -1812,7 +1814,7 @@ static int http_getsock_do(struct connectdata *conn,
static CURLcode https_connecting(struct connectdata *conn, bool *done)
{
CURLcode result;
DEBUGASSERT((conn) && (conn->protocol & PROT_HTTPS));
DEBUGASSERT((conn) && (conn->handler->protocol & PROT_HTTPS));
/* perform SSL initialization for this socket */
result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
@ -1830,7 +1832,7 @@ static int https_getsock(struct connectdata *conn,
curl_socket_t *socks,
int numsocks)
{
if(conn->protocol & PROT_HTTPS) {
if(conn->handler->protocol & PROT_HTTPS) {
struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
if(!numsocks)
@ -2122,7 +2124,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
return CURLE_OUT_OF_MEMORY;
}
if( (conn->protocol&(PROT_HTTP|PROT_FTP)) &&
if( (conn->handler->protocol&(PROT_HTTP|PROT_FTP)) &&
data->set.upload) {
httpreq = HTTPREQ_PUT;
}
@ -2203,7 +2205,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
}
else {
if((conn->protocol&PROT_HTTP) &&
if((conn->handler->protocol&PROT_HTTP) &&
data->set.upload &&
(data->set.infilesize == -1)) {
if(conn->bits.authneg)
@ -2259,9 +2261,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
/* When building Host: headers, we must put the host name within
[brackets] if the host name is a plain IPv6-address. RFC2732-style. */
if(((conn->protocol&PROT_HTTPS) && (conn->remote_port == PORT_HTTPS)) ||
(!(conn->protocol&PROT_HTTPS) && (conn->remote_port == PORT_HTTP)) )
/* if(HTTPS on port 443) OR (non-HTTPS on port 80) then don't include
if(((conn->given->protocol&PROT_HTTPS) &&
(conn->remote_port == PORT_HTTPS)) ||
((conn->given->protocol&PROT_HTTP) &&
(conn->remote_port == PORT_HTTP)) )
/* if(HTTPS on port 443) OR (HTTP on port 80) then don't include
the port number in the host string */
conn->allocptr.host = aprintf("Host: %s%s%s\r\n",
conn->bits.ipv6_ip?"[":"",
@ -2576,7 +2580,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
conn->allocptr.cookiehost?
conn->allocptr.cookiehost:host,
data->state.path,
(bool)(conn->protocol&PROT_HTTPS?TRUE:FALSE));
(bool)(conn->handler->protocol&PROT_HTTPS?
TRUE:FALSE));
Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
}
if(co) {
@ -3036,7 +3041,7 @@ checkprotoprefix(struct SessionHandle *data, struct connectdata *conn,
const char *s)
{
#ifndef CURL_DISABLE_RTSP
if(conn->protocol & PROT_RTSP)
if(conn->handler->protocol & PROT_RTSP)
return checkrtspprefix(data, s);
#else
(void)conn;
@ -3212,7 +3217,8 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
k->header = FALSE; /* no more header to parse! */
if((k->size == -1) && !k->chunk && !conn->bits.close &&
(conn->httpversion >= 11) && !(conn->protocol & PROT_RTSP)) {
(conn->httpversion >= 11) &&
!(conn->handler->protocol & PROT_RTSP)) {
/* On HTTP 1.1, when connection is not to get closed, but no
Content-Length nor Content-Encoding chunked have been
received, according to RFC2616 section 4.4 point 5, we
@ -3373,7 +3379,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
#define HEADER1 k->p /* no conversion needed, just use k->p */
#endif /* CURL_DOES_CONVERSIONS */
if(conn->protocol & PROT_HTTP) {
if(conn->handler->protocol & PROT_HTTP) {
nc = sscanf(HEADER1,
" HTTP/%d.%d %3d",
&httpversion_major,
@ -3401,7 +3407,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
}
}
}
else if(conn->protocol & PROT_RTSP) {
else if(conn->handler->protocol & PROT_RTSP) {
nc = sscanf(HEADER1,
" RTSP/%d.%d %3d",
&rtspversion_major,
@ -3592,7 +3598,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
conn->bits.close = TRUE; /* close when done */
}
else if(Curl_compareheader(k->p, "Transfer-Encoding:", "chunked") &&
!(conn->protocol & PROT_RTSP)) {
!(conn->handler->protocol & PROT_RTSP)) {
/*
* [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
* means that the server will send a series of "chunks". Each
@ -3715,7 +3721,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
}
}
#ifndef CURL_DISABLE_RTSP
else if(conn->protocol & PROT_RTSP) {
else if(conn->handler->protocol & PROT_RTSP) {
result = Curl_rtsp_parseheader(conn, k->p);
if(result)
return result;

Просмотреть файл

@ -128,7 +128,8 @@ const struct Curl_handler Curl_handler_imap = {
ZERO_NULL, /* perform_getsock */
imap_disconnect, /* disconnect */
PORT_IMAP, /* defport */
PROT_IMAP /* protocol */
PROT_IMAP, /* protocol */
PROTOPT_CLOSEACTION /* flags */
};
@ -151,7 +152,8 @@ const struct Curl_handler Curl_handler_imaps = {
ZERO_NULL, /* perform_getsock */
imap_disconnect, /* disconnect */
PORT_IMAPS, /* defport */
PROT_IMAP | PROT_IMAPS | PROT_SSL /* protocol */
PROT_IMAP | PROT_IMAPS, /* protocol */
PROTOPT_CLOSEACTION | PROTOPT_SSL /* flags */
};
#endif
@ -174,7 +176,8 @@ static const struct Curl_handler Curl_handler_imap_proxy = {
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
PORT_IMAP, /* defport */
PROT_HTTP /* protocol */
PROT_HTTP, /* protocol */
PROTOPT_NONE /* flags */
};
@ -197,7 +200,8 @@ static const struct Curl_handler Curl_handler_imaps_proxy = {
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
PORT_IMAPS, /* defport */
PROT_HTTP /* protocol */
PROT_HTTP, /* protocol */
PROTOPT_NONE /* flags */
};
#endif
#endif
@ -351,7 +355,7 @@ static CURLcode imap_state_starttls_resp(struct connectdata *conn,
else {
result = Curl_ssl_connect(conn, FIRSTSOCKET);
if(CURLE_OK == result) {
conn->protocol |= PROT_IMAPS;
conn->handler = &Curl_handler_imaps;
result = imap_state_login(conn);
}
}
@ -368,7 +372,7 @@ static CURLcode imap_state_upgrade_tls(struct connectdata *conn)
result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &imapc->ssldone);
if(imapc->ssldone) {
conn->protocol |= PROT_IMAPS;
conn->handler = &Curl_handler_imaps;
result = imap_state_login(conn);
state(conn, IMAP_STOP);
}
@ -617,7 +621,7 @@ static CURLcode imap_multi_statemach(struct connectdata *conn,
struct imap_conn *imapc = &conn->proto.imapc;
CURLcode result;
if((conn->protocol & PROT_IMAPS) && !imapc->ssldone) {
if((conn->handler->protocol & PROT_IMAPS) && !imapc->ssldone) {
result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &imapc->ssldone);
}
else {
@ -734,7 +738,8 @@ static CURLcode imap_connect(struct connectdata *conn,
}
#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_PROXY */
if((conn->protocol & PROT_IMAPS) && data->state.used_interface != Curl_if_multi) {
if((conn->handler->protocol & PROT_IMAPS) &&
data->state.used_interface != Curl_if_multi) {
/* BLOCKING */
/* IMAPS is simply imap with SSL for the control channel */
/* now, perform the SSL initialization for this socket */

Просмотреть файл

@ -1476,7 +1476,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
* a protocol which uses two "channels" like FTP, as then the error
* happened in the data connection.
*/
if(!(easy->easy_conn->protocol & PROT_DUALCHANNEL))
if(!(easy->easy_conn->handler->flags & PROTOPT_DUAL))
easy->easy_conn->bits.close = TRUE;
Curl_posttransfer(data);
@ -1768,7 +1768,7 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
/* go over all connections that have close actions */
for(i=0; i< multi->connc->num; i++) {
if(multi->connc->connects[i] &&
multi->connc->connects[i]->protocol & PROT_CLOSEACTION) {
multi->connc->connects[i]->handler->flags & PROTOPT_CLOSEACTION) {
Curl_disconnect(multi->connc->connects[i], /* dead_connection */ FALSE);
multi->connc->connects[i] = NULL;
}
@ -2129,7 +2129,7 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
data = conn->recv_pipe->head->ptr;
}
if(conn && !(conn->handler->protocol & PROT_LOCKEDBITS))
if(conn && !(conn->handler->flags & PROTOPT_DIRLOCK))
/* set socket event bitmask if they're not locked */
conn->cselect_bits = ev_bitmask;
@ -2137,7 +2137,7 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
result = multi_runsingle(multi, now, data->set.one_easy);
while (CURLM_CALL_MULTI_PERFORM == result);
if(conn && !(conn->handler->protocol & PROT_LOCKEDBITS))
if(conn && !(conn->handler->flags & PROTOPT_DIRLOCK))
/* clear the bitmask only if not locked */
conn->cselect_bits = 0;
@ -2682,7 +2682,7 @@ static void multi_connc_remove_handle(struct Curl_multi *multi,
for nice connection closures".
*/
if(conn->protocol & PROT_CLOSEACTION) {
if(conn->handler->flags & PROTOPT_CLOSEACTION) {
/* this handle is still being used by a shared connection and
thus we leave it around for now */
if(add_closure(multi, data) == CURLM_OK)

Просмотреть файл

@ -83,7 +83,8 @@ const struct Curl_handler Curl_handler_ldap = {
ZERO_NULL, /* perform_getsock */
ldap_disconnect, /* disconnect */
PORT_LDAP, /* defport */
PROT_LDAP /* protocol */
PROT_LDAP, /* protocol */
PROTOPT_NONE /* flags */
};
#ifdef USE_SSL
@ -105,7 +106,8 @@ const struct Curl_handler Curl_handler_ldaps = {
ZERO_NULL, /* perform_getsock */
ldap_disconnect, /* disconnect */
PORT_LDAPS, /* defport */
PROT_LDAP | PROT_SSL /* protocol */
PROT_LDAP, /* protocol */
PROTOPT_SSL /* flags */
};
#endif
@ -185,7 +187,7 @@ static CURLcode ldap_connect(struct connectdata *conn, bool *done)
strcpy(hosturl, "ldap");
ptr = hosturl+4;
if (conn->protocol & PROT_SSL)
if (conn->handler->flags & PROTOPT_SSL)
*ptr++ = 's';
snprintf(ptr, sizeof(hosturl)-(ptr-hosturl), "://%s:%d",
conn->host.name, conn->remote_port);
@ -229,7 +231,7 @@ static CURLcode ldap_connect(struct connectdata *conn, bool *done)
#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_PROXY */
#ifdef USE_SSL
if (conn->protocol & PROT_SSL) {
if (conn->handler->flags & PROTOPT_SSL) {
CURLcode res;
if (data->state.used_interface == Curl_if_easy) {
res = Curl_ssl_connect(conn, FIRSTSOCKET);
@ -260,7 +262,7 @@ static CURLcode ldap_connecting(struct connectdata *conn, bool *done)
char *info = NULL;
#ifdef USE_SSL
if (conn->protocol & PROT_SSL) {
if (conn->handler->flags & PROTOPT_SSL) {
/* Is the SSL handshake complete yet? */
if (!li->ssldone) {
CURLcode res = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &li->ssldone);

Просмотреть файл

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2011, 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
@ -128,7 +128,8 @@ const struct Curl_handler Curl_handler_pop3 = {
ZERO_NULL, /* perform_getsock */
pop3_disconnect, /* disconnect */
PORT_POP3, /* defport */
PROT_POP3 /* protocol */
PROT_POP3, /* protocol */
PROTOPT_CLOSEACTION /* flags */
};
@ -151,7 +152,8 @@ const struct Curl_handler Curl_handler_pop3s = {
ZERO_NULL, /* perform_getsock */
pop3_disconnect, /* disconnect */
PORT_POP3S, /* defport */
PROT_POP3 | PROT_POP3S | PROT_SSL /* protocol */
PROT_POP3 | PROT_POP3S, /* protocol */
PROTOPT_CLOSEACTION | PROTOPT_SSL /* flags */
};
#endif
@ -174,7 +176,8 @@ static const struct Curl_handler Curl_handler_pop3_proxy = {
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
PORT_POP3, /* defport */
PROT_HTTP /* protocol */
PROT_HTTP, /* protocol */
PROTOPT_NONE /* flags */
};
@ -197,7 +200,8 @@ static const struct Curl_handler Curl_handler_pop3s_proxy = {
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
PORT_POP3S, /* defport */
PROT_HTTP /* protocol */
PROT_HTTP, /* protocol */
PROTOPT_NONE /* flags */
};
#endif
#endif
@ -288,7 +292,7 @@ static CURLcode pop3_state_starttls_resp(struct connectdata *conn,
/* Curl_ssl_connect is BLOCKING */
result = Curl_ssl_connect(conn, FIRSTSOCKET);
if(CURLE_OK == result) {
conn->protocol |= PROT_POP3S;
conn->handler = &Curl_handler_pop3s;
result = pop3_state_user(conn);
}
}
@ -637,7 +641,7 @@ static CURLcode pop3_connect(struct connectdata *conn,
}
#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_PROXY */
if(conn->protocol & PROT_POP3S) {
if(conn->handler->protocol & PROT_POP3S) {
/* BLOCKING */
/* POP3S is simply pop3 with SSL for the control channel */
/* now, perform the SSL initialization for this socket */

Просмотреть файл

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2011, 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
@ -97,6 +97,7 @@ const struct Curl_handler Curl_handler_rtsp = {
Curl_rtsp_disconnect, /* disconnect */
PORT_RTSP, /* defport */
PROT_RTSP, /* protocol */
PROTOPT_NONE /* flags */
};
CURLcode Curl_rtsp_connect(struct connectdata *conn, bool *done)

Просмотреть файл

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2011, 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
@ -441,7 +441,8 @@ CURLcode Curl_client_write(struct connectdata *conn,
}
if(type & CLIENTWRITE_BODY) {
if((conn->protocol&PROT_FTP) && conn->proto.ftpc.transfertype == 'A') {
if((conn->handler->protocol&PROT_FTP) &&
conn->proto.ftpc.transfertype == 'A') {
#ifdef CURL_DOES_CONVERSIONS
/* convert from the network encoding */
size_t rc;

Просмотреть файл

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2011, 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
@ -135,7 +135,8 @@ const struct Curl_handler Curl_handler_smtp = {
ZERO_NULL, /* perform_getsock */
smtp_disconnect, /* disconnect */
PORT_SMTP, /* defport */
PROT_SMTP /* protocol */
PROT_SMTP, /* protocol */
PROTOPT_CLOSEACTION /* flags */
};
@ -158,7 +159,8 @@ const struct Curl_handler Curl_handler_smtps = {
ZERO_NULL, /* perform_getsock */
smtp_disconnect, /* disconnect */
PORT_SMTPS, /* defport */
PROT_SMTP | PROT_SMTPS | PROT_SSL /* protocol */
PROT_SMTP | PROT_SMTPS, /* protocol */
PROTOPT_CLOSEACTION | PROTOPT_SSL /* flags */
};
#endif
@ -181,7 +183,8 @@ static const struct Curl_handler Curl_handler_smtp_proxy = {
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
PORT_SMTP, /* defport */
PROT_HTTP /* protocol */
PROT_HTTP, /* protocol */
PROTOPT_NONE /* flags */
};
@ -204,7 +207,8 @@ static const struct Curl_handler Curl_handler_smtps_proxy = {
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
PORT_SMTPS, /* defport */
PROT_HTTP /* protocol */
PROT_HTTP, /* protocol */
PROTOPT_NONE /* flags */
};
#endif
#endif
@ -471,7 +475,7 @@ static CURLcode smtp_state_starttls_resp(struct connectdata *conn,
/* Curl_ssl_connect is BLOCKING */
result = Curl_ssl_connect(conn, FIRSTSOCKET);
if(CURLE_OK == result) {
conn->protocol |= PROT_SMTPS;
conn->handler = &Curl_handler_smtps;
result = smtp_state_ehlo(conn);
}
}
@ -1101,7 +1105,7 @@ static CURLcode smtp_connect(struct connectdata *conn,
}
#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_PROXY */
if(conn->protocol & PROT_SMTPS) {
if(conn->handler->protocol & PROT_SMTPS) {
/* BLOCKING */
/* SMTPS is simply smtp with SSL for the control channel */
/* now, perform the SSL initialization for this socket */

Просмотреть файл

@ -175,7 +175,8 @@ const struct Curl_handler Curl_handler_scp = {
ssh_perform_getsock, /* perform_getsock */
scp_disconnect, /* disconnect */
PORT_SSH, /* defport */
PROT_SCP /* protocol */
PROT_SCP, /* protocol */
PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION /* flags */
};
@ -197,7 +198,8 @@ const struct Curl_handler Curl_handler_sftp = {
ssh_perform_getsock, /* perform_getsock */
sftp_disconnect, /* disconnect */
PORT_SSH, /* defport */
PROT_SFTP /* protocol */
PROT_SFTP, /* protocol */
PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION /* flags */
};
@ -411,7 +413,7 @@ static CURLcode ssh_getworkingpath(struct connectdata *conn,
return CURLE_OUT_OF_MEMORY;
/* Check for /~/ , indicating relative to the user's home directory */
if(conn->protocol & PROT_SCP) {
if(conn->handler->protocol & PROT_SCP) {
real_path = malloc(working_path_len+1);
if(real_path == NULL) {
free(working_path);
@ -423,7 +425,7 @@ static CURLcode ssh_getworkingpath(struct connectdata *conn,
else
memcpy(real_path, working_path, 1 + working_path_len);
}
else if(conn->protocol & PROT_SFTP) {
else if(conn->handler->protocol & PROT_SFTP) {
if((working_path_len > 1) && (working_path[1] == '~')) {
size_t homelen = strlen(homedir);
real_path = malloc(homelen + working_path_len + 1);
@ -931,7 +933,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
conn->sockfd = sock;
conn->writesockfd = CURL_SOCKET_BAD;
if(conn->protocol == PROT_SFTP) {
if(conn->handler->protocol == PROT_SFTP) {
state(conn, SSH_SFTP_INIT);
break;
}
@ -2566,7 +2568,7 @@ static CURLcode ssh_connect(struct connectdata *conn, bool *done)
if(result)
return result;
if(conn->protocol & PROT_SCP) {
if(conn->handler->protocol & PROT_SCP) {
conn->recv[FIRSTSOCKET] = scp_recv;
conn->send[FIRSTSOCKET] = scp_send;
} else {
@ -2715,7 +2717,7 @@ static CURLcode ssh_do(struct connectdata *conn, bool *done)
Curl_pgrsSetUploadSize(data, 0);
Curl_pgrsSetDownloadSize(data, 0);
if(conn->protocol & PROT_SCP)
if(conn->handler->protocol & PROT_SCP)
res = scp_perform(conn, &connected, done);
else
res = sftp_perform(conn, &connected, done);

Просмотреть файл

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2011, 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
@ -196,7 +196,8 @@ const struct Curl_handler Curl_handler_telnet = {
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
PORT_TELNET, /* defport */
PROT_TELNET /* protocol */
PROT_TELNET, /* protocol */
PROTOPT_NONE /* flags */
};

Просмотреть файл

@ -196,7 +196,8 @@ const struct Curl_handler Curl_handler_tftp = {
ZERO_NULL, /* perform_getsock */
tftp_disconnect, /* disconnect */
PORT_TFTP, /* defport */
PROT_TFTP /* protocol */
PROT_TFTP, /* protocol */
PROTOPT_NONE /* flags */
};
/**********************************************************

Просмотреть файл

@ -322,7 +322,7 @@ static int data_pending(const struct connectdata *conn)
{
/* in the case of libssh2, we can never be really sure that we have emptied
its internal buffers so we MUST always try until we get EAGAIN back */
return conn->protocol&(PROT_SCP|PROT_SFTP) ||
return conn->handler->protocol&(PROT_SCP|PROT_SFTP) ||
Curl_ssl_data_pending(conn, FIRSTSOCKET);
}
@ -469,7 +469,7 @@ static CURLcode readwrite_data(struct SessionHandle *data,
#ifndef CURL_DISABLE_RTSP
/* Check for RTP at the beginning of the data */
if(conn->protocol & PROT_RTSP) {
if(conn->handler->protocol & PROT_RTSP) {
result = Curl_rtsp_rtp_readwrite(data, conn, &nread, &readmore);
if(result)
return result;
@ -490,7 +490,8 @@ static CURLcode readwrite_data(struct SessionHandle *data,
#ifndef CURL_DISABLE_RTSP
/* Check for RTP after the headers if there is no Content */
if(k->maxdownload <= 0 && nread > 0 && (conn->protocol & PROT_RTSP)) {
if(k->maxdownload <= 0 && nread > 0 &&
(conn->handler->protocol & PROT_RTSP)) {
result = Curl_rtsp_rtp_readwrite(data, conn, &nread, &readmore);
if(result)
return result;
@ -516,7 +517,7 @@ static CURLcode readwrite_data(struct SessionHandle *data,
if(0 == k->bodywrites && !is_empty_data) {
/* These checks are only made the first time we are about to
write a piece of the body */
if(conn->protocol&(PROT_HTTP|PROT_RTSP)) {
if(conn->handler->protocol&(PROT_HTTP|PROT_RTSP)) {
/* HTTP-only checks */
if(data->req.newurl) {
@ -703,7 +704,7 @@ static CURLcode readwrite_data(struct SessionHandle *data,
if(!k->ignorebody) {
#ifndef CURL_DISABLE_POP3
if(conn->protocol&PROT_POP3)
if(conn->handler->protocol&PROT_POP3)
result = Curl_pop3_write(conn, k->str, nread);
else
#endif /* CURL_DISABLE_POP3 */
@ -746,7 +747,7 @@ static CURLcode readwrite_data(struct SessionHandle *data,
#ifndef CURL_DISABLE_RTSP
if(excess > 0 && !conn->bits.stream_was_rewound &&
(conn->protocol & PROT_RTSP)) {
(conn->handler->protocol & PROT_RTSP)) {
/* Check for RTP after the content if there is unrewound excess */
/* Parse the excess data */
@ -834,7 +835,7 @@ static CURLcode readwrite_upload(struct SessionHandle *data,
break;
}
if(conn->protocol&(PROT_HTTP|PROT_RTSP)) {
if(conn->handler->protocol&(PROT_HTTP|PROT_RTSP)) {
if(data->state.proto.http->sending == HTTPSEND_REQUEST)
/* We're sending the HTTP request headers, not the data.
Remember that so we don't change the line endings. */
@ -872,7 +873,7 @@ static CURLcode readwrite_upload(struct SessionHandle *data,
data->req.upload_present = nread;
#ifndef CURL_DISABLE_SMTP
if(conn->protocol & PROT_SMTP) {
if(conn->handler->protocol & PROT_SMTP) {
result = Curl_smtp_escape_eob(conn, nread);
if(result)
return result;
@ -2059,7 +2060,7 @@ CURLcode Curl_retry_request(struct connectdata *conn,
/* if we're talking upload, we can't do the checks below, unless the protocol
is HTTP as when uploading over HTTP we will still get a response */
if(data->set.upload && !(conn->protocol&(PROT_HTTP|PROT_RTSP)))
if(data->set.upload && !(conn->handler->protocol&(PROT_HTTP|PROT_RTSP)))
return CURLE_OK;
if(/* workaround for broken TLS servers */ data->state.ssl_connect_retry ||

Просмотреть файл

@ -263,7 +263,8 @@ static const struct Curl_handler Curl_handler_dummy = {
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
0, /* defport */
0 /* protocol */
0, /* protocol */
0 /* flags */
};
void Curl_safefree(void *ptr)
@ -765,9 +766,9 @@ CURLcode Curl_init_userdefined(struct UserDefined *set)
/* for the *protocols fields we don't use the CURLPROTO_ALL convenience
define since we internally only use the lower 16 bits for the passed
in bitmask to not conflict with the private bits */
set->allowed_protocols = PROT_EXTMASK;
set->allowed_protocols = PROT_ALL;
set->redir_protocols =
PROT_EXTMASK & ~(CURLPROTO_FILE|CURLPROTO_SCP); /* not FILE or SCP */
PROT_ALL & ~(CURLPROTO_FILE|CURLPROTO_SCP); /* not FILE or SCP */
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
/*
@ -2382,7 +2383,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
transfer, which thus helps the app which takes URLs from users or other
external inputs and want to restrict what protocol(s) to deal
with. Defaults to CURLPROTO_ALL. */
data->set.allowed_protocols = va_arg(param, long) & PROT_EXTMASK;
data->set.allowed_protocols = va_arg(param, long);
break;
case CURLOPT_REDIR_PROTOCOLS:
@ -2390,7 +2391,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
to be set in both bitmasks to be allowed to get redirected to. Defaults
to all protocols except FILE and SCP. */
data->set.redir_protocols = va_arg(param, long) & PROT_EXTMASK;
data->set.redir_protocols = va_arg(param, long);
break;
case CURLOPT_MAIL_FROM:
@ -2931,7 +2932,7 @@ ConnectionExists(struct SessionHandle *data,
use */
bool dead;
#ifndef CURL_DISABLE_RTSP
if(check->protocol & PROT_RTSP)
if(check->handler->protocol & PROT_RTSP)
/* RTSP is a special case due to RTP interleaving */
dead = RTSPConnIsDead(check);
else
@ -3003,11 +3004,12 @@ ConnectionExists(struct SessionHandle *data,
}
}
if((needle->protocol&PROT_SSL) != (check->protocol&PROT_SSL))
if((needle->handler->flags&PROTOPT_SSL) !=
(check->handler->flags&PROTOPT_SSL))
/* don't do mixed SSL and non-SSL connections */
continue;
if(needle->protocol&PROT_SSL) {
if(needle->handler->flags&PROTOPT_SSL) {
if((data->set.ssl.verifypeer != check->verifypeer) ||
(data->set.ssl.verifyhost != check->verifyhost))
continue;
@ -3022,7 +3024,7 @@ ConnectionExists(struct SessionHandle *data,
in use so we skip it */
continue;
if(!needle->bits.httpproxy || needle->protocol&PROT_SSL ||
if(!needle->bits.httpproxy || needle->handler->flags&PROTOPT_SSL ||
(needle->bits.httpproxy && check->bits.httpproxy &&
needle->bits.tunnel_proxy && check->bits.tunnel_proxy &&
Curl_raw_equal(needle->proxy.name, check->proxy.name) &&
@ -3034,7 +3036,7 @@ ConnectionExists(struct SessionHandle *data,
if(Curl_raw_equal(needle->handler->scheme, check->handler->scheme) &&
Curl_raw_equal(needle->host.name, check->host.name) &&
(needle->remote_port == check->remote_port) ) {
if(needle->protocol & PROT_SSL) {
if(needle->handler->flags & PROTOPT_SSL) {
/* This is SSL, verify that we're using the same
ssl options as well */
if(!Curl_ssl_config_matches(&needle->ssl_config,
@ -3053,8 +3055,8 @@ ConnectionExists(struct SessionHandle *data,
continue;
}
}
if((needle->protocol & PROT_FTP) ||
((needle->protocol & PROT_HTTP) &&
if((needle->handler->protocol & PROT_FTP) ||
((needle->handler->protocol & PROT_HTTP) &&
(data->state.authhost.want==CURLAUTH_NTLM))) {
/* This is FTP or HTTP+NTLM, verify that we're using the same name
and password as well */
@ -3639,8 +3641,7 @@ static CURLcode findprotocol(struct SessionHandle *data,
break;
/* Perform setup complement if some. */
conn->handler = p;
conn->protocol |= p->protocol;
conn->handler = conn->given = p;
/* 'port' and 'remote_port' are set in setup_connection_internals() */
return CURLE_OK;
@ -3938,8 +3939,7 @@ 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)p->defport;
conn->protocol |= p->protocol;
conn->remote_port = (unsigned short)conn->given->defport;
return CURLE_OK;
}
@ -4418,7 +4418,7 @@ static CURLcode parse_remote_port(struct SessionHandle *data,
* stripped off. It would be better to work directly from the original
* URL and simply replace the port part of it.
*/
url = aprintf("%s://%s%s%s:%hu%s%s%s", conn->handler->scheme,
url = aprintf("%s://%s%s%s:%hu%s%s%s", conn->given->scheme,
conn->bits.ipv6_ip?"[":"", conn->host.name,
conn->bits.ipv6_ip?"]":"", conn->remote_port,
data->state.slash_removed?"/":"", data->state.path,
@ -4507,7 +4507,7 @@ static CURLcode set_userpass(struct connectdata *conn,
const char *user, const char *passwd)
{
/* If our protocol needs a password and we have none, use the defaults */
if( (conn->protocol & (PROT_FTP|PROT_IMAP)) &&
if( (conn->handler->protocol & (PROT_FTP|PROT_IMAP)) &&
!conn->bits.user_passwd) {
conn->user = strdup(CURL_DEFAULT_USER);
@ -4829,13 +4829,11 @@ static CURLcode create_conn(struct SessionHandle *data,
proxy = NULL;
}
/* proxy must be freed later unless NULL */
if(proxy) {
long bits = conn->protocol & (PROT_HTTPS|PROT_SSL);
if(proxy && !(conn->handler->flags & PROTOPT_BANPROXY)) {
if((conn->proxytype == CURLPROXY_HTTP) ||
(conn->proxytype == CURLPROXY_HTTP_1_0)) {
/* force this connection's protocol to become HTTP */
conn->protocol = PROT_HTTP | bits;
conn->handler = &Curl_handler_http;
conn->bits.httpproxy = TRUE;
}
conn->bits.proxy = TRUE;
@ -4881,7 +4879,7 @@ static CURLcode create_conn(struct SessionHandle *data,
* file: is a special case in that it doesn't need a network connection
***********************************************************************/
#ifndef CURL_DISABLE_FILE
if(conn->protocol & PROT_FILE) {
if(conn->handler->protocol & PROT_FILE) {
bool done;
/* this is supposed to be the connect function so we better at least check
that the file is present here! */
@ -4918,7 +4916,7 @@ static CURLcode create_conn(struct SessionHandle *data,
* If the protocol is using SSL and HTTP proxy is used, we set
* the tunnel_proxy bit.
*************************************************************/
if((conn->protocol&PROT_SSL) && conn->bits.httpproxy)
if((conn->given->flags&PROTOPT_SSL) && conn->bits.httpproxy)
conn->bits.tunnel_proxy = TRUE;
/*************************************************************
@ -5041,7 +5039,7 @@ static CURLcode setup_conn(struct connectdata *conn,
Curl_pgrsTime(data, TIMER_NAMELOOKUP);
if(conn->protocol & PROT_FILE) {
if(conn->handler->protocol & PROT_FILE) {
/* There's nothing in this function to setup if we're only doing
a file:// transfer */
*protocol_done = TRUE;

Просмотреть файл

@ -695,7 +695,8 @@ struct Curl_handler {
CURLcode (*disconnect)(struct connectdata *, bool dead_connection);
long defport; /* Default port. */
long protocol; /* PROT_* flags concerning the protocol set */
unsigned int protocol; /* PROT_* flags concerning the protocol set */
unsigned int flags; /* Extra particular characteristics, see PROTOPT_* */
};
/* return the count of bytes sent, or -1 on error */
@ -735,7 +736,7 @@ struct connectdata {
/**** Fields set when inited and not modified again */
long connectindex; /* what index in the connection cache connects index this
particular struct has */
long protocol; /* PROT_* flags concerning the protocol set */
#define PROT_HTTP CURLPROTO_HTTP
#define PROT_HTTPS CURLPROTO_HTTPS
#define PROT_FTP CURLPROTO_FTP
@ -762,24 +763,18 @@ struct connectdata {
#define PROT_RTMPTS CURLPROTO_RTMPTS
#define PROT_GOPHER CURLPROTO_GOPHER
/* (1<<25) is currently the highest used bit in the public bitmask. We make
sure we use "private bits" above the public ones to make things easier;
Gopher will not conflict with the current bit 25. */
#define PROT_EXTMASK 0x03ffffff
#define PROT_SSL (1<<29) /* protocol requires SSL */
/* these ones need action before socket close */
#define PROT_CLOSEACTION (PROT_FTP | PROT_IMAP | PROT_POP3 | \
PROT_SFTP | PROT_SCP)
#define PROT_DUALCHANNEL PROT_FTP /* these protocols use two connections */
#define PROT_ALL ~0
#define PROTOPT_NONE 0 /* nothing extra */
#define PROTOPT_SSL (1<<0) /* uses SSL */
#define PROTOPT_DUAL (1<<1) /* this protocol uses two connections */
#define PROTOPT_CLOSEACTION (1<<2) /* need action before socket close */
/* some protocols will have to call the underlying functions without regard to
what exact state the socket signals. IE even if the socket says "readable",
the send function might need to be called while uploading, or vice versa.
*/
#define PROT_LOCKEDBITS (PROT_SCP | PROT_SFTP)
#define PROTOPT_DIRLOCK (1<<3)
#define PROTOPT_BANPROXY (1<<4) /* not allowed to use proxy */
/* 'dns_entry' is the particular host we use. This points to an entry in the
DNS cache and it will not get pruned while locked. It gets unlocked in
@ -857,7 +852,8 @@ struct connectdata {
long timeoutms_per_addr; /* how long time in milliseconds to spend on
trying to connect to each IP address */
const struct Curl_handler * handler; /* Connection's protocol handler. */
const struct Curl_handler *handler; /* Connection's protocol handler */
const struct Curl_handler *given; /* The protocol first given */
long ip_version; /* copied from the SessionHandle at creation time */