[RFC 3/3] imap_send: add support for curl over tunnel

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Starting from libcurl 7.21.5, libcurl can be tricked into using
an already open socket.
This allows to use tunneling with libcurl instead of the legacy imap code.

Signed-off-by: Nicolas Morey-Chaisemartin <nicolas@xxxxxxxxxxxxxxxxxxxxxx>
---
 Documentation/git-imap-send.txt |  4 ++--
 imap-send.c                     | 45 +++++++++++++++++++++++++++++++++++------
 2 files changed, 41 insertions(+), 8 deletions(-)

diff --git a/Documentation/git-imap-send.txt b/Documentation/git-imap-send.txt
index 5d1e4c80c..e765c08d7 100644
--- a/Documentation/git-imap-send.txt
+++ b/Documentation/git-imap-send.txt
@@ -38,8 +38,8 @@ OPTIONS
 	Be quiet.
 
 --curl::
-	Use libcurl to communicate with the IMAP server, unless tunneling
-	into it.  Ignored if Git was built without the USE_CURL_FOR_IMAP_SEND
+	Use libcurl to communicate with the IMAP server.
+	Ignored if Git was built without the USE_CURL_FOR_IMAP_SEND
 	option set.
 
 --no-curl::
diff --git a/imap-send.c b/imap-send.c
index e5ff70096..31b93d873 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -1408,6 +1408,26 @@ static int append_msgs_to_imap(struct imap_server_conf *server,
 }
 
 #ifdef USE_CURL_FOR_IMAP_SEND
+static curl_socket_t curl_tunnel_socket(void *clientp,
+					curlsocktype purpose,
+					struct curl_sockaddr *address)
+{
+	return (unsigned long)clientp;
+}
+
+static int sockopt_callback(void *clientp, curl_socket_t curlfd,
+				 curlsocktype purpose)
+{
+	/* CURL_SOCKOPT_ALREADY_CONNECTED was intreocued in 7.21.5
+	 * and is needed to get curl working on an existing fd */
+#if LIBCURL_VERSION_NUM >= 0x071505
+	return CURL_SOCKOPT_ALREADY_CONNECTED;
+#else
+	return CURL_SOCKOPT_ERROR;
+#endif
+}
+
+
 static CURL *setup_curl(struct imap_server_conf *srvc)
 {
 	CURL *curl;
@@ -1424,8 +1444,21 @@ static CURL *setup_curl(struct imap_server_conf *srvc)
 	curl_easy_setopt(curl, CURLOPT_USERNAME, server.user);
 	curl_easy_setopt(curl, CURLOPT_PASSWORD, server.pass);
 
-	strbuf_addstr(&path, server.use_ssl ? "imaps://" : "imap://");
-	strbuf_addstr(&path, server.host);
+	if (srvc->tunnel) {
+		int fds[2];
+
+		setup_tunnel(srvc, fds);
+		curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, curl_tunnel_socket);
+		curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, (unsigned long)fds[0]);
+		curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback);
+		/* Create a fake hostname to avoid resolution issue and in case
+		 * imap.host was not set */
+		strbuf_addstr(&path, "imap://localhost");
+	} else {
+		strbuf_addstr(&path, server.use_ssl ? "imaps://" : "imap://");
+		strbuf_addstr(&path, server.host);
+	}
+
 	if (!path.len || path.buf[path.len - 1] != '/')
 		strbuf_addch(&path, '/');
 	strbuf_addstr(&path, server.folder);
@@ -1570,12 +1603,12 @@ int cmd_main(int argc, const char **argv)
 
 	/* write it to the imap server */
 
-	if (server.tunnel)
-		return append_msgs_to_imap(&server, &all_msgs, total);
-
 #ifdef USE_CURL_FOR_IMAP_SEND
 	if (use_curl)
-		return curl_append_msgs_to_imap(&server, &all_msgs, total);
+#if LIBCURL_VERSION_NUM < 0x071505
+		if (!server.tunnel)
+#endif
+			return curl_append_msgs_to_imap(&server, &all_msgs, total);
 #endif
 
 	return append_msgs_to_imap(&server, &all_msgs, total);
-- 
2.14.0.3.gb4ff627ec.dirty




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux