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

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