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 = {
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 = {
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 = {
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 = {
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 */
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)
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * 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
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)
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
0, /* defport */
- PROT_FILE /* protocol */
+ PROT_FILE, /* protocol */
+ PROTOPT_BANPROXY /* flags */
};
ZERO_NULL, /* perform_getsock */
ftp_disconnect, /* disconnect */
PORT_FTP, /* defport */
- PROT_FTP /* protocol */
+ PROT_FTP, /* protocol */
+ PROTOPT_DUAL | PROTOPT_CLOSEACTION /* flags */
};
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
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
PORT_FTP, /* defport */
- PROT_HTTP /* protocol */
+ PROT_HTTP, /* protocol */
+ PROTOPT_NONE /* flags */
};
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
PORT_FTPS, /* defport */
- PROT_HTTP /* protocol */
+ PROT_HTTP, /* protocol */
+ PROTOPT_NONE /* flags */
};
#endif
#endif
/* 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);
}
}
#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 */
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * 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
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)
ZERO_NULL, /* disconnect */
PORT_HTTP, /* defport */
PROT_HTTP, /* protocol */
+ PROTOPT_NONE /* flags */
};
#ifdef USE_SSL
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
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 */
}
#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
}
#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);
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);
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)
return CURLE_OUT_OF_MEMORY;
}
- if( (conn->protocol&(PROT_HTTP|PROT_FTP)) &&
- data->set.upload) {
+ if( (conn->handler->protocol&(PROT_HTTP|PROT_FTP)) &&
+ data->set.upload) {
httpreq = HTTPREQ_PUT;
}
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)
/* 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?"[":"",
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) {
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;
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
#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,
}
}
}
- else if(conn->protocol & PROT_RTSP) {
+ else if(conn->handler->protocol & PROT_RTSP) {
nc = sscanf(HEADER1,
" RTSP/%d.%d %3d",
&rtspversion_major,
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
}
}
#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;
ZERO_NULL, /* perform_getsock */
imap_disconnect, /* disconnect */
PORT_IMAP, /* defport */
- PROT_IMAP /* protocol */
+ PROT_IMAP, /* protocol */
+ PROTOPT_CLOSEACTION /* flags */
};
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
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
PORT_IMAP, /* defport */
- PROT_HTTP /* protocol */
+ PROT_HTTP, /* protocol */
+ PROTOPT_NONE /* flags */
};
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
PORT_IMAPS, /* defport */
- PROT_HTTP /* protocol */
+ PROT_HTTP, /* protocol */
+ PROTOPT_NONE /* flags */
};
#endif
#endif
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);
}
}
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);
}
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 {
}
#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 */
* 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);
/* 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;
}
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;
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;
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)
ZERO_NULL, /* perform_getsock */
ldap_disconnect, /* disconnect */
PORT_LDAP, /* defport */
- PROT_LDAP /* protocol */
+ PROT_LDAP, /* protocol */
+ PROTOPT_NONE /* flags */
};
#ifdef USE_SSL
ZERO_NULL, /* perform_getsock */
ldap_disconnect, /* disconnect */
PORT_LDAPS, /* defport */
- PROT_LDAP | PROT_SSL /* protocol */
+ PROT_LDAP, /* protocol */
+ PROTOPT_SSL /* flags */
};
#endif
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);
#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);
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);
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * 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
ZERO_NULL, /* perform_getsock */
pop3_disconnect, /* disconnect */
PORT_POP3, /* defport */
- PROT_POP3 /* protocol */
+ PROT_POP3, /* protocol */
+ PROTOPT_CLOSEACTION /* flags */
};
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
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
PORT_POP3, /* defport */
- PROT_HTTP /* protocol */
+ PROT_HTTP, /* protocol */
+ PROTOPT_NONE /* flags */
};
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
PORT_POP3S, /* defport */
- PROT_HTTP /* protocol */
+ PROT_HTTP, /* protocol */
+ PROTOPT_NONE /* flags */
};
#endif
#endif
/* 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);
}
}
}
#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 */
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * 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
Curl_rtsp_disconnect, /* disconnect */
PORT_RTSP, /* defport */
PROT_RTSP, /* protocol */
+ PROTOPT_NONE /* flags */
};
CURLcode Curl_rtsp_connect(struct connectdata *conn, bool *done)
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * 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
}
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;
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * 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
ZERO_NULL, /* perform_getsock */
smtp_disconnect, /* disconnect */
PORT_SMTP, /* defport */
- PROT_SMTP /* protocol */
+ PROT_SMTP, /* protocol */
+ PROTOPT_CLOSEACTION /* flags */
};
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
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
PORT_SMTP, /* defport */
- PROT_HTTP /* protocol */
+ PROT_HTTP, /* protocol */
+ PROTOPT_NONE /* flags */
};
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
PORT_SMTPS, /* defport */
- PROT_HTTP /* protocol */
+ PROT_HTTP, /* protocol */
+ PROTOPT_NONE /* flags */
};
#endif
#endif
/* 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);
}
}
}
#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 */
ssh_perform_getsock, /* perform_getsock */
scp_disconnect, /* disconnect */
PORT_SSH, /* defport */
- PROT_SCP /* protocol */
+ PROT_SCP, /* protocol */
+ PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION /* flags */
};
ssh_perform_getsock, /* perform_getsock */
sftp_disconnect, /* disconnect */
PORT_SSH, /* defport */
- PROT_SFTP /* protocol */
+ PROT_SFTP, /* protocol */
+ PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION /* flags */
};
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);
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);
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;
}
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 {
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);
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * 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
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
PORT_TELNET, /* defport */
- PROT_TELNET /* protocol */
+ PROT_TELNET, /* protocol */
+ PROTOPT_NONE /* flags */
};
ZERO_NULL, /* perform_getsock */
tftp_disconnect, /* disconnect */
PORT_TFTP, /* defport */
- PROT_TFTP /* protocol */
+ PROT_TFTP, /* protocol */
+ PROTOPT_NONE /* flags */
};
/**********************************************************
{
/* 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);
}
#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;
#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;
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) {
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 */
#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 */
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. */
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;
/* 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 ||
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
0, /* defport */
- 0 /* protocol */
+ 0, /* protocol */
+ 0 /* flags */
};
void Curl_safefree(void *ptr)
/* 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)
/*
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:
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:
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
}
}
- 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;
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) &&
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,
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 */
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;
/* 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;
}
* 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,
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);
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;
* 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! */
* 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;
/*************************************************************
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;
*/
CURLcode (*disconnect)(struct connectdata *, bool dead_connection);
- long defport; /* Default port. */
- long protocol; /* PROT_* flags concerning the protocol set */
+ long defport; /* Default port. */
+ 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 */
/**** 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
#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
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 */