[libsoup] Bug 578928 – SOUP_SESSION_TIMEOUT does not work with https



commit 634fad5f8959e893d1ee144a7d67f2d1b302e363
Author: Dan Winship <danw gnome org>
Date:   Sat Apr 18 08:31:48 2009 -0400

    Bug 578928 â?? SOUP_SESSION_TIMEOUT does not work with https
    
    soup-gnutls.c: Fix error-code logic to return G_IO_STATUS_AGAIN even
    with synchronous connections, if the underlying socket operation
    returns EAGAIN.
---
 libsoup/soup-gnutls.c |   39 ++++++++++++++++++++++++++++++++++-----
 1 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/libsoup/soup-gnutls.c b/libsoup/soup-gnutls.c
index 41f075d..b5a5f32 100644
--- a/libsoup/soup-gnutls.c
+++ b/libsoup/soup-gnutls.c
@@ -15,6 +15,7 @@
 #include <fcntl.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 #include <glib.h>
 
@@ -46,7 +47,8 @@ struct SoupSSLCredentials {
 typedef struct {
 	GIOChannel channel;
 	GIOChannel *real_sock;
-	gboolean non_blocking;
+	int sockfd;
+	gboolean non_blocking, eagain;
 	gnutls_session session;
 	SoupSSLCredentials *creds;
 	char *hostname;
@@ -200,7 +202,7 @@ again:
 	}
 
 	if (result == GNUTLS_E_INTERRUPTED || result == GNUTLS_E_AGAIN) {
-		if (chan->non_blocking)
+		if (chan->non_blocking || chan->eagain)
 			return G_IO_STATUS_AGAIN;
 		else
 			goto again;
@@ -265,7 +267,7 @@ again:
 	}
 
 	if (result == GNUTLS_E_INTERRUPTED || result == GNUTLS_E_AGAIN) {
-		if (chan->non_blocking)
+		if (chan->non_blocking || chan->eagain)
 			return G_IO_STATUS_AGAIN;
 		else
 			goto again;
@@ -381,6 +383,30 @@ init_dh_params (void)
 	return dh_params != NULL;
 }
 
+static ssize_t
+soup_gnutls_pull_func (gnutls_transport_ptr_t transport_data,
+		       void *buf, size_t buflen)
+{
+	SoupGNUTLSChannel *chan = transport_data;
+	ssize_t nread;
+
+	nread = read (chan->sockfd, buf, buflen);
+	chan->eagain = (nread == -1 && errno == EAGAIN);
+	return nread;
+}
+
+static ssize_t
+soup_gnutls_push_func (gnutls_transport_ptr_t transport_data,
+		       const void *buf, size_t buflen)
+{
+	SoupGNUTLSChannel *chan = transport_data;
+	ssize_t nwrote;
+
+	nwrote = write (chan->sockfd, buf, buflen);
+	chan->eagain = (nwrote == -1 && errno == EAGAIN);
+	return nwrote;
+}
+
 /**
  * soup_ssl_wrap_iochannel:
  * @sock: a #GIOChannel wrapping a TCP socket.
@@ -430,10 +456,9 @@ soup_ssl_wrap_iochannel (GIOChannel *sock, gboolean non_blocking,
 	if (type == SOUP_SSL_TYPE_SERVER)
 		gnutls_dh_set_prime_bits (session, DH_BITS);
 
-	gnutls_transport_set_ptr (session, GINT_TO_POINTER (sockfd));
-
 	chan = g_slice_new0 (SoupGNUTLSChannel);
 	chan->real_sock = sock;
+	chan->sockfd = sockfd;
 	chan->session = session;
 	chan->creds = creds;
 	chan->hostname = g_strdup (remote_host);
@@ -441,6 +466,10 @@ soup_ssl_wrap_iochannel (GIOChannel *sock, gboolean non_blocking,
 	chan->non_blocking = non_blocking;
 	g_io_channel_ref (sock);
 
+	gnutls_transport_set_ptr (session, chan);
+	gnutls_transport_set_push_function (session, soup_gnutls_push_func);
+	gnutls_transport_set_pull_function (session, soup_gnutls_pull_func);
+
 	gchan = (GIOChannel *) chan;
 	gchan->funcs = (GIOFuncs *)&soup_gnutls_channel_funcs;
 	g_io_channel_init (gchan);



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