summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Winship <danw@gnome.org>2009-06-23 19:07:05 -0400
committerDan Winship <danw@gnome.org>2009-06-23 19:07:05 -0400
commit6a9489d1b21bf7a5b45abf40a8b4b5af50f17883 (patch)
tree16b5334460ce09500c04f88173c7235187814bd4
parentd39f333e98c1e62e2527ad13e89c9a5d468dadeb (diff)
downloadlibsoup-gresolver.tar.gz
checkpointgresolver
-rw-r--r--libsoup/soup-gnutls.c99
-rw-r--r--libsoup/soup-socket.c273
-rw-r--r--libsoup/soup-ssl.h15
3 files changed, 148 insertions, 239 deletions
diff --git a/libsoup/soup-gnutls.c b/libsoup/soup-gnutls.c
index b5a5f32a..c44a89c7 100644
--- a/libsoup/soup-gnutls.c
+++ b/libsoup/soup-gnutls.c
@@ -171,33 +171,26 @@ again:
return G_IO_STATUS_NORMAL;
}
-static GIOStatus
-soup_gnutls_read (GIOChannel *channel,
- gchar *buf,
- gsize count,
- gsize *bytes_read,
- GError **err)
+gssize
+soup_ssl_session_receive (SoupSSLSession *session,
+ gchar *buffer, gsize size,
+ GCancellable *cancellable,
+ GError **error)
{
- SoupGNUTLSChannel *chan = (SoupGNUTLSChannel *) channel;
- gint result;
-
- *bytes_read = 0;
+ int result;
+ gssize nread = 0;
again:
- if (!chan->established) {
- result = do_handshake (chan, err);
+ if (!session->established) {
+ if (!do_handshake (session, error))
+ return -1;
- if (result == G_IO_STATUS_AGAIN ||
- result == G_IO_STATUS_ERROR)
- return result;
-
- chan->established = TRUE;
+ session->established = TRUE;
}
- result = gnutls_record_recv (chan->session, buf, count);
-
+ result = gnutls_record_recv (session->gnutls_session, buffer, size);
if (result == GNUTLS_E_REHANDSHAKE) {
- chan->established = FALSE;
+ session->established = FALSE;
goto again;
}
@@ -407,40 +400,17 @@ soup_gnutls_push_func (gnutls_transport_ptr_t transport_data,
return nwrote;
}
-/**
- * soup_ssl_wrap_iochannel:
- * @sock: a #GIOChannel wrapping a TCP socket.
- * @non_blocking: whether the underlying socket is blocking or not
- * @type: whether this is a client or server socket
- * @remote_host: the hostname of the remote machine
- * @creds: a client or server credentials structure
- *
- * This attempts to wrap a new #GIOChannel around @sock that
- * will SSL-encrypt/decrypt all traffic through it.
- *
- * Return value: an SSL-encrypting #GIOChannel, or %NULL on
- * failure.
- **/
-GIOChannel *
-soup_ssl_wrap_iochannel (GIOChannel *sock, gboolean non_blocking,
- SoupSSLType type, const char *remote_host,
- SoupSSLCredentials *creds)
+SoupSSLSession *
+soup_ssl_session_new (GSocket *gsock, SoupSSLType type,
+ const char *remote_host, SoupSSLCredentials *creds)
{
- SoupGNUTLSChannel *chan = NULL;
- GIOChannel *gchan = NULL;
+ SoupSSLSession *sss = NULL;
gnutls_session session = NULL;
- int sockfd;
int ret;
- g_return_val_if_fail (sock != NULL, NULL);
+ g_return_val_if_fail (gsock != NULL, NULL);
g_return_val_if_fail (creds != NULL, NULL);
- sockfd = g_io_channel_unix_get_fd (sock);
- if (!sockfd) {
- g_warning ("Failed to get channel fd.");
- goto THROW_CREATE_ERROR;
- }
-
ret = gnutls_init (&session,
(type == SOUP_SSL_TYPE_CLIENT) ? GNUTLS_CLIENT : GNUTLS_SERVER);
if (ret)
@@ -456,27 +426,18 @@ soup_ssl_wrap_iochannel (GIOChannel *sock, gboolean non_blocking,
if (type == SOUP_SSL_TYPE_SERVER)
gnutls_dh_set_prime_bits (session, DH_BITS);
- chan = g_slice_new0 (SoupGNUTLSChannel);
- chan->real_sock = sock;
- chan->sockfd = sockfd;
- chan->session = session;
- chan->creds = creds;
- chan->hostname = g_strdup (remote_host);
- chan->type = type;
- chan->non_blocking = non_blocking;
- g_io_channel_ref (sock);
-
- gnutls_transport_set_ptr (session, chan);
+ sss = g_slice_new0 (SoupSSLSession);
+ sss->gsock = g_object_ref (gsock);
+ sss->session = session;
+ sss->creds = creds;
+ sss->hostname = g_strdup (remote_host);
+ sss->type = type;
+
+ gnutls_transport_set_ptr (session, sss);
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);
- gchan->is_readable = gchan->is_writeable = TRUE;
- gchan->use_buffer = FALSE;
-
- return gchan;
+ return sss;
THROW_CREATE_ERROR:
if (session)
@@ -484,6 +445,12 @@ soup_ssl_wrap_iochannel (GIOChannel *sock, gboolean non_blocking,
return NULL;
}
+gssize soup_ssl_session_send (SoupSSLSession *session,
+ const gchar *buffer,
+ gsize size,
+ GCancellable *cancellable,
+ GError **error);
+
#if defined(GCRY_THREAD_OPTION_PTHREAD_IMPL) && !defined(G_OS_WIN32)
GCRY_THREAD_OPTION_PTHREAD_IMPL;
#endif
diff --git a/libsoup/soup-socket.c b/libsoup/soup-socket.c
index 51a0668e..cc114bb1 100644
--- a/libsoup/soup-socket.c
+++ b/libsoup/soup-socket.c
@@ -64,7 +64,7 @@ enum {
typedef struct {
int sockfd;
SoupAddress *local_addr, *remote_addr;
- GIOChannel *iochannel;
+ GSocket *gsock;
guint non_blocking:1;
guint is_server:1;
@@ -82,12 +82,6 @@ typedef struct {
} SoupSocketPrivate;
#define SOUP_SOCKET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_SOCKET, SoupSocketPrivate))
-#ifdef HAVE_IPV6
-#define soup_sockaddr_max sockaddr_in6
-#else
-#define soup_sockaddr_max sockaddr_in
-#endif
-
static void set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec);
static void get_property (GObject *object, guint prop_id,
@@ -121,8 +115,8 @@ soup_socket_init (SoupSocket *sock)
static void
disconnect_internal (SoupSocketPrivate *priv)
{
- g_io_channel_unref (priv->iochannel);
- priv->iochannel = NULL;
+ g_object_unref (priv->gsock);
+ priv->gsock = NULL;
priv->sockfd = -1;
if (priv->read_src) {
@@ -148,7 +142,7 @@ finalize (GObject *object)
{
SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
- if (priv->iochannel)
+ if (priv->gsock)
disconnect_internal (priv);
if (priv->local_addr)
@@ -175,10 +169,6 @@ soup_socket_class_init (SoupSocketClass *socket_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (socket_class);
-#ifdef SIGPIPE
- signal (SIGPIPE, SIG_IGN);
-#endif
-
g_type_class_add_private (socket_class, sizeof (SoupSocketPrivate));
/* virtual method override */
@@ -373,42 +363,10 @@ soup_socket_class_init (SoupSocketClass *socket_class)
"Value in seconds to timeout a blocking I/O",
0, G_MAXUINT, 0,
G_PARAM_READWRITE));
-
-#ifdef G_OS_WIN32
- /* Make sure WSAStartup() gets called. */
- soup_address_get_type ();
-#endif
}
static void
-set_nonblocking (SoupSocketPrivate *priv)
-{
-#ifndef G_OS_WIN32
- int flags;
-#else
- u_long val;
-#endif
-
- if (priv->sockfd == -1)
- return;
-
-#ifndef G_OS_WIN32
- flags = fcntl (priv->sockfd, F_GETFL, 0);
- if (flags != -1) {
- if (priv->non_blocking)
- flags |= O_NONBLOCK;
- else
- flags &= ~O_NONBLOCK;
- fcntl (priv->sockfd, F_SETFL, flags);
- }
-#else
- val = priv->non_blocking ? 1 : 0;
- ioctlsocket (priv->sockfd, FIONBIO, &val);
-#endif
-}
-
-static void
set_fdflags (SoupSocketPrivate *priv)
{
int opt;
@@ -420,21 +378,9 @@ set_fdflags (SoupSocketPrivate *priv)
if (priv->sockfd == -1)
return;
- set_nonblocking (priv);
-
-#ifndef G_OS_WIN32
- flags = fcntl (priv->sockfd, F_GETFD, 0);
- if (flags != -1) {
- flags |= FD_CLOEXEC;
- fcntl (priv->sockfd, F_SETFD, flags);
- }
-#endif
-
opt = 1;
setsockopt (priv->sockfd, IPPROTO_TCP,
TCP_NODELAY, (void *) &opt, sizeof (opt));
- setsockopt (priv->sockfd, SOL_SOCKET,
- SO_REUSEADDR, (void *) &opt, sizeof (opt));
#ifndef G_OS_WIN32
timeout.tv_sec = priv->timeout;
@@ -459,16 +405,8 @@ set_fdflags (SoupSocketPrivate *priv)
SO_SNDTIMEO, (void *) &opt, sizeof (opt));
#endif
-#ifndef G_OS_WIN32
- priv->iochannel =
- g_io_channel_unix_new (priv->sockfd);
-#else
- priv->iochannel =
- g_io_channel_win32_new_socket (priv->sockfd);
-#endif
- g_io_channel_set_close_on_unref (priv->iochannel, TRUE);
- g_io_channel_set_encoding (priv->iochannel, NULL, NULL);
- g_io_channel_set_buffered (priv->iochannel, FALSE);
+ priv->gsock = g_socket_new_from_fd (priv->sockfd, NULL);
+ g_socket_set_blocking (priv->gsock, !priv->non_blocking);
}
static void
@@ -486,7 +424,8 @@ set_property (GObject *object, guint prop_id,
break;
case PROP_NON_BLOCKING:
priv->non_blocking = g_value_get_boolean (value);
- set_nonblocking (priv);
+ if (priv->gsock)
+ g_socket_set_blocking (priv->gsock, !priv->non_blocking);
break;
case PROP_SSL_CREDENTIALS:
priv->ssl_creds = g_value_get_pointer (value);
@@ -566,7 +505,6 @@ soup_socket_new (const char *optname1, ...)
typedef struct {
SoupSocket *sock;
GCancellable *cancellable;
- guint cancel_id;
SoupSocketCallback callback;
gpointer user_data;
} SoupSocketAsyncConnectData;
@@ -579,8 +517,6 @@ idle_connect_result (gpointer user_data)
guint status;
priv->watch_src = NULL;
- if (sacd->cancel_id)
- g_signal_handler_disconnect (sacd->cancellable, sacd->cancel_id);
if (priv->sockfd == -1) {
if (g_cancellable_is_cancelled (sacd->cancellable))
@@ -596,21 +532,13 @@ idle_connect_result (gpointer user_data)
}
static gboolean
-connect_watch (GIOChannel* iochannel, GIOCondition condition, gpointer data)
+connect_watch (GSocket *sock, GIOCondition condition, gpointer data)
{
SoupSocketAsyncConnectData *sacd = data;
SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sacd->sock);
- int error = 0;
- int len = sizeof (error);
- /* Remove the watch now in case we don't return immediately */
- g_source_destroy (priv->watch_src);
- priv->watch_src = NULL;
-
- if ((condition & ~(G_IO_IN | G_IO_OUT)) ||
- (getsockopt (priv->sockfd, SOL_SOCKET, SO_ERROR,
- (void *)&error, (void *)&len) != 0) ||
- error)
+ if (g_cancellable_is_cancelled (sacd->cancellable) ||
+ !g_socket_check_connect_result (priv->gsock))
disconnect_internal (priv);
return idle_connect_result (sacd);
@@ -632,45 +560,61 @@ got_address (SoupAddress *addr, guint status, gpointer user_data)
g_slice_free (SoupSocketAsyncConnectData, sacd);
}
-static void
-async_cancel (GCancellable *cancellable, gpointer user_data)
-{
- SoupSocketAsyncConnectData *sacd = user_data;
- SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sacd->sock);
-
- if (priv->watch_src)
- g_source_destroy (priv->watch_src);
- disconnect_internal (priv);
- priv->watch_src = soup_add_completion (priv->async_context,
- idle_connect_result, sacd);
-}
-
static guint
-socket_connect_internal (SoupSocket *sock)
+socket_connect_internal (SoupSocket *sock, GCancellable *cancellable)
{
SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
- struct sockaddr *sa;
- int len, status;
+ GSocketAddress *addr;
+ GError *error = NULL;
+ int status;
- sa = soup_address_get_sockaddr (priv->remote_addr, &len);
- if (!sa)
+ addr = soup_address_get_gsockaddr (priv->remote_addr);
+ if (!addr)
return SOUP_STATUS_CANT_RESOLVE;
- priv->sockfd = socket (sa->sa_family, SOCK_STREAM, 0);
+ priv->sockfd = socket (soup_address_get_family (priv->remote_addr),
+ SOCK_STREAM, 0);
if (SOUP_IS_INVALID_SOCKET (priv->sockfd))
return SOUP_STATUS_CANT_CONNECT;
set_fdflags (priv);
- status = connect (priv->sockfd, sa, len);
+ if (priv->non_blocking) {
+ if (g_socket_connect (priv->gsock, addr, &error))
+ return SOUP_STATUS_OK;
- if (SOUP_IS_SOCKET_ERROR (status)) {
- if (SOUP_IS_CONNECT_STATUS_INPROGRESS ())
+ if (error->domain == G_IO_ERROR &&
+ error->code == G_IO_ERROR_PENDING) {
+ g_error_free (error);
return SOUP_STATUS_CONTINUE;
+ }
+ g_error_free (error);
+ } else {
+ if (!g_socket_condition_wait (priv->gsock, G_IO_OUT,
+ cancellable, NULL)) {
+ disconnect_internal (priv);
+ return SOUP_STATUS_CANCELLED;
+ }
+ if (g_socket_connect (priv->gsock, addr, NULL))
+ return SOUP_STATUS_OK;
+ }
- disconnect_internal (priv);
- return SOUP_STATUS_CANT_CONNECT;
- } else
- return SOUP_STATUS_OK;
+ disconnect_internal (priv);
+ return SOUP_STATUS_CANT_CONNECT;
+}
+
+static GSource *
+soup_socket_create_watch (SoupSocketPrivate *priv, GIOCondition cond,
+ GIOFunc callback, gpointer user_data,
+ GCancellable *cancellable)
+{
+ GSource *watch;
+
+ watch = g_socket_create_source (priv->gsock, cond, cancellable);
+ g_source_set_callback (watch, callback, user_data);
+ g_source_attach (watch, priv->async_context);
+ g_source_unref (watch);
+
+ return watch;
}
/**
@@ -723,36 +667,22 @@ soup_socket_connect_async (SoupSocket *sock, GCancellable *cancellable,
return;
}
- status = socket_connect_internal (sock);
+ status = socket_connect_internal (sock, NULL);
if (status == SOUP_STATUS_CONTINUE) {
/* Wait for connect to succeed or fail */
priv->watch_src =
- soup_add_io_watch (priv->async_context,
- priv->iochannel,
- G_IO_IN | G_IO_OUT |
- G_IO_PRI | G_IO_ERR |
- G_IO_HUP | G_IO_NVAL,
- connect_watch, sacd);
- if (cancellable) {
- sacd->cancel_id =
- g_signal_connect (cancellable, "cancelled",
- G_CALLBACK (async_cancel),
- sacd);
- }
+ soup_socket_create_watch (priv,
+ G_IO_IN | G_IO_OUT |
+ G_IO_PRI | G_IO_ERR |
+ G_IO_HUP | G_IO_NVAL,
+ connect_watch, sacd,
+ cancellable);
} else {
priv->watch_src = soup_add_completion (priv->async_context,
idle_connect_result, sacd);
}
}
-static void
-sync_cancel (GCancellable *cancellable, gpointer sock)
-{
- SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
-
- shutdown (priv->sockfd, SHUT_RDWR);
-}
-
/**
* soup_socket_connect_sync:
* @sock: a client #SoupSocket (which must not already be connected)
@@ -770,7 +700,6 @@ guint
soup_socket_connect_sync (SoupSocket *sock, GCancellable *cancellable)
{
SoupSocketPrivate *priv;
- guint status, cancel_id;
g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_STATUS_MALFORMED);
priv = SOUP_SOCKET_GET_PRIVATE (sock);
@@ -785,39 +714,24 @@ soup_socket_connect_sync (SoupSocket *sock, GCancellable *cancellable)
return status;
}
- if (cancellable) {
- cancel_id = g_signal_connect (cancellable, "cancelled",
- G_CALLBACK (sync_cancel), sock);
- }
-
- status = socket_connect_internal (sock);
-
- if (cancellable) {
- if (status != SOUP_STATUS_OK &&
- g_cancellable_is_cancelled (cancellable)) {
- status = SOUP_STATUS_CANCELLED;
- disconnect_internal (priv);
- }
- g_signal_handler_disconnect (cancellable, cancel_id);
- }
-
- return status;
+ return socket_connect_internal (sock, cancellable);
}
static gboolean
-listen_watch (GIOChannel* iochannel, GIOCondition condition, gpointer data)
+listen_watch (GSocket *gsock, GIOCondition condition, gpointer data)
{
SoupSocket *sock = data, *new;
SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock), *new_priv;
- struct soup_sockaddr_max sa;
+ struct sockaddr_storage sa;
int sa_len, sockfd;
if (condition & (G_IO_HUP | G_IO_ERR)) {
- g_source_destroy (priv->watch_src);
priv->watch_src = NULL;
return FALSE;
}
+ /* Using g_socket_accept() here would require more rewriting... */
+
sa_len = sizeof (sa);
sockfd = accept (priv->sockfd, (struct sockaddr *)&sa, (void *)&sa_len);
if (SOUP_IS_INVALID_SOCKET (sockfd))
@@ -863,8 +777,7 @@ soup_socket_listen (SoupSocket *sock)
{
SoupSocketPrivate *priv;
- struct sockaddr *sa;
- int sa_len;
+ GSocketAddress *addr;
g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
priv = SOUP_SOCKET_GET_PRIVATE (sock);
@@ -879,33 +792,34 @@ soup_socket_listen (SoupSocket *sock)
* have to make a new addr by calling getsockname(), which
* will have the right port number.
*/
- sa = soup_address_get_sockaddr (priv->local_addr, &sa_len);
- g_return_val_if_fail (sa != NULL, FALSE);
+ addr = soup_address_get_gsockaddr (priv->local_addr);
+ g_return_val_if_fail (addr != NULL, FALSE);
- priv->sockfd = socket (sa->sa_family, SOCK_STREAM, 0);
+ priv->sockfd = socket (soup_address_get_family (priv->local_addr),
+ SOCK_STREAM, 0);
if (SOUP_IS_INVALID_SOCKET (priv->sockfd))
goto cant_listen;
set_fdflags (priv);
/* Bind */
- if (bind (priv->sockfd, sa, sa_len) != 0)
+ if (!g_socket_bind (priv->gsock, addr, TRUE, NULL))
goto cant_listen;
/* Force local_addr to be re-resolved now */
g_object_unref (priv->local_addr);
priv->local_addr = NULL;
/* Listen */
- if (listen (priv->sockfd, 10) != 0)
+ if (!g_socket_listen (priv->gsock, NULL))
goto cant_listen;
- priv->watch_src = soup_add_io_watch (priv->async_context,
- priv->iochannel,
- G_IO_IN | G_IO_ERR | G_IO_HUP,
- listen_watch, sock);
+ priv->watch_src = soup_socket_create_watch (priv,
+ G_IO_IN | G_IO_ERR | G_IO_HUP,
+ listen_watch, sock,
+ NULL);
return TRUE;
cant_listen:
- if (priv->iochannel)
+ if (priv->gsock)
disconnect_internal (priv);
return FALSE;
@@ -1048,7 +962,7 @@ soup_socket_is_connected (SoupSocket *sock)
g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
priv = SOUP_SOCKET_GET_PRIVATE (sock);
- return priv->iochannel != NULL;
+ return priv->gsock != NULL;
}
/**
@@ -1069,7 +983,7 @@ soup_socket_get_local_address (SoupSocket *sock)
g_mutex_lock (priv->addrlock);
if (!priv->local_addr) {
- struct soup_sockaddr_max bound_sa;
+ struct sockaddr_storage bound_sa;
int sa_len;
sa_len = sizeof (bound_sa);
@@ -1099,7 +1013,7 @@ soup_socket_get_remote_address (SoupSocket *sock)
g_mutex_lock (priv->addrlock);
if (!priv->remote_addr) {
- struct soup_sockaddr_max bound_sa;
+ struct sockaddr_storage bound_sa;
int sa_len;
sa_len = sizeof (bound_sa);
@@ -1137,7 +1051,7 @@ socket_timeout (gpointer sock)
}
static gboolean
-socket_read_watch (GIOChannel *chan, GIOCondition cond, gpointer user_data)
+socket_read_watch (GSocket *gsock, GIOCondition cond, gpointer user_data)
{
SoupSocket *sock = user_data;
SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
@@ -1158,7 +1072,7 @@ socket_read_watch (GIOChannel *chan, GIOCondition cond, gpointer user_data)
static SoupSocketIOStatus
read_from_network (SoupSocket *sock, gpointer buffer, gsize len,
- gsize *nread, GError **error)
+ gsize *nread, GCancellable *cancellable, GError **error)
{
SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
GIOStatus status;
@@ -1167,14 +1081,31 @@ read_from_network (SoupSocket *sock, gpointer buffer, gsize len,
*nread = 0;
- if (!priv->iochannel)
+ if (!priv->gsock)
return SOUP_SOCKET_EOF;
if (priv->timed_out)
return SOUP_SOCKET_ERROR;
- status = g_io_channel_read_chars (priv->iochannel,
- buffer, len, nread, &my_err);
+ while (1) {
+ if (!priv->non_blocking) {
+ if (!g_socket_condition_wait (priv->gsock, G_IO_IN,
+ cancellable, &my_err))
+ break;
+ }
+
+ my_nread = g_socket_receive (priv->gsock, buffer, len, &my_err);
+
+ if (my_err->domain == G_IO_ERROR &&
+ my_err->code == G_IO_ERROR_PENDING) {
+ g_error_free (my_err);
+ if (priv->non_blocking)
+ return SOUP_SOCKET_WOULD_BLOCK;
+ else
+ continue;
+ }
+ }
+
if (my_err) {
if (my_err->domain == SOUP_SSL_ERROR &&
my_err->code == SOUP_SSL_ERROR_HANDSHAKE_NEEDS_WRITE)
diff --git a/libsoup/soup-ssl.h b/libsoup/soup-ssl.h
index f4e3eab1..c3037e90 100644
--- a/libsoup/soup-ssl.h
+++ b/libsoup/soup-ssl.h
@@ -14,6 +14,7 @@ typedef enum {
} SoupSSLType;
typedef struct SoupSSLCredentials SoupSSLCredentials;
+typedef struct SoupSSLSession SoupSSLSession;
SoupSSLCredentials *soup_ssl_get_client_credentials (const char *ca_file);
void soup_ssl_free_client_credentials (SoupSSLCredentials *creds);
@@ -22,10 +23,20 @@ SoupSSLCredentials *soup_ssl_get_server_credentials (const char *cert_f
const char *key_file);
void soup_ssl_free_server_credentials (SoupSSLCredentials *creds);
-GIOChannel *soup_ssl_wrap_iochannel (GIOChannel *sock,
- gboolean non_blocking,
+SoupSSLSession *soup_ssl_session_new (GSocket *gsock,
SoupSSLType type,
const char *remote_host,
SoupSSLCredentials *creds);
+gssize soup_ssl_session_receive (SoupSSLSession *session,
+ gchar *buffer,
+ gsize size,
+ GCancellable *cancellable,
+ GError **error);
+gssize soup_ssl_session_send (SoupSSLSession *session,
+ const gchar *buffer,
+ gsize size,
+ GCancellable *cancellable,
+ GError **error);
+
#endif /* SOUP_SSL_H */