protocol handler: added flags field
authorDaniel Stenberg <daniel@haxx.se>
Mon, 14 Mar 2011 21:22:22 +0000 (22:22 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 14 Mar 2011 21:22:22 +0000 (22:22 +0100)
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.

19 files changed:
lib/curl_rtmp.c
lib/dict.c
lib/file.c
lib/ftp.c
lib/gopher.c
lib/http.c
lib/imap.c
lib/multi.c
lib/openldap.c
lib/pop3.c
lib/rtsp.c
lib/sendf.c
lib/smtp.c
lib/ssh.c
lib/telnet.c
lib/tftp.c
lib/transfer.c
lib/url.c
lib/urldata.h

index bc1769e..183db0d 100644 (file)
@@ -74,7 +74,8 @@ const struct Curl_handler Curl_handler_rtmp = {
   ZERO_NULL,                            /* perform_getsock */
   rtmp_disconnect,                      /* disconnect */
   PORT_RTMP,                            /* defport */
-  PROT_RTMP                             /* protocol */
+  PROT_RTMP,                            /* protocol */
+  PROTOPT_NONE                          /* flags*/
 };
 
 const struct Curl_handler Curl_handler_rtmpt = {
@@ -91,7 +92,8 @@ const struct Curl_handler Curl_handler_rtmpt = {
   ZERO_NULL,                            /* perform_getsock */
   rtmp_disconnect,                      /* disconnect */
   PORT_RTMPT,                           /* defport */
-  PROT_RTMPT                            /* protocol */
+  PROT_RTMPT,                           /* protocol */
+  PROTOPT_NONE                          /* flags*/
 };
 
 const struct Curl_handler Curl_handler_rtmpe = {
@@ -108,7 +110,8 @@ const struct Curl_handler Curl_handler_rtmpe = {
   ZERO_NULL,                            /* perform_getsock */
   rtmp_disconnect,                      /* disconnect */
   PORT_RTMP,                            /* defport */
-  PROT_RTMPE                            /* protocol */
+  PROT_RTMPE,                           /* protocol */
+  PROTOPT_NONE                          /* flags*/
 };
 
 const struct Curl_handler Curl_handler_rtmpte = {
@@ -125,7 +128,8 @@ const struct Curl_handler Curl_handler_rtmpte = {
   ZERO_NULL,                            /* perform_getsock */
   rtmp_disconnect,                      /* disconnect */
   PORT_RTMPT,                           /* defport */
-  PROT_RTMPTE                           /* protocol */
+  PROT_RTMPTE,                          /* protocol */
+  PROTOPT_NONE                          /* flags*/
 };
 
 const struct Curl_handler Curl_handler_rtmps = {
@@ -142,7 +146,8 @@ const struct Curl_handler Curl_handler_rtmps = {
   ZERO_NULL,                            /* perform_getsock */
   rtmp_disconnect,                      /* disconnect */
   PORT_RTMPS,                           /* defport */
-  PROT_RTMPS                            /* protocol */
+  PROT_RTMPS,                           /* protocol */
+  PROTOPT_NONE                          /* flags*/
 };
 const struct Curl_handler Curl_handler_rtmpts = {
   "RTMPTS",                             /* scheme */
@@ -158,7 +163,8 @@ const struct Curl_handler Curl_handler_rtmpts = {
   ZERO_NULL,                            /* perform_getsock */
   rtmp_disconnect,                      /* disconnect */
   PORT_RTMPS,                           /* defport */
-  PROT_RTMPTS                           /* protocol */
+  PROT_RTMPTS,                          /* protocol */
+  PROTOPT_NONE                          /* flags*/
 };
 
 static CURLcode rtmp_setup(struct connectdata *conn)
index d86923a..750f728 100644 (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
  * you should have received as part of this distribution. The terms
@@ -108,7 +108,8 @@ const struct Curl_handler Curl_handler_dict = {
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
   PORT_DICT,                            /* defport */
-  PROT_DICT                             /* protocol */
+  PROT_DICT,                            /* protocol */
+  PROTOPT_NONE                          /* flags */
 };
 
 static char *unescape_word(struct SessionHandle *data, const char *inputbuff)
index d4e941f..52c175f 100644 (file)
@@ -127,7 +127,8 @@ const struct Curl_handler Curl_handler_file = {
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
   0,                                    /* defport */
-  PROT_FILE                             /* protocol */
+  PROT_FILE,                            /* protocol */
+  PROTOPT_BANPROXY                      /* flags */
 };
 
 
index af6b4ad..be7cc23 100644 (file)
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -179,7 +179,8 @@ const struct Curl_handler Curl_handler_ftp = {
   ZERO_NULL,                       /* perform_getsock */
   ftp_disconnect,                  /* disconnect */
   PORT_FTP,                        /* defport */
-  PROT_FTP                         /* protocol */
+  PROT_FTP,                        /* protocol */
+  PROTOPT_DUAL | PROTOPT_CLOSEACTION /* flags */
 };
 
 
@@ -202,7 +203,8 @@ const struct Curl_handler Curl_handler_ftps = {
   ZERO_NULL,                       /* perform_getsock */
   ftp_disconnect,                  /* disconnect */
   PORT_FTPS,                       /* defport */
-  PROT_FTP | PROT_FTPS | PROT_SSL  /* protocol */
+  PROT_FTP | PROT_FTPS,            /* protocol */
+  PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION /* flags */
 };
 #endif
 
@@ -225,7 +227,8 @@ static const struct Curl_handler Curl_handler_ftp_proxy = {
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
   PORT_FTP,                             /* defport */
-  PROT_HTTP                             /* protocol */
+  PROT_HTTP,                            /* protocol */
+  PROTOPT_NONE                          /* flags */
 };
 
 
@@ -248,7 +251,8 @@ static const struct Curl_handler Curl_handler_ftps_proxy = {
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
   PORT_FTPS,                            /* defport */
-  PROT_HTTP                             /* protocol */
+  PROT_HTTP,                            /* protocol */
+  PROTOPT_NONE                          /* flags */
 };
 #endif
 #endif
@@ -2480,7 +2484,6 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
         /* Curl_ssl_connect is BLOCKING */
         result = Curl_ssl_connect(conn, FIRSTSOCKET);
         if(CURLE_OK == result) {
-          conn->protocol |= PROT_FTPS;
           conn->ssl[SECONDARYSOCKET].use = FALSE; /* clear-text data */
           result = ftp_state_user(conn);
         }
@@ -2949,7 +2952,7 @@ static CURLcode ftp_connect(struct connectdata *conn,
   }
 #endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_PROXY */
 
-  if(conn->protocol & PROT_FTPS) {
+  if(conn->handler->protocol & PROT_FTPS) {
     /* BLOCKING */
     /* FTPS is simply ftp with SSL for the control channel */
     /* now, perform the SSL initialization for this socket */
index 3d8fcff..70a3f06 100644 (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
  * you should have received as part of this distribution. The terms
@@ -113,7 +113,8 @@ const struct Curl_handler Curl_handler_gopher = {
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
   PORT_GOPHER,                          /* defport */
-  PROT_GOPHER                           /* protocol */
+  PROT_GOPHER,                          /* protocol */
+  PROTOPT_NONE                          /* flags */
 };
 
 static CURLcode gopher_do(struct connectdata *conn, bool *done)
index 419efc1..2a74066 100644 (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;
index 113907a..12af795 100644 (file)
@@ -128,7 +128,8 @@ const struct Curl_handler Curl_handler_imap = {
   ZERO_NULL,                        /* perform_getsock */
   imap_disconnect,                  /* disconnect */
   PORT_IMAP,                        /* defport */
-  PROT_IMAP                         /* protocol */
+  PROT_IMAP,                        /* protocol */
+  PROTOPT_CLOSEACTION               /* flags */
 };
 
 
@@ -151,7 +152,8 @@ const struct Curl_handler Curl_handler_imaps = {
   ZERO_NULL,                        /* perform_getsock */
   imap_disconnect,                  /* disconnect */
   PORT_IMAPS,                       /* defport */
-  PROT_IMAP | PROT_IMAPS | PROT_SSL  /* protocol */
+  PROT_IMAP | PROT_IMAPS,           /* protocol */
+  PROTOPT_CLOSEACTION | PROTOPT_SSL /* flags */
 };
 #endif
 
@@ -174,7 +176,8 @@ static const struct Curl_handler Curl_handler_imap_proxy = {
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
   PORT_IMAP,                            /* defport */
-  PROT_HTTP                             /* protocol */
+  PROT_HTTP,                            /* protocol */
+  PROTOPT_NONE                          /* flags */
 };
 
 
@@ -197,7 +200,8 @@ static const struct Curl_handler Curl_handler_imaps_proxy = {
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
   PORT_IMAPS,                           /* defport */
-  PROT_HTTP                             /* protocol */
+  PROT_HTTP,                            /* protocol */
+  PROTOPT_NONE                          /* flags */
 };
 #endif
 #endif
@@ -351,7 +355,7 @@ static CURLcode imap_state_starttls_resp(struct connectdata *conn,
     else {
       result = Curl_ssl_connect(conn, FIRSTSOCKET);
       if(CURLE_OK == result) {
-        conn->protocol |= PROT_IMAPS;
+        conn->handler = &Curl_handler_imaps;
         result = imap_state_login(conn);
       }
     }
@@ -368,7 +372,7 @@ static CURLcode imap_state_upgrade_tls(struct connectdata *conn)
   result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &imapc->ssldone);
 
   if(imapc->ssldone) {
-    conn->protocol |= PROT_IMAPS;
+    conn->handler = &Curl_handler_imaps;
     result = imap_state_login(conn);
     state(conn, IMAP_STOP);
   }
@@ -617,7 +621,7 @@ static CURLcode imap_multi_statemach(struct connectdata *conn,
   struct imap_conn *imapc = &conn->proto.imapc;
   CURLcode result;
 
-  if((conn->protocol & PROT_IMAPS) && !imapc->ssldone) {
+  if((conn->handler->protocol & PROT_IMAPS) && !imapc->ssldone) {
     result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &imapc->ssldone);
   }
   else {
@@ -734,7 +738,8 @@ static CURLcode imap_connect(struct connectdata *conn,
   }
 #endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_PROXY */
 
-  if((conn->protocol & PROT_IMAPS) && data->state.used_interface != Curl_if_multi) {
+  if((conn->handler->protocol & PROT_IMAPS) &&
+     data->state.used_interface != Curl_if_multi) {
     /* BLOCKING */
     /* IMAPS is simply imap with SSL for the control channel */
     /* now, perform the SSL initialization for this socket */
index d68c368..8172d06 100644 (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
          * happened in the data connection.
          */
-        if(!(easy->easy_conn->protocol & PROT_DUALCHANNEL))
+        if(!(easy->easy_conn->handler->flags & PROTOPT_DUAL))
           easy->easy_conn->bits.close = TRUE;
 
         Curl_posttransfer(data);
@@ -1768,7 +1768,7 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
     /* go over all connections that have close actions */
     for(i=0; i< multi->connc->num; i++) {
       if(multi->connc->connects[i] &&
-         multi->connc->connects[i]->protocol & PROT_CLOSEACTION) {
+         multi->connc->connects[i]->handler->flags & PROTOPT_CLOSEACTION) {
         Curl_disconnect(multi->connc->connects[i], /* dead_connection */ FALSE);
         multi->connc->connects[i] = NULL;
       }
@@ -2129,7 +2129,7 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
           data = conn->recv_pipe->head->ptr;
       }
 
-      if(conn && !(conn->handler->protocol & PROT_LOCKEDBITS))
+      if(conn && !(conn->handler->flags & PROTOPT_DIRLOCK))
         /* set socket event bitmask if they're not locked */
         conn->cselect_bits = ev_bitmask;
 
@@ -2137,7 +2137,7 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
         result = multi_runsingle(multi, now, data->set.one_easy);
       while (CURLM_CALL_MULTI_PERFORM == result);
 
-      if(conn && !(conn->handler->protocol & PROT_LOCKEDBITS))
+      if(conn && !(conn->handler->flags & PROTOPT_DIRLOCK))
         /* clear the bitmask only if not locked */
         conn->cselect_bits = 0;
 
@@ -2682,7 +2682,7 @@ static void multi_connc_remove_handle(struct Curl_multi *multi,
          for nice connection closures".
       */
 
-      if(conn->protocol & PROT_CLOSEACTION) {
+      if(conn->handler->flags & PROTOPT_CLOSEACTION) {
         /* this handle is still being used by a shared connection and
            thus we leave it around for now */
         if(add_closure(multi, data) == CURLM_OK)
index 7010da6..386f796 100644 (file)
@@ -83,7 +83,8 @@ const struct Curl_handler Curl_handler_ldap = {
   ZERO_NULL,                            /* perform_getsock */
   ldap_disconnect,                      /* disconnect */
   PORT_LDAP,                            /* defport */
-  PROT_LDAP                             /* protocol */
+  PROT_LDAP,                            /* protocol */
+  PROTOPT_NONE                          /* flags */
 };
 
 #ifdef USE_SSL
@@ -105,7 +106,8 @@ const struct Curl_handler Curl_handler_ldaps = {
   ZERO_NULL,                            /* perform_getsock */
   ldap_disconnect,                      /* disconnect */
   PORT_LDAPS,                           /* defport */
-  PROT_LDAP | PROT_SSL                  /* protocol */
+  PROT_LDAP,                            /* protocol */
+  PROTOPT_SSL                           /* flags */
 };
 #endif
 
@@ -185,7 +187,7 @@ static CURLcode ldap_connect(struct connectdata *conn, bool *done)
 
   strcpy(hosturl, "ldap");
   ptr = hosturl+4;
-  if (conn->protocol & PROT_SSL)
+  if (conn->handler->flags & PROTOPT_SSL)
     *ptr++ = 's';
   snprintf(ptr, sizeof(hosturl)-(ptr-hosturl), "://%s:%d",
     conn->host.name, conn->remote_port);
@@ -229,7 +231,7 @@ static CURLcode ldap_connect(struct connectdata *conn, bool *done)
 #endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_PROXY */
 
 #ifdef USE_SSL
-  if (conn->protocol & PROT_SSL) {
+  if (conn->handler->flags & PROTOPT_SSL) {
     CURLcode res;
     if (data->state.used_interface == Curl_if_easy) {
       res = Curl_ssl_connect(conn, FIRSTSOCKET);
@@ -260,7 +262,7 @@ static CURLcode ldap_connecting(struct connectdata *conn, bool *done)
   char *info = NULL;
 
 #ifdef USE_SSL
-  if (conn->protocol & PROT_SSL) {
+  if (conn->handler->flags & PROTOPT_SSL) {
     /* Is the SSL handshake complete yet? */
     if (!li->ssldone) {
       CURLcode res = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &li->ssldone);
index 9f67443..2c1cc00 100644 (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
  * you should have received as part of this distribution. The terms
@@ -128,7 +128,8 @@ const struct Curl_handler Curl_handler_pop3 = {
   ZERO_NULL,                        /* perform_getsock */
   pop3_disconnect,                  /* disconnect */
   PORT_POP3,                        /* defport */
-  PROT_POP3                         /* protocol */
+  PROT_POP3,                        /* protocol */
+  PROTOPT_CLOSEACTION               /* flags */
 };
 
 
@@ -151,7 +152,8 @@ const struct Curl_handler Curl_handler_pop3s = {
   ZERO_NULL,                        /* perform_getsock */
   pop3_disconnect,                  /* disconnect */
   PORT_POP3S,                       /* defport */
-  PROT_POP3 | PROT_POP3S | PROT_SSL  /* protocol */
+  PROT_POP3 | PROT_POP3S,           /* protocol */
+  PROTOPT_CLOSEACTION | PROTOPT_SSL /* flags */
 };
 #endif
 
@@ -174,7 +176,8 @@ static const struct Curl_handler Curl_handler_pop3_proxy = {
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
   PORT_POP3,                            /* defport */
-  PROT_HTTP                             /* protocol */
+  PROT_HTTP,                            /* protocol */
+  PROTOPT_NONE                          /* flags */
 };
 
 
@@ -197,7 +200,8 @@ static const struct Curl_handler Curl_handler_pop3s_proxy = {
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
   PORT_POP3S,                           /* defport */
-  PROT_HTTP                             /* protocol */
+  PROT_HTTP,                            /* protocol */
+  PROTOPT_NONE                          /* flags */
 };
 #endif
 #endif
@@ -288,7 +292,7 @@ static CURLcode pop3_state_starttls_resp(struct connectdata *conn,
     /* Curl_ssl_connect is BLOCKING */
     result = Curl_ssl_connect(conn, FIRSTSOCKET);
     if(CURLE_OK == result) {
-      conn->protocol |= PROT_POP3S;
+      conn->handler = &Curl_handler_pop3s;
       result = pop3_state_user(conn);
     }
   }
@@ -637,7 +641,7 @@ static CURLcode pop3_connect(struct connectdata *conn,
   }
 #endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_PROXY */
 
-  if(conn->protocol & PROT_POP3S) {
+  if(conn->handler->protocol & PROT_POP3S) {
     /* BLOCKING */
     /* POP3S is simply pop3 with SSL for the control channel */
     /* now, perform the SSL initialization for this socket */
index 066e10f..baf561f 100644 (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
  * you should have received as part of this distribution. The terms
@@ -97,6 +97,7 @@ const struct Curl_handler Curl_handler_rtsp = {
   Curl_rtsp_disconnect,                 /* disconnect */
   PORT_RTSP,                            /* defport */
   PROT_RTSP,                            /* protocol */
+  PROTOPT_NONE                          /* flags */
 };
 
 CURLcode Curl_rtsp_connect(struct connectdata *conn, bool *done)
index d04371f..d9e7dbb 100644 (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
  * you should have received as part of this distribution. The terms
@@ -441,7 +441,8 @@ CURLcode Curl_client_write(struct connectdata *conn,
   }
 
   if(type & CLIENTWRITE_BODY) {
-    if((conn->protocol&PROT_FTP) && conn->proto.ftpc.transfertype == 'A') {
+    if((conn->handler->protocol&PROT_FTP) &&
+       conn->proto.ftpc.transfertype == 'A') {
 #ifdef CURL_DOES_CONVERSIONS
       /* convert from the network encoding */
       size_t rc;
index b01ad7d..cfd4d98 100644 (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
  * you should have received as part of this distribution. The terms
@@ -135,7 +135,8 @@ const struct Curl_handler Curl_handler_smtp = {
   ZERO_NULL,                        /* perform_getsock */
   smtp_disconnect,                  /* disconnect */
   PORT_SMTP,                        /* defport */
-  PROT_SMTP                         /* protocol */
+  PROT_SMTP,                        /* protocol */
+  PROTOPT_CLOSEACTION               /* flags */
 };
 
 
@@ -158,7 +159,8 @@ const struct Curl_handler Curl_handler_smtps = {
   ZERO_NULL,                        /* perform_getsock */
   smtp_disconnect,                  /* disconnect */
   PORT_SMTPS,                       /* defport */
-  PROT_SMTP | PROT_SMTPS | PROT_SSL  /* protocol */
+  PROT_SMTP | PROT_SMTPS,           /* protocol */
+  PROTOPT_CLOSEACTION | PROTOPT_SSL /* flags */
 };
 #endif
 
@@ -181,7 +183,8 @@ static const struct Curl_handler Curl_handler_smtp_proxy = {
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
   PORT_SMTP,                            /* defport */
-  PROT_HTTP                             /* protocol */
+  PROT_HTTP,                            /* protocol */
+  PROTOPT_NONE                          /* flags */
 };
 
 
@@ -204,7 +207,8 @@ static const struct Curl_handler Curl_handler_smtps_proxy = {
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
   PORT_SMTPS,                           /* defport */
-  PROT_HTTP                             /* protocol */
+  PROT_HTTP,                            /* protocol */
+  PROTOPT_NONE                          /* flags */
 };
 #endif
 #endif
@@ -471,7 +475,7 @@ static CURLcode smtp_state_starttls_resp(struct connectdata *conn,
     /* Curl_ssl_connect is BLOCKING */
     result = Curl_ssl_connect(conn, FIRSTSOCKET);
     if(CURLE_OK == result) {
-      conn->protocol |= PROT_SMTPS;
+      conn->handler = &Curl_handler_smtps;
       result = smtp_state_ehlo(conn);
     }
   }
@@ -1101,7 +1105,7 @@ static CURLcode smtp_connect(struct connectdata *conn,
   }
 #endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_PROXY */
 
-  if(conn->protocol & PROT_SMTPS) {
+  if(conn->handler->protocol & PROT_SMTPS) {
     /* BLOCKING */
     /* SMTPS is simply smtp with SSL for the control channel */
     /* now, perform the SSL initialization for this socket */
index e85ad26..1551ea9 100644 (file)
--- a/lib/ssh.c
+++ b/lib/ssh.c
@@ -175,7 +175,8 @@ const struct Curl_handler Curl_handler_scp = {
   ssh_perform_getsock,                  /* perform_getsock */
   scp_disconnect,                       /* disconnect */
   PORT_SSH,                             /* defport */
-  PROT_SCP                              /* protocol */
+  PROT_SCP,                             /* protocol */
+  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION /* flags */
 };
 
 
@@ -197,7 +198,8 @@ const struct Curl_handler Curl_handler_sftp = {
   ssh_perform_getsock,                  /* perform_getsock */
   sftp_disconnect,                      /* disconnect */
   PORT_SSH,                             /* defport */
-  PROT_SFTP                             /* protocol */
+  PROT_SFTP,                            /* protocol */
+  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION /* flags */
 };
 
 
@@ -411,7 +413,7 @@ static CURLcode ssh_getworkingpath(struct connectdata *conn,
     return CURLE_OUT_OF_MEMORY;
 
   /* Check for /~/ , indicating relative to the user's home directory */
-  if(conn->protocol & PROT_SCP) {
+  if(conn->handler->protocol & PROT_SCP) {
     real_path = malloc(working_path_len+1);
     if(real_path == NULL) {
       free(working_path);
@@ -423,7 +425,7 @@ static CURLcode ssh_getworkingpath(struct connectdata *conn,
     else
       memcpy(real_path, working_path, 1 + working_path_len);
   }
-  else if(conn->protocol & PROT_SFTP) {
+  else if(conn->handler->protocol & PROT_SFTP) {
     if((working_path_len > 1) && (working_path[1] == '~')) {
       size_t homelen = strlen(homedir);
       real_path = malloc(homelen + working_path_len + 1);
@@ -931,7 +933,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       conn->sockfd = sock;
       conn->writesockfd = CURL_SOCKET_BAD;
 
-      if(conn->protocol == PROT_SFTP) {
+      if(conn->handler->protocol == PROT_SFTP) {
         state(conn, SSH_SFTP_INIT);
         break;
       }
@@ -2566,7 +2568,7 @@ static CURLcode ssh_connect(struct connectdata *conn, bool *done)
   if(result)
     return result;
 
-  if(conn->protocol & PROT_SCP) {
+  if(conn->handler->protocol & PROT_SCP) {
     conn->recv[FIRSTSOCKET] = scp_recv;
     conn->send[FIRSTSOCKET] = scp_send;
   } else {
@@ -2715,7 +2717,7 @@ static CURLcode ssh_do(struct connectdata *conn, bool *done)
   Curl_pgrsSetUploadSize(data, 0);
   Curl_pgrsSetDownloadSize(data, 0);
 
-  if(conn->protocol & PROT_SCP)
+  if(conn->handler->protocol & PROT_SCP)
     res = scp_perform(conn, &connected,  done);
   else
     res = sftp_perform(conn, &connected,  done);
index 1a5683d..a716a55 100644 (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
  * you should have received as part of this distribution. The terms
@@ -196,7 +196,8 @@ const struct Curl_handler Curl_handler_telnet = {
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
   PORT_TELNET,                          /* defport */
-  PROT_TELNET                           /* protocol */
+  PROT_TELNET,                          /* protocol */
+  PROTOPT_NONE                          /* flags */
 };
 
 
index ef57fb1..a70ceac 100644 (file)
@@ -196,7 +196,8 @@ const struct Curl_handler Curl_handler_tftp = {
   ZERO_NULL,                            /* perform_getsock */
   tftp_disconnect,                      /* disconnect */
   PORT_TFTP,                            /* defport */
-  PROT_TFTP                             /* protocol */
+  PROT_TFTP,                            /* protocol */
+  PROTOPT_NONE                          /* flags */
 };
 
 /**********************************************************
index 63ab5c4..8302396 100644 (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
      its internal buffers so we MUST always try until we get EAGAIN back */
-  return conn->protocol&(PROT_SCP|PROT_SFTP) ||
+  return conn->handler->protocol&(PROT_SCP|PROT_SFTP) ||
     Curl_ssl_data_pending(conn, FIRSTSOCKET);
 }
 
@@ -469,7 +469,7 @@ static CURLcode readwrite_data(struct SessionHandle *data,
 
 #ifndef CURL_DISABLE_RTSP
     /* Check for RTP at the beginning of the data */
-    if(conn->protocol & PROT_RTSP) {
+    if(conn->handler->protocol & PROT_RTSP) {
       result = Curl_rtsp_rtp_readwrite(data, conn, &nread, &readmore);
       if(result)
         return result;
@@ -490,7 +490,8 @@ static CURLcode readwrite_data(struct SessionHandle *data,
 
 #ifndef CURL_DISABLE_RTSP
       /* Check for RTP after the headers if there is no Content */
-      if(k->maxdownload <= 0 && nread > 0 && (conn->protocol & PROT_RTSP)) {
+      if(k->maxdownload <= 0 && nread > 0 &&
+         (conn->handler->protocol & PROT_RTSP)) {
         result = Curl_rtsp_rtp_readwrite(data, conn, &nread, &readmore);
         if(result)
           return result;
@@ -516,7 +517,7 @@ static CURLcode readwrite_data(struct SessionHandle *data,
       if(0 == k->bodywrites && !is_empty_data) {
         /* These checks are only made the first time we are about to
            write a piece of the body */
-        if(conn->protocol&(PROT_HTTP|PROT_RTSP)) {
+        if(conn->handler->protocol&(PROT_HTTP|PROT_RTSP)) {
           /* HTTP-only checks */
 
           if(data->req.newurl) {
@@ -703,7 +704,7 @@ static CURLcode readwrite_data(struct SessionHandle *data,
             if(!k->ignorebody) {
 
 #ifndef CURL_DISABLE_POP3
-              if(conn->protocol&PROT_POP3)
+              if(conn->handler->protocol&PROT_POP3)
                 result = Curl_pop3_write(conn, k->str, nread);
               else
 #endif /* CURL_DISABLE_POP3 */
@@ -746,7 +747,7 @@ static CURLcode readwrite_data(struct SessionHandle *data,
 
 #ifndef CURL_DISABLE_RTSP
     if(excess > 0 && !conn->bits.stream_was_rewound &&
-        (conn->protocol & PROT_RTSP)) {
+        (conn->handler->protocol & PROT_RTSP)) {
       /* Check for RTP after the content if there is unrewound excess */
 
       /* Parse the excess data */
@@ -834,7 +835,7 @@ static CURLcode readwrite_upload(struct SessionHandle *data,
           break;
         }
 
-        if(conn->protocol&(PROT_HTTP|PROT_RTSP)) {
+        if(conn->handler->protocol&(PROT_HTTP|PROT_RTSP)) {
           if(data->state.proto.http->sending == HTTPSEND_REQUEST)
             /* We're sending the HTTP request headers, not the data.
                Remember that so we don't change the line endings. */
@@ -872,7 +873,7 @@ static CURLcode readwrite_upload(struct SessionHandle *data,
       data->req.upload_present = nread;
 
 #ifndef CURL_DISABLE_SMTP
-      if(conn->protocol & PROT_SMTP) {
+      if(conn->handler->protocol & PROT_SMTP) {
         result = Curl_smtp_escape_eob(conn, nread);
         if(result)
           return result;
@@ -2059,7 +2060,7 @@ CURLcode Curl_retry_request(struct connectdata *conn,
 
   /* if we're talking upload, we can't do the checks below, unless the protocol
      is HTTP as when uploading over HTTP we will still get a response */
-  if(data->set.upload && !(conn->protocol&(PROT_HTTP|PROT_RTSP)))
+  if(data->set.upload && !(conn->handler->protocol&(PROT_HTTP|PROT_RTSP)))
     return CURLE_OK;
 
   if(/* workaround for broken TLS servers */ data->state.ssl_connect_retry ||
index 5af0071..e9a7f4a 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -263,7 +263,8 @@ static const struct Curl_handler Curl_handler_dummy = {
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
   0,                                    /* defport */
-  0                                     /* protocol */
+  0,                                    /* protocol */
+  0                                     /* flags */
 };
 
 void Curl_safefree(void *ptr)
@@ -765,9 +766,9 @@ CURLcode Curl_init_userdefined(struct UserDefined *set)
   /* for the *protocols fields we don't use the CURLPROTO_ALL convenience
      define since we internally only use the lower 16 bits for the passed
      in bitmask to not conflict with the private bits */
-  set->allowed_protocols = PROT_EXTMASK;
+  set->allowed_protocols = PROT_ALL;
   set->redir_protocols =
-    PROT_EXTMASK & ~(CURLPROTO_FILE|CURLPROTO_SCP); /* not FILE or SCP */
+    PROT_ALL & ~(CURLPROTO_FILE|CURLPROTO_SCP); /* not FILE or SCP */
 
 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
   /*
@@ -2382,7 +2383,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
        transfer, which thus helps the app which takes URLs from users or other
        external inputs and want to restrict what protocol(s) to deal
        with. Defaults to CURLPROTO_ALL. */
-    data->set.allowed_protocols = va_arg(param, long) & PROT_EXTMASK;
+    data->set.allowed_protocols = va_arg(param, long);
     break;
 
   case CURLOPT_REDIR_PROTOCOLS:
@@ -2390,7 +2391,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
        as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
        to be set in both bitmasks to be allowed to get redirected to. Defaults
        to all protocols except FILE and SCP. */
-    data->set.redir_protocols = va_arg(param, long) & PROT_EXTMASK;
+    data->set.redir_protocols = va_arg(param, long);
     break;
 
   case CURLOPT_MAIL_FROM:
@@ -2931,7 +2932,7 @@ ConnectionExists(struct SessionHandle *data,
          use */
       bool dead;
 #ifndef CURL_DISABLE_RTSP
-      if(check->protocol & PROT_RTSP)
+      if(check->handler->protocol & PROT_RTSP)
         /* RTSP is a special case due to RTP interleaving */
         dead = RTSPConnIsDead(check);
       else
@@ -3003,11 +3004,12 @@ ConnectionExists(struct SessionHandle *data,
       }
     }
 
-    if((needle->protocol&PROT_SSL) != (check->protocol&PROT_SSL))
+    if((needle->handler->flags&PROTOPT_SSL) !=
+       (check->handler->flags&PROTOPT_SSL))
       /* don't do mixed SSL and non-SSL connections */
       continue;
 
-    if(needle->protocol&PROT_SSL) {
+    if(needle->handler->flags&PROTOPT_SSL) {
       if((data->set.ssl.verifypeer != check->verifypeer) ||
          (data->set.ssl.verifyhost != check->verifyhost))
         continue;
@@ -3022,7 +3024,7 @@ ConnectionExists(struct SessionHandle *data,
          in use so we skip it */
       continue;
 
-    if(!needle->bits.httpproxy || needle->protocol&PROT_SSL ||
+    if(!needle->bits.httpproxy || needle->handler->flags&PROTOPT_SSL ||
        (needle->bits.httpproxy && check->bits.httpproxy &&
         needle->bits.tunnel_proxy && check->bits.tunnel_proxy &&
         Curl_raw_equal(needle->proxy.name, check->proxy.name) &&
@@ -3034,7 +3036,7 @@ ConnectionExists(struct SessionHandle *data,
       if(Curl_raw_equal(needle->handler->scheme, check->handler->scheme) &&
          Curl_raw_equal(needle->host.name, check->host.name) &&
          (needle->remote_port == check->remote_port) ) {
-        if(needle->protocol & PROT_SSL) {
+        if(needle->handler->flags & PROTOPT_SSL) {
           /* This is SSL, verify that we're using the same
              ssl options as well */
           if(!Curl_ssl_config_matches(&needle->ssl_config,
@@ -3053,8 +3055,8 @@ ConnectionExists(struct SessionHandle *data,
             continue;
           }
         }
-        if((needle->protocol & PROT_FTP) ||
-           ((needle->protocol & PROT_HTTP) &&
+        if((needle->handler->protocol & PROT_FTP) ||
+           ((needle->handler->protocol & PROT_HTTP) &&
             (data->state.authhost.want==CURLAUTH_NTLM))) {
           /* This is FTP or HTTP+NTLM, verify that we're using the same name
              and password as well */
@@ -3639,8 +3641,7 @@ static CURLcode findprotocol(struct SessionHandle *data,
         break;
 
       /* Perform setup complement if some. */
-      conn->handler = p;
-      conn->protocol |= p->protocol;
+      conn->handler = conn->given = p;
 
       /* 'port' and 'remote_port' are set in setup_connection_internals() */
       return CURLE_OK;
@@ -3938,8 +3939,7 @@ static CURLcode setup_connection_internals(struct connectdata *conn)
     /* we check for -1 here since if proxy was detected already, this
        was very likely already set to the proxy port */
     conn->port = p->defport;
-  conn->remote_port = (unsigned short)p->defport;
-  conn->protocol |= p->protocol;
+  conn->remote_port = (unsigned short)conn->given->defport;
 
   return CURLE_OK;
 }
@@ -4418,7 +4418,7 @@ static CURLcode parse_remote_port(struct SessionHandle *data,
        * stripped off. It would be better to work directly from the original
        * URL and simply replace the port part of it.
        */
-      url = aprintf("%s://%s%s%s:%hu%s%s%s", conn->handler->scheme,
+      url = aprintf("%s://%s%s%s:%hu%s%s%s", conn->given->scheme,
                     conn->bits.ipv6_ip?"[":"", conn->host.name,
                     conn->bits.ipv6_ip?"]":"", conn->remote_port,
                     data->state.slash_removed?"/":"", data->state.path,
@@ -4507,7 +4507,7 @@ static CURLcode set_userpass(struct connectdata *conn,
                              const char *user, const char *passwd)
 {
   /* If our protocol needs a password and we have none, use the defaults */
-  if( (conn->protocol & (PROT_FTP|PROT_IMAP)) &&
+  if( (conn->handler->protocol & (PROT_FTP|PROT_IMAP)) &&
        !conn->bits.user_passwd) {
 
     conn->user = strdup(CURL_DEFAULT_USER);
@@ -4829,13 +4829,11 @@ static CURLcode create_conn(struct SessionHandle *data,
     proxy = NULL;
   }
   /* proxy must be freed later unless NULL */
-  if(proxy) {
-    long bits = conn->protocol & (PROT_HTTPS|PROT_SSL);
-
+  if(proxy && !(conn->handler->flags & PROTOPT_BANPROXY)) {
     if((conn->proxytype == CURLPROXY_HTTP) ||
        (conn->proxytype == CURLPROXY_HTTP_1_0)) {
       /* force this connection's protocol to become HTTP */
-      conn->protocol = PROT_HTTP | bits;
+      conn->handler = &Curl_handler_http;
       conn->bits.httpproxy = TRUE;
     }
     conn->bits.proxy = TRUE;
@@ -4881,7 +4879,7 @@ static CURLcode create_conn(struct SessionHandle *data,
    * file: is a special case in that it doesn't need a network connection
    ***********************************************************************/
 #ifndef CURL_DISABLE_FILE
-  if(conn->protocol & PROT_FILE) {
+  if(conn->handler->protocol & PROT_FILE) {
     bool done;
     /* this is supposed to be the connect function so we better at least check
        that the file is present here! */
@@ -4918,7 +4916,7 @@ static CURLcode create_conn(struct SessionHandle *data,
    * If the protocol is using SSL and HTTP proxy is used, we set
    * the tunnel_proxy bit.
    *************************************************************/
-  if((conn->protocol&PROT_SSL) && conn->bits.httpproxy)
+  if((conn->given->flags&PROTOPT_SSL) && conn->bits.httpproxy)
     conn->bits.tunnel_proxy = TRUE;
 
   /*************************************************************
@@ -5041,7 +5039,7 @@ static CURLcode setup_conn(struct connectdata *conn,
 
   Curl_pgrsTime(data, TIMER_NAMELOOKUP);
 
-  if(conn->protocol & PROT_FILE) {
+  if(conn->handler->protocol & PROT_FILE) {
     /* There's nothing in this function to setup if we're only doing
        a file:// transfer */
     *protocol_done = TRUE;
index 2f7fe5e..20cce14 100644 (file)
@@ -694,8 +694,9 @@ struct Curl_handler {
    */
   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 */
@@ -735,7 +736,7 @@ struct connectdata {
   /**** Fields set when inited and not modified again */
   long connectindex; /* what index in the connection cache connects index this
                         particular struct has */
-  long protocol; /* PROT_* flags concerning the protocol set */
+
 #define PROT_HTTP    CURLPROTO_HTTP
 #define PROT_HTTPS   CURLPROTO_HTTPS
 #define PROT_FTP     CURLPROTO_FTP
@@ -762,24 +763,18 @@ struct connectdata {
 #define PROT_RTMPTS  CURLPROTO_RTMPTS
 #define PROT_GOPHER  CURLPROTO_GOPHER
 
-/* (1<<25) is currently the highest used bit in the public bitmask. We make
-   sure we use "private bits" above the public ones to make things easier;
-   Gopher will not conflict with the current bit 25. */
-
-#define PROT_EXTMASK 0x03ffffff
-
-#define PROT_SSL     (1<<29) /* protocol requires SSL */
-
-/* these ones need action before socket close */
-#define PROT_CLOSEACTION (PROT_FTP | PROT_IMAP | PROT_POP3 |    \
-                          PROT_SFTP | PROT_SCP)
-#define PROT_DUALCHANNEL PROT_FTP /* these protocols use two connections */
+#define PROT_ALL     ~0
 
+#define PROTOPT_NONE 0             /* nothing extra */
+#define PROTOPT_SSL (1<<0)         /* uses SSL */
+#define PROTOPT_DUAL (1<<1)        /* this protocol uses two connections */
+#define PROTOPT_CLOSEACTION (1<<2) /* need action before socket close */
 /* some protocols will have to call the underlying functions without regard to
    what exact state the socket signals. IE even if the socket says "readable",
    the send function might need to be called while uploading, or vice versa.
 */
-#define PROT_LOCKEDBITS (PROT_SCP | PROT_SFTP)
+#define PROTOPT_DIRLOCK (1<<3)
+#define PROTOPT_BANPROXY (1<<4)    /* not allowed to use proxy */
 
   /* 'dns_entry' is the particular host we use. This points to an entry in the
      DNS cache and it will not get pruned while locked. It gets unlocked in
@@ -857,7 +852,8 @@ struct connectdata {
   long timeoutms_per_addr; /* how long time in milliseconds to spend on
                               trying to connect to each IP address */
 
-  const struct Curl_handler * handler;  /* Connection's protocol handler. */
+  const struct Curl_handler *handler; /* Connection's protocol handler */
+  const struct Curl_handler *given;   /* The protocol first given */
 
   long ip_version; /* copied from the SessionHandle at creation time */