handler: make 'protocol' always specified as a single bit

This makes the findprotocol() function work as intended so that libcurl
can properly be restricted to not support HTTP while still supporting
HTTPS - since the HTTPS handler previously set both the HTTP and HTTPS
bits in the protocol field.

This fixes --proto and --proto-redir for most SSL protocols.

This is done by adding a few new convenience defines that groups HTTP
and HTTPS, FTP and FTPS etc that should then be used when the code wants
to check for both protocols at once. PROTO_FAMILY_[protocol] style.

Bug: https://github.com/bagder/curl/pull/97
Reported-by: drizzt
This commit is contained in:
Daniel Stenberg 2014-04-20 19:37:54 +02:00
parent cf9342e275
commit 710f14edba
11 changed files with 35 additions and 26 deletions

View File

@ -208,7 +208,7 @@ const struct Curl_handler Curl_handler_ftps = {
ftp_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
PORT_FTPS, /* defport */
CURLPROTO_FTP | CURLPROTO_FTPS, /* protocol */
CURLPROTO_FTPS, /* protocol */
PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION |
PROTOPT_NEEDSPWD | PROTOPT_NOURLQUERY /* flags */
};

View File

@ -144,7 +144,7 @@ const struct Curl_handler Curl_handler_https = {
ZERO_NULL, /* disconnect */
ZERO_NULL, /* readwrite */
PORT_HTTPS, /* defport */
CURLPROTO_HTTP | CURLPROTO_HTTPS, /* protocol */
CURLPROTO_HTTPS, /* protocol */
PROTOPT_SSL | PROTOPT_CREDSPERREQUEST /* flags */
};
#endif
@ -1771,7 +1771,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
}
http->writebytecount = http->readbytecount = 0;
if((conn->handler->protocol&(CURLPROTO_HTTP|CURLPROTO_FTP)) &&
if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) &&
data->set.upload) {
httpreq = HTTPREQ_PUT;
}
@ -1883,7 +1883,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
}
else {
if((conn->handler->protocol&CURLPROTO_HTTP) &&
if((conn->handler->protocol&PROTO_FAMILY_HTTP) &&
data->set.upload &&
(data->set.infilesize == -1)) {
if(conn->bits.authneg)
@ -3190,7 +3190,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->handler->protocol & CURLPROTO_HTTP) {
if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
nc = sscanf(HEADER1,
" HTTP/%d.%d %3d",
&httpversion_major,

View File

@ -136,7 +136,7 @@ const struct Curl_handler Curl_handler_http2_ssl = {
http2_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
PORT_HTTP, /* defport */
CURLPROTO_HTTP | CURLPROTO_HTTPS, /* protocol */
CURLPROTO_HTTPS, /* protocol */
PROTOPT_SSL /* flags */
};

View File

@ -155,7 +155,7 @@ const struct Curl_handler Curl_handler_imaps = {
imap_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
PORT_IMAPS, /* defport */
CURLPROTO_IMAP | CURLPROTO_IMAPS, /* protocol */
CURLPROTO_IMAPS, /* protocol */
PROTOPT_CLOSEACTION | PROTOPT_SSL |
PROTOPT_NEEDSPWD /* flags */
};

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2014, 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
@ -159,7 +159,7 @@ const struct Curl_handler Curl_handler_ldaps = {
ZERO_NULL, /* disconnect */
ZERO_NULL, /* readwrite */
PORT_LDAPS, /* defport */
CURLPROTO_LDAP | CURLPROTO_LDAPS, /* protocol */
CURLPROTO_LDAPS, /* protocol */
PROTOPT_SSL /* flags */
};
#endif

View File

@ -156,7 +156,7 @@ const struct Curl_handler Curl_handler_pop3s = {
pop3_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
PORT_POP3S, /* defport */
CURLPROTO_POP3 | CURLPROTO_POP3S, /* protocol */
CURLPROTO_POP3S, /* protocol */
PROTOPT_CLOSEACTION | PROTOPT_SSL
| PROTOPT_NOURLQUERY /* flags */
};

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2014, 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
@ -422,7 +422,7 @@ CURLcode Curl_client_write(struct connectdata *conn,
}
if(type & CLIENTWRITE_BODY) {
if((conn->handler->protocol&CURLPROTO_FTP) &&
if((conn->handler->protocol&PROTO_FAMILY_FTP) &&
conn->proto.ftpc.transfertype == 'A') {
/* convert from the network encoding */
CURLcode rc = Curl_convert_from_network(data, ptr, len);

View File

@ -155,7 +155,7 @@ const struct Curl_handler Curl_handler_smtps = {
smtp_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
PORT_SMTPS, /* defport */
CURLPROTO_SMTP | CURLPROTO_SMTPS, /* protocol */
CURLPROTO_SMTPS, /* protocol */
PROTOPT_CLOSEACTION | PROTOPT_SSL
| PROTOPT_NOURLQUERY /* flags */
};

View File

@ -99,7 +99,7 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
#ifdef CURL_DOES_CONVERSIONS
bool sending_http_headers = FALSE;
if(conn->handler->protocol&(CURLPROTO_HTTP|CURLPROTO_RTSP)) {
if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) {
const struct HTTP *http = data->req.protop;
if(http->sending == HTTPSEND_REQUEST)
@ -319,7 +319,7 @@ static int data_pending(const struct connectdata *conn)
TRUE. The thing is if we read everything, then http2_recv won't
be called and we cannot signal the HTTP/2 stream has closed. As
a workaround, we return nonzero here to call http2_recv. */
((conn->handler->protocol&CURLPROTO_HTTP) && conn->httpversion == 20 &&
((conn->handler->protocol&PROTO_FAMILY_HTTP) && conn->httpversion == 20 &&
conn->proto.httpc.closed);
#else
Curl_ssl_data_pending(conn, FIRSTSOCKET);
@ -527,7 +527,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->handler->protocol&(CURLPROTO_HTTP|CURLPROTO_RTSP)) {
if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) {
/* HTTP-only checks */
if(data->req.newurl) {
@ -723,7 +723,7 @@ static CURLcode readwrite_data(struct SessionHandle *data,
if(!k->ignorebody) {
#ifndef CURL_DISABLE_POP3
if(conn->handler->protocol&CURLPROTO_POP3)
if(conn->handler->protocol&PROTO_FAMILY_POP3)
result = Curl_pop3_write(conn, k->str, nread);
else
#endif /* CURL_DISABLE_POP3 */
@ -854,7 +854,7 @@ static CURLcode readwrite_upload(struct SessionHandle *data,
break;
}
if(conn->handler->protocol&(CURLPROTO_HTTP|CURLPROTO_RTSP)) {
if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) {
if(http->sending == HTTPSEND_REQUEST)
/* We're sending the HTTP request headers, not the data.
Remember that so we don't change the line endings. */
@ -892,7 +892,7 @@ static CURLcode readwrite_upload(struct SessionHandle *data,
data->req.upload_present = nread;
#ifndef CURL_DISABLE_SMTP
if(conn->handler->protocol & CURLPROTO_SMTP) {
if(conn->handler->protocol & PROTO_FAMILY_SMTP) {
result = Curl_smtp_escape_eob(conn, nread);
if(result)
return result;
@ -1873,7 +1873,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->handler->protocol&(CURLPROTO_HTTP|CURLPROTO_RTSP)))
!(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)))
return CURLE_OK;
if(/* workaround for broken TLS servers */ data->state.ssl_connect_retry ||
@ -1899,7 +1899,7 @@ CURLcode Curl_retry_request(struct connectdata *conn,
transferred! */
if(conn->handler->protocol&CURLPROTO_HTTP) {
if(conn->handler->protocol&PROTO_FAMILY_HTTP) {
struct HTTP *http = data->req.protop;
if(http->writebytecount)
return Curl_readrewind(conn);
@ -1972,7 +1972,7 @@ Curl_setup_transfer(
state info where we wait for the 100-return code
*/
if((data->state.expect100header) &&
(conn->handler->protocol&CURLPROTO_HTTP) &&
(conn->handler->protocol&PROTO_FAMILY_HTTP) &&
(http->sending == HTTPSEND_BODY)) {
/* wait with write until we either got 100-continue or a timeout */
k->exp100 = EXP100_AWAITING_CONTINUE;

View File

@ -2703,7 +2703,7 @@ static bool SocketIsDead(curl_socket_t sock)
static bool IsPipeliningPossible(const struct SessionHandle *handle,
const struct connectdata *conn)
{
if((conn->handler->protocol & CURLPROTO_HTTP) &&
if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
Curl_multi_pipeline_enabled(handle->multi) &&
(handle->set.httpreq == HTTPREQ_GET ||
handle->set.httpreq == HTTPREQ_HEAD) &&
@ -2927,7 +2927,7 @@ ConnectionExists(struct SessionHandle *data,
bool canPipeline = IsPipeliningPossible(data, needle);
bool wantNTLMhttp = ((data->state.authhost.want & CURLAUTH_NTLM) ||
(data->state.authhost.want & CURLAUTH_NTLM_WB)) &&
(needle->handler->protocol & CURLPROTO_HTTP) ? TRUE : FALSE;
(needle->handler->protocol & PROTO_FAMILY_HTTP) ? TRUE : FALSE;
struct connectbundle *bundle;
*force_reuse = FALSE;
@ -5330,7 +5330,7 @@ static CURLcode create_conn(struct SessionHandle *data,
#else
/* force this connection's protocol to become HTTP if not already
compatible - if it isn't tunneling through */
if(!(conn->handler->protocol & CURLPROTO_HTTP) &&
if(!(conn->handler->protocol & PROTO_FAMILY_HTTP) &&
!conn->bits.tunnel_proxy)
conn->handler = &Curl_handler_http;

View File

@ -58,6 +58,14 @@
#define CURL_DEFAULT_USER "anonymous"
#define CURL_DEFAULT_PASSWORD "ftp@example.com"
/* Convenience defines for checking protocols or their SSL based version. Each
protocol handler should only ever have a single CURLPROTO_ in its protocol
field. */
#define PROTO_FAMILY_HTTP (CURLPROTO_HTTP|CURLPROTO_HTTPS)
#define PROTO_FAMILY_FTP (CURLPROTO_FTP|CURLPROTO_FTPS)
#define PROTO_FAMILY_POP3 (CURLPROTO_POP3|CURLPROTO_POP3S)
#define PROTO_FAMILY_SMTP (CURLPROTO_SMTP|CURLPROTO_SMTPS)
#define DEFAULT_CONNCACHE_SIZE 5
/* length of longest IPv6 address string including the trailing null */
@ -778,7 +786,8 @@ struct Curl_handler {
ssize_t *nread, bool *readmore);
long defport; /* Default port. */
unsigned int protocol; /* See CURLPROTO_* */
unsigned int protocol; /* See CURLPROTO_* - this needs to be the single
specific protocol bit */
unsigned int flags; /* Extra particular characteristics, see PROTOPT_* */
};