1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-22 08:08:50 -05:00

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
parent ed8749e308
commit 8831000bc0
19 changed files with 166 additions and 132 deletions

View File

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

View File

@ -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 * 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
@ -108,7 +108,8 @@ const struct Curl_handler Curl_handler_dict = {
ZERO_NULL, /* perform_getsock */ ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */ ZERO_NULL, /* disconnect */
PORT_DICT, /* defport */ PORT_DICT, /* defport */
PROT_DICT /* protocol */ PROT_DICT, /* protocol */
PROTOPT_NONE /* flags */
}; };
static char *unescape_word(struct SessionHandle *data, const char *inputbuff) static char *unescape_word(struct SessionHandle *data, const char *inputbuff)

View File

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

View File

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

View File

@ -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 * 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
@ -113,7 +113,8 @@ const struct Curl_handler Curl_handler_gopher = {
ZERO_NULL, /* perform_getsock */ ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */ ZERO_NULL, /* disconnect */
PORT_GOPHER, /* defport */ PORT_GOPHER, /* defport */
PROT_GOPHER /* protocol */ PROT_GOPHER, /* protocol */
PROTOPT_NONE /* flags */
}; };
static CURLcode gopher_do(struct connectdata *conn, bool *done) static CURLcode gopher_do(struct connectdata *conn, bool *done)

View File

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

View File

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

View File

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

View File

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

View File

