From f0612f166a5fa51d09498baa19a327c5cf36941f Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 5 May 2011 16:27:03 +0200
Subject: [PATCH] RTSP: convert protocol-specific checks to generic

Add a 'readwrite' function to the protocol handler struct and use that
for the extra readwrite functionality RTSP needs.
---
 lib/curl_rtmp.c |  7 +++++++
 lib/dict.c      |  1 +
 lib/file.c      |  1 +
 lib/ftp.c       |  4 ++++
 lib/gopher.c    |  1 +
 lib/http.c      |  2 ++
 lib/imap.c      |  4 ++++
 lib/openldap.c  |  2 ++
 lib/pop3.c      |  4 ++++
 lib/rtsp.c      | 23 +++++++++++++++++++----
 lib/rtsp.h      | 13 -------------
 lib/smtp.c      |  4 ++++
 lib/ssh.c       |  2 ++
 lib/telnet.c    |  1 +
 lib/tftp.c      |  1 +
 lib/transfer.c  | 26 ++++++++------------------
 lib/url.c       |  1 +
 lib/urldata.h   |  5 +++++
 18 files changed, 67 insertions(+), 35 deletions(-)

diff --git a/lib/curl_rtmp.c b/lib/curl_rtmp.c
index 2aab52b404..44b7e1524c 100644
--- a/lib/curl_rtmp.c
+++ b/lib/curl_rtmp.c
@@ -73,6 +73,7 @@ const struct Curl_handler Curl_handler_rtmp = {
   ZERO_NULL,                            /* doing_getsock */
   ZERO_NULL,                            /* perform_getsock */
   rtmp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
   PORT_RTMP,                            /* defport */
   CURLPROTO_RTMP,                       /* protocol */
   PROTOPT_NONE                          /* flags*/
@@ -91,6 +92,7 @@ const struct Curl_handler Curl_handler_rtmpt = {
   ZERO_NULL,                            /* doing_getsock */
   ZERO_NULL,                            /* perform_getsock */
   rtmp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
   PORT_RTMPT,                           /* defport */
   CURLPROTO_RTMPT,                      /* protocol */
   PROTOPT_NONE                          /* flags*/
@@ -109,6 +111,7 @@ const struct Curl_handler Curl_handler_rtmpe = {
   ZERO_NULL,                            /* doing_getsock */
   ZERO_NULL,                            /* perform_getsock */
   rtmp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
   PORT_RTMP,                            /* defport */
   CURLPROTO_RTMPE,                      /* protocol */
   PROTOPT_NONE                          /* flags*/
@@ -127,6 +130,7 @@ const struct Curl_handler Curl_handler_rtmpte = {
   ZERO_NULL,                            /* doing_getsock */
   ZERO_NULL,                            /* perform_getsock */
   rtmp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
   PORT_RTMPT,                           /* defport */
   CURLPROTO_RTMPTE,                     /* protocol */
   PROTOPT_NONE                          /* flags*/
@@ -145,10 +149,12 @@ const struct Curl_handler Curl_handler_rtmps = {
   ZERO_NULL,                            /* doing_getsock */
   ZERO_NULL,                            /* perform_getsock */
   rtmp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
   PORT_RTMPS,                           /* defport */
   CURLPROTO_RTMPS,                      /* protocol */
   PROTOPT_NONE                          /* flags*/
 };
+
 const struct Curl_handler Curl_handler_rtmpts = {
   "RTMPTS",                             /* scheme */
   rtmp_setup,                           /* setup_connection */
@@ -162,6 +168,7 @@ const struct Curl_handler Curl_handler_rtmpts = {
   ZERO_NULL,                            /* doing_getsock */
   ZERO_NULL,                            /* perform_getsock */
   rtmp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
   PORT_RTMPS,                           /* defport */
   CURLPROTO_RTMPTS,                     /* protocol */
   PROTOPT_NONE                          /* flags*/
diff --git a/lib/dict.c b/lib/dict.c
index c296bd998c..0baaeec3a2 100644
--- a/lib/dict.c
+++ b/lib/dict.c
@@ -107,6 +107,7 @@ const struct Curl_handler Curl_handler_dict = {
   ZERO_NULL,                            /* doing_getsock */
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
   PORT_DICT,                            /* defport */
   CURLPROTO_DICT,                       /* protocol */
   PROTOPT_NONE                          /* flags */
diff --git a/lib/file.c b/lib/file.c
index 6fe4c4979e..4f3ea1bb47 100644
--- a/lib/file.c
+++ b/lib/file.c
@@ -127,6 +127,7 @@ const struct Curl_handler Curl_handler_file = {
   ZERO_NULL,                            /* doing_getsock */
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
   0,                                    /* defport */
   CURLPROTO_FILE,                       /* protocol */
   PROTOPT_NONETWORK                     /* flags */
diff --git a/lib/ftp.c b/lib/ftp.c
index ec8d9f11d4..52322dfafc 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -178,6 +178,7 @@ const struct Curl_handler Curl_handler_ftp = {
   ftp_getsock,                     /* doing_getsock */
   ZERO_NULL,                       /* perform_getsock */
   ftp_disconnect,                  /* disconnect */
+  ZERO_NULL,                       /* readwrite */
   PORT_FTP,                        /* defport */
   CURLPROTO_FTP,                   /* protocol */
   PROTOPT_DUAL | PROTOPT_CLOSEACTION /* flags */
@@ -202,6 +203,7 @@ const struct Curl_handler Curl_handler_ftps = {
   ftp_getsock,                     /* doing_getsock */
   ZERO_NULL,                       /* perform_getsock */
   ftp_disconnect,                  /* disconnect */
+  ZERO_NULL,                       /* readwrite */
   PORT_FTPS,                       /* defport */
   CURLPROTO_FTP | CURLPROTO_FTPS,  /* protocol */
   PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION /* flags */
@@ -226,6 +228,7 @@ static const struct Curl_handler Curl_handler_ftp_proxy = {
   ZERO_NULL,                            /* doing_getsock */
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
   PORT_FTP,                             /* defport */
   CURLPROTO_HTTP,                       /* protocol */
   PROTOPT_NONE                          /* flags */
@@ -250,6 +253,7 @@ static const struct Curl_handler Curl_handler_ftps_proxy = {
   ZERO_NULL,                            /* doing_getsock */
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
   PORT_FTPS,                            /* defport */
   CURLPROTO_HTTP,                       /* protocol */
   PROTOPT_NONE                          /* flags */
diff --git a/lib/gopher.c b/lib/gopher.c
index 3ee8261b66..b2d2689d1c 100644
--- a/lib/gopher.c
+++ b/lib/gopher.c
@@ -112,6 +112,7 @@ const struct Curl_handler Curl_handler_gopher = {
   ZERO_NULL,                            /* doing_getsock */
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
   PORT_GOPHER,                          /* defport */
   CURLPROTO_GOPHER,                     /* protocol */
   PROTOPT_NONE                          /* flags */
diff --git a/lib/http.c b/lib/http.c
index 5759a7ff23..cc8dcffa58 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -139,6 +139,7 @@ const struct Curl_handler Curl_handler_http = {
   http_getsock_do,                      /* doing_getsock */
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
   PORT_HTTP,                            /* defport */
   CURLPROTO_HTTP,                       /* protocol */
   PROTOPT_NONE                          /* flags */
@@ -161,6 +162,7 @@ const struct Curl_handler Curl_handler_https = {
   http_getsock_do,                      /* doing_getsock */
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
   PORT_HTTPS,                           /* defport */
   CURLPROTO_HTTP | CURLPROTO_HTTPS,     /* protocol */
   PROTOPT_SSL                           /* flags */
diff --git a/lib/imap.c b/lib/imap.c
index a01da3eece..67f0328e49 100644
--- a/lib/imap.c
+++ b/lib/imap.c
@@ -126,6 +126,7 @@ const struct Curl_handler Curl_handler_imap = {
   imap_getsock,                     /* doing_getsock */
   ZERO_NULL,                        /* perform_getsock */
   imap_disconnect,                  /* disconnect */
+  ZERO_NULL,                        /* readwrite */
   PORT_IMAP,                        /* defport */
   CURLPROTO_IMAP,                   /* protocol */
   PROTOPT_CLOSEACTION               /* flags */
@@ -150,6 +151,7 @@ const struct Curl_handler Curl_handler_imaps = {
   imap_getsock,                     /* doing_getsock */
   ZERO_NULL,                        /* perform_getsock */
   imap_disconnect,                  /* disconnect */
+  ZERO_NULL,                        /* readwrite */
   PORT_IMAPS,                       /* defport */
   CURLPROTO_IMAP | CURLPROTO_IMAPS, /* protocol */
   PROTOPT_CLOSEACTION | PROTOPT_SSL /* flags */
@@ -174,6 +176,7 @@ static const struct Curl_handler Curl_handler_imap_proxy = {
   ZERO_NULL,                            /* doing_getsock */
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
   PORT_IMAP,                            /* defport */
   CURLPROTO_HTTP,                       /* protocol */
   PROTOPT_NONE                          /* flags */
@@ -198,6 +201,7 @@ static const struct Curl_handler Curl_handler_imaps_proxy = {
   ZERO_NULL,                            /* doing_getsock */
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
   PORT_IMAPS,                           /* defport */
   CURLPROTO_HTTP,                       /* protocol */
   PROTOPT_NONE                          /* flags */
diff --git a/lib/openldap.c b/lib/openldap.c
index 80dc284ac0..69523cb371 100644
--- a/lib/openldap.c
+++ b/lib/openldap.c
@@ -85,6 +85,7 @@ const struct Curl_handler Curl_handler_ldap = {
   ZERO_NULL,                            /* doing_getsock */
   ZERO_NULL,                            /* perform_getsock */
   ldap_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
   PORT_LDAP,                            /* defport */
   CURLPROTO_LDAP,                       /* protocol */
   PROTOPT_NONE                          /* flags */
@@ -108,6 +109,7 @@ const struct Curl_handler Curl_handler_ldaps = {
   ZERO_NULL,                            /* doing_getsock */
   ZERO_NULL,                            /* perform_getsock */
   ldap_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
   PORT_LDAPS,                           /* defport */
   CURLPROTO_LDAP,                       /* protocol */
   PROTOPT_SSL                           /* flags */
diff --git a/lib/pop3.c b/lib/pop3.c
index f536612857..0581c58b01 100644
--- a/lib/pop3.c
+++ b/lib/pop3.c
@@ -126,6 +126,7 @@ const struct Curl_handler Curl_handler_pop3 = {
   pop3_getsock,                     /* doing_getsock */
   ZERO_NULL,                        /* perform_getsock */
   pop3_disconnect,                  /* disconnect */
+  ZERO_NULL,                        /* readwrite */
   PORT_POP3,                        /* defport */
   CURLPROTO_POP3,                   /* protocol */
   PROTOPT_CLOSEACTION               /* flags */
@@ -150,6 +151,7 @@ const struct Curl_handler Curl_handler_pop3s = {
   pop3_getsock,                     /* doing_getsock */
   ZERO_NULL,                        /* perform_getsock */
   pop3_disconnect,                  /* disconnect */
+  ZERO_NULL,                        /* readwrite */
   PORT_POP3S,                       /* defport */
   CURLPROTO_POP3 | CURLPROTO_POP3S, /* protocol */
   PROTOPT_CLOSEACTION | PROTOPT_SSL /* flags */
@@ -174,6 +176,7 @@ static const struct Curl_handler Curl_handler_pop3_proxy = {
   ZERO_NULL,                            /* doing_getsock */
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
   PORT_POP3,                            /* defport */
   CURLPROTO_HTTP,                       /* protocol */
   PROTOPT_NONE                          /* flags */
@@ -198,6 +201,7 @@ static const struct Curl_handler Curl_handler_pop3s_proxy = {
   ZERO_NULL,                            /* doing_getsock */
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
   PORT_POP3S,                           /* defport */
   CURLPROTO_HTTP,                       /* protocol */
   PROTOPT_NONE                          /* flags */
diff --git a/lib/rtsp.c b/lib/rtsp.c
index a408476f49..9e55f30c7d 100644
--- a/lib/rtsp.c
+++ b/lib/rtsp.c
@@ -63,6 +63,19 @@ static int rtsp_getsock_do(struct connectdata *conn,
                            curl_socket_t *socks,
                            int numsocks);
 
+/*
+ * Parse and write out any available RTP data.
+ *
+ * nread: amount of data left after k->str. will be modified if RTP
+ *        data is parsed and k->str is moved up
+ * readmore: whether or not the RTP parser needs more data right away
+ */
+static CURLcode rtsp_rtp_readwrite(struct SessionHandle *data,
+                                   struct connectdata *conn,
+                                   ssize_t *nread,
+                                   bool *readmore);
+
+
 /* this returns the socket to wait for in the DO and DOING state for the multi
    interface and then we're always _sending_ a request and thus we wait for
    the single socket to become writable only */
@@ -96,6 +109,7 @@ const struct Curl_handler Curl_handler_rtsp = {
   rtsp_getsock_do,                      /* doing_getsock */
   ZERO_NULL,                            /* perform_getsock */
   Curl_rtsp_disconnect,                 /* disconnect */
+  rtsp_rtp_readwrite,                   /* readwrite */
   PORT_RTSP,                            /* defport */
   CURLPROTO_RTSP,                       /* protocol */
   PROTOPT_NONE                          /* flags */
@@ -560,10 +574,11 @@ CURLcode Curl_rtsp(struct connectdata *conn, bool *done)
   return result;
 }
 
-CURLcode Curl_rtsp_rtp_readwrite(struct SessionHandle *data,
-                                 struct connectdata *conn,
-                                 ssize_t *nread,
-                                 bool *readmore) {
+
+static CURLcode rtsp_rtp_readwrite(struct SessionHandle *data,
+                                   struct connectdata *conn,
+                                   ssize_t *nread,
+                                   bool *readmore) {
   struct SingleRequest *k = &data->req;
   struct rtsp_conn *rtspc = &(conn->proto.rtspc);
 
diff --git a/lib/rtsp.h b/lib/rtsp.h
index 2e2074edc4..93016be7af 100644
--- a/lib/rtsp.h
+++ b/lib/rtsp.h
@@ -26,19 +26,6 @@
 
 extern const struct Curl_handler Curl_handler_rtsp;
 
-/*
- * Parse and write out any available RTP data.
- *
- * nread: amount of data left after k->str. will be modified if RTP
- *        data is parsed and k->str is moved up
- * readmore: whether or not the RTP parser needs more data right away
- */
-CURLcode Curl_rtsp_rtp_readwrite(struct SessionHandle *data,
-                                 struct connectdata *conn,
-                                 ssize_t *nread,
-                                 bool *readmore);
-
-
 /* protocol-specific functions set up to be called by the main engine */
 CURLcode Curl_rtsp(struct connectdata *conn, bool *done);
 CURLcode Curl_rtsp_done(struct connectdata *conn, CURLcode, bool premature);
diff --git a/lib/smtp.c b/lib/smtp.c
index e0e4216d3a..1626ae7dad 100644
--- a/lib/smtp.c
+++ b/lib/smtp.c
@@ -134,6 +134,7 @@ const struct Curl_handler Curl_handler_smtp = {
   smtp_getsock,                     /* doing_getsock */
   ZERO_NULL,                        /* perform_getsock */
   smtp_disconnect,                  /* disconnect */
+  ZERO_NULL,                        /* readwrite */
   PORT_SMTP,                        /* defport */
   CURLPROTO_SMTP,                   /* protocol */
   PROTOPT_CLOSEACTION               /* flags */
@@ -158,6 +159,7 @@ const struct Curl_handler Curl_handler_smtps = {
   smtp_getsock,                     /* doing_getsock */
   ZERO_NULL,                        /* perform_getsock */
   smtp_disconnect,                  /* disconnect */
+  ZERO_NULL,                        /* readwrite */
   PORT_SMTPS,                       /* defport */
   CURLPROTO_SMTP | CURLPROTO_SMTPS, /* protocol */
   PROTOPT_CLOSEACTION | PROTOPT_SSL /* flags */
@@ -182,6 +184,7 @@ static const struct Curl_handler Curl_handler_smtp_proxy = {
   ZERO_NULL,                            /* doing_getsock */
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
   PORT_SMTP,                            /* defport */
   CURLPROTO_HTTP,                       /* protocol */
   PROTOPT_NONE                          /* flags */
@@ -206,6 +209,7 @@ static const struct Curl_handler Curl_handler_smtps_proxy = {
   ZERO_NULL,                            /* doing_getsock */
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
   PORT_SMTPS,                           /* defport */
   CURLPROTO_HTTP,                       /* protocol */
   PROTOPT_NONE                          /* flags */
diff --git a/lib/ssh.c b/lib/ssh.c
index c0e1bc6441..7f42c7ea86 100644
--- a/lib/ssh.c
+++ b/lib/ssh.c
@@ -172,6 +172,7 @@ const struct Curl_handler Curl_handler_scp = {
   ssh_getsock,                          /* doing_getsock */
   ssh_perform_getsock,                  /* perform_getsock */
   scp_disconnect,                       /* disconnect */
+  ZERO_NULL,                            /* readwrite */
   PORT_SSH,                             /* defport */
   CURLPROTO_SCP,                        /* protocol */
   PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION /* flags */
@@ -195,6 +196,7 @@ const struct Curl_handler Curl_handler_sftp = {
   ssh_getsock,                          /* doing_getsock */
   ssh_perform_getsock,                  /* perform_getsock */
   sftp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
   PORT_SSH,                             /* defport */
   CURLPROTO_SFTP,                       /* protocol */
   PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION /* flags */
diff --git a/lib/telnet.c b/lib/telnet.c
index 0d810835a1..80592d27e9 100644
--- a/lib/telnet.c
+++ b/lib/telnet.c
@@ -195,6 +195,7 @@ const struct Curl_handler Curl_handler_telnet = {
   ZERO_NULL,                            /* doing_getsock */
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
   PORT_TELNET,                          /* defport */
   CURLPROTO_TELNET,                     /* protocol */
   PROTOPT_NONE                          /* flags */
diff --git a/lib/tftp.c b/lib/tftp.c
index d753d6d5a6..6612389870 100644
--- a/lib/tftp.c
+++ b/lib/tftp.c
@@ -196,6 +196,7 @@ const struct Curl_handler Curl_handler_tftp = {
   tftp_getsock,                         /* doing_getsock */
   ZERO_NULL,                            /* perform_getsock */
   tftp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
   PORT_TFTP,                            /* defport */
   CURLPROTO_TFTP,                       /* protocol */
   PROTOPT_NONE                          /* flags */
diff --git a/lib/transfer.c b/lib/transfer.c
index d250b106c3..87a03aa86e 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -467,16 +467,13 @@ static CURLcode readwrite_data(struct SessionHandle *data,
        in the flow below before the actual storing is done. */
     k->str = k->buf;
 
-#ifndef CURL_DISABLE_RTSP
-    /* Check for RTP at the beginning of the data */
-    if(conn->handler->protocol & CURLPROTO_RTSP) {
-      result = Curl_rtsp_rtp_readwrite(data, conn, &nread, &readmore);
+    if(conn->handler->readwrite) {
+      result = conn->handler->readwrite(data, conn, &nread, &readmore);
       if(result)
         return result;
       if(readmore)
         break;
     }
-#endif
 
 #ifndef CURL_DISABLE_HTTP
     /* Since this is a two-state thing, we check if we are parsing
@@ -488,17 +485,14 @@ static CURLcode readwrite_data(struct SessionHandle *data,
       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->handler->protocol & CURLPROTO_RTSP)) {
-        result = Curl_rtsp_rtp_readwrite(data, conn, &nread, &readmore);
+      if(conn->handler->readwrite &&
+         (k->maxdownload <= 0 && nread > 0)) {
+        result = conn->handler->readwrite(data, conn, &nread, &readmore);
         if(result)
           return result;
         if(readmore)
           break;
       }
-#endif
 
       if(stop_reading) {
         /* We've stopped dealing with input, get out of the do-while loop */
@@ -765,16 +759,13 @@ static CURLcode readwrite_data(struct SessionHandle *data,
 
     } /* if(! header and data to read ) */
 
-#ifndef CURL_DISABLE_RTSP
-    if(excess > 0 && !conn->bits.stream_was_rewound &&
-       (conn->handler->protocol & CURLPROTO_RTSP)) {
-      /* Check for RTP after the content if there is unrewound excess */
-
+    if(conn->handler->readwrite &&
+       (excess > 0 && !conn->bits.stream_was_rewound)) {
       /* Parse the excess data */
       k->str += nread;
       nread = (ssize_t)excess;
 
-      result = Curl_rtsp_rtp_readwrite(data, conn, &nread, &readmore);
+      result = conn->handler->readwrite(data, conn, &nread, &readmore);
       if(result)
         return result;
 
@@ -782,7 +773,6 @@ static CURLcode readwrite_data(struct SessionHandle *data,
         k->keepon |= KEEP_RECV; /* we're not done reading */
       break;
     }
-#endif
 
     if(is_empty_data) {
       /* if we received nothing, the server closed the connection and we
diff --git a/lib/url.c b/lib/url.c
index 30c9d7c021..6a3d81aaf6 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -265,6 +265,7 @@ static const struct Curl_handler Curl_handler_dummy = {
   ZERO_NULL,                            /* doing_getsock */
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
   0,                                    /* defport */
   0,                                    /* protocol */
   PROTOPT_NONE                          /* flags */
diff --git a/lib/urldata.h b/lib/urldata.h
index 3f080520af..e78dbbf3cd 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -684,6 +684,11 @@ struct Curl_handler {
    */
   CURLcode (*disconnect)(struct connectdata *, bool dead_connection);
 
+  /* If used, this function gets called from transfer.c:readwrite_data() to
+     allow the protocol to do extra reads/writes */
+  CURLcode (*readwrite)(struct SessionHandle *data, struct connectdata *conn,
+                        ssize_t *nread, bool *readmore);
+
   long defport;           /* Default port. */
   unsigned int protocol;  /* See CURLPROTO_*  */
   unsigned int flags;     /* Extra particular characteristics, see PROTOPT_* */
-- 
GitLab