@ -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 * 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
@ -128,7 +128,8 @@ const struct Curl_handler Curl_handler_pop3 = {
ZERO_NULL, /* perform_getsock */ ZERO_NULL, /* perform_getsock */
pop3_disconnect, /* disconnect */ pop3_disconnect, /* disconnect */
PORT_POP3, /* defport */ 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 */ ZERO_NULL, /* perform_getsock */
pop3_disconnect, /* disconnect */ pop3_disconnect, /* disconnect */
PORT_POP3S, /* defport */ PORT_POP3S, /* defport */
PROT_POP3 | PROT_POP3S | PROT_SSL /* protocol */ PROT_POP3 | PROT_POP3S, /* protocol */
PROTOPT_CLOSEACTION | PROTOPT_SSL /* flags */
}; };
#endif #endif
@ -174,7 +176,8 @@ static const struct Curl_handler Curl_handler_pop3_proxy = {
ZERO_NULL, /* perform_getsock */ ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */ ZERO_NULL, /* disconnect */
PORT_POP3, /* defport */ 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, /* perform_getsock */
ZERO_NULL, /* disconnect */ ZERO_NULL, /* disconnect */
PORT_POP3S, /* defport */ PORT_POP3S, /* defport */
PROT_HTTP /* protocol */ PROT_HTTP, /* protocol */
PROTOPT_NONE /* flags */
}; };
#endif #endif
#endif #endif
@ -288,7 +292,7 @@ static CURLcode pop3_state_starttls_resp(struct connectdata *conn,
/* Curl_ssl_connect is BLOCKING */ /* Curl_ssl_connect is BLOCKING */
result = Curl_ssl_connect(conn, FIRSTSOCKET); result = Curl_ssl_connect(conn, FIRSTSOCKET);
if(CURLE_OK == result) { if(CURLE_OK == result) {
conn->protocol |= PROT_POP3S; conn->handler = &Curl_handler_pop3s;
result = pop3_state_user(conn); result = pop3_state_user(conn);
} }
} }
@ -637,7 +641,7 @@ static CURLcode pop3_connect(struct connectdata *conn,
} }
#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_PROXY */ #endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_PROXY */
if(conn->protocol & PROT_POP3S) { if(conn->handler->protocol & PROT_POP3S) {
/* BLOCKING */ /* BLOCKING */
/* POP3S is simply pop3 with SSL for the control channel */ /* POP3S is simply pop3 with SSL for the control channel */
/* now, perform the SSL initialization for this socket */ /* now, perform the SSL initialization for this socket */

View File

@ -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 * 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
@ -97,6 +97,7 @@ const struct Curl_handler Curl_handler_rtsp = {
Curl_rtsp_disconnect, /* disconnect */ Curl_rtsp_disconnect, /* disconnect */
PORT_RTSP, /* defport */ PORT_RTSP, /* defport */
PROT_RTSP, /* protocol */ PROT_RTSP, /* protocol */
PROTOPT_NONE /* flags */
}; };
CURLcode Curl_rtsp_connect(struct connectdata *conn, bool *done) CURLcode Curl_rtsp_connect(struct connectdata *conn, bool *done)

View File

@ -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 * 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
@ -441,7 +441,8 @@ CURLcode Curl_client_write(struct connectdata *conn,
} }
if(type & CLIENTWRITE_BODY) { 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 #ifdef CURL_DOES_CONVERSIONS
/* convert from the network encoding */ /* convert from the network encoding */
size_t rc; size_t rc;

View File

@ -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 * 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
@ -135,7 +135,8 @@ const struct Curl_handler Curl_handler_smtp = {
ZERO_NULL, /* perform_getsock */ ZERO_NULL, /* perform_getsock */
smtp_disconnect, /* disconnect */ smtp_disconnect, /* disconnect */
PORT_SMTP, /* defport */ 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 */ ZERO_NULL, /* perform_getsock */
smtp_disconnect, /* disconnect */ smtp_disconnect, /* disconnect */
PORT_SMTPS, /* defport */ PORT_SMTPS, /* defport */
PROT_SMTP | PROT_SMTPS | PROT_SSL /* protocol */ PROT_SMTP | PROT_SMTPS, /* protocol */
PROTOPT_CLOSEACTION | PROTOPT_SSL /* flags */
}; };
#endif #endif
@ -181,7 +183,8 @@ static const struct Curl_handler Curl_handler_smtp_proxy = {
ZERO_NULL, /* perform_getsock */ ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */ ZERO_NULL, /* disconnect */
PORT_SMTP, /* defport */ 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, /* perform_getsock */
ZERO_NULL, /* disconnect */ ZERO_NULL, /* disconnect */
PORT_SMTPS, /* defport */ PORT_SMTPS, /* defport */
PROT_HTTP /* protocol */ PROT_HTTP, /* protocol */
PROTOPT_NONE /* flags */
}; };
#endif #endif
#endif #endif
@ -471,7 +475,7 @@ static CURLcode smtp_state_starttls_resp(struct connectdata *conn,
/* Curl_ssl_connect is BLOCKING */ /* Curl_ssl_connect is BLOCKING */
result = Curl_ssl_connect(conn, FIRSTSOCKET); result = Curl_ssl_connect(conn, FIRSTSOCKET);
if(CURLE_OK == result) { if(CURLE_OK == result) {
conn->protocol |= PROT_SMTPS; conn->handler = &Curl_handler_smtps;
result = smtp_state_ehlo(conn); result = smtp_state_ehlo(conn);
} }
} }
@ -1101,7 +1105,7 @@ static CURLcode smtp_connect(struct connectdata *conn,
} }
#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_PROXY */ #endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_PROXY */
if(conn->protocol & PROT_SMTPS) { if(conn->handler->protocol & PROT_SMTPS) {
/* BLOCKING */ /* BLOCKING */
/* SMTPS is simply smtp with SSL for the control channel */ /* SMTPS is simply smtp with SSL for the control channel */
/* now, perform the SSL initialization for this socket */ /* now, perform the SSL initialization for this socket */

View File

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

View File

@ -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 * 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
@ -196,7 +196,8 @@ const struct Curl_handler Curl_handler_telnet = {
ZERO_NULL, /* perform_getsock */ ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */ ZERO_NULL, /* disconnect */
PORT_TELNET, /* defport */ PORT_TELNET, /* defport */
PROT_TELNET /* protocol */ PROT_TELNET, /* protocol */
PROTOPT_NONE /* flags */
}; };

View File

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

View File

@ -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 /* 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 */ 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); Curl_ssl_data_pending(conn, FIRSTSOCKET);
} }
@ -469,7 +469,7 @@ static CURLcode readwrite_data(struct SessionHandle *data,
#ifndef CURL_DISABLE_RTSP #ifndef CURL_DISABLE_RTSP
/* Check for RTP at the beginning of the data */ /* 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); result = Curl_rtsp_rtp_readwrite(data, conn, &nread, &readmore);
if(result) if(result)
return result; return result;
@ -490,7 +490,8 @@ static CURLcode readwrite_data(struct SessionHandle *data,
#ifndef CURL_DISABLE_RTSP #ifndef CURL_DISABLE_RTSP
/* Check for RTP after the headers if there is no Content */ /* 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); result = Curl_rtsp_rtp_readwrite(data, conn, &nread, &readmore);
if(result) if(result)
return result; return result;
@ -516,7 +517,7 @@ static CURLcode readwrite_data(struct SessionHandle *data,
if(0 == k->bodywrites && !is_empty_data) { if(0 == k->bodywrites && !is_empty_data) {
/* These checks are only made the first time we are about to /* These checks are only made the first time we are about to
write a piece of the body */ write a piece of the body */
if(conn->protocol&(PROT_HTTP|PROT_RTSP)) { if(conn->handler->protocol&(PROT_HTTP|PROT_RTSP)) {
/* HTTP-only checks */ /* HTTP-only checks */
if(data->req.newurl) { if(data->req.newurl) {
@ -703,7 +704,7 @@ static CURLcode readwrite_data(struct SessionHandle *data,
if(!k->ignorebody) { if(!k->ignorebody) {
#ifndef CURL_DISABLE_POP3 #ifndef CURL_DISABLE_POP3
if(conn->protocol&PROT_POP3) if(conn->handler->protocol&PROT_POP3)
result = Curl_pop3_write(conn, k->str, nread); result = Curl_pop3_write(conn, k->str, nread);
else else
#endif /* CURL_DISABLE_POP3 */ #endif /* CURL_DISABLE_POP3 */
@ -746,7 +747,7 @@ static CURLcode readwrite_data(struct SessionHandle *data,
#ifndef CURL_DISABLE_RTSP #ifndef CURL_DISABLE_RTSP
if(excess > 0 && !conn->bits.stream_was_rewound && 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 */ /* Check for RTP after the content if there is unrewound excess */
/* Parse the excess data */ /* Parse the excess data */
@ -834,7 +835,7 @@ static CURLcode readwrite_upload(struct SessionHandle *data,
break; break;
} }
if(conn->protocol&(PROT_HTTP|PROT_RTSP)) { if(conn->handler->protocol&(PROT_HTTP|PROT_RTSP)) {
if(data->state.proto.http->sending == HTTPSEND_REQUEST) if(data->state.proto.http->sending == HTTPSEND_REQUEST)
/* We're sending the HTTP request headers, not the data. /* We're sending the HTTP request headers, not the data.
Remember that so we don't change the line endings. */ 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; data->req.upload_present = nread;
#ifndef CURL_DISABLE_SMTP #ifndef CURL_DISABLE_SMTP
if(conn->protocol & PROT_SMTP) { if(conn->handler->protocol & PROT_SMTP) {
result = Curl_smtp_escape_eob(conn, nread); result = Curl_smtp_escape_eob(conn, nread);
if(result) if(result)
return 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 /* 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 */ 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; return CURLE_OK;
if(/* workaround for broken TLS servers */ data->state.ssl_connect_retry || if(/* workaround for broken TLS servers */ data->state.ssl_connect_retry ||

View File

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

View File

@ -695,7 +695,8 @@ struct Curl_handler {
CURLcode (*disconnect)(struct connectdata *, bool dead_connection); CURLcode (*disconnect)(struct connectdata *, bool dead_connection);
long defport; /* Default port. */ 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 */ /* return the count of bytes sent, or -1 on error */
@ -735,7 +736,7 @@ struct connectdata {
/**** Fields set when inited and not modified again */ /**** Fields set when inited and not modified again */
long connectindex; /* what index in the connection cache connects index this long connectindex; /* what index in the connection cache connects index this
particular struct has */ particular struct has */
long protocol; /* PROT_* flags concerning the protocol set */
#define PROT_HTTP CURLPROTO_HTTP #define PROT_HTTP CURLPROTO_HTTP
#define PROT_HTTPS CURLPROTO_HTTPS #define PROT_HTTPS CURLPROTO_HTTPS
#define PROT_FTP CURLPROTO_FTP #define PROT_FTP CURLPROTO_FTP
@ -762,24 +763,18 @@ struct connectdata {
#define PROT_RTMPTS CURLPROTO_RTMPTS #define PROT_RTMPTS CURLPROTO_RTMPTS
#define PROT_GOPHER CURLPROTO_GOPHER #define PROT_GOPHER CURLPROTO_GOPHER
/* (1<<25) is currently the highest used bit in the public bitmask. We make #define PROT_ALL ~0
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 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 /* 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", 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. 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_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 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 long timeoutms_per_addr; /* how long time in milliseconds to spend on
trying to connect to each IP address */ 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 */ long ip_version; /* copied from the SessionHandle at creation time */