Commit a1690339 authored by Dan Winship's avatar Dan Winship

make GProxyConnection public, as GTcpWrapperConnection

GProxyConnection is a class that was added for proxy support;
g_socket_client_connect() returns a GSocketConnection, but in some
cases (eg, encrypted SOCKS), GProxy might return a GIOStream that is
not a GSocketConnection. In that case, GSocketClient would wrap the
stream up in a GProxyConnection, which is a subclass of
GSocketConnection but uses the input/output streams of the wrapped
connection.

GTlsConnection is not a GSocketConnection, so it has the same problem,
so it will need the same treatment. Rename the class to
GTcpWrapperStream, and make it public, so people can extract the base
stream from it when necessary.

(This is not ideal and GSocketClient will need to be revisited as an
API at some point...)

https://bugzilla.gnome.org/show_bug.cgi?id=588189
parent c20c2c0a
......@@ -120,6 +120,7 @@
<xi:include href="xml/gsocketconnection.xml"/>
<xi:include href="xml/gunixconnection.xml"/>
<xi:include href="xml/gtcpconnection.xml"/>
<xi:include href="xml/gtcpwrapperconnection.xml"/>
<xi:include href="xml/gsocketlistener.xml"/>
<xi:include href="xml/gsocketservice.xml"/>
<xi:include href="xml/gthreadedsocketservice.xml"/>
......
......@@ -1882,6 +1882,25 @@ GTcpConnectionPrivate
g_tcp_connection_get_type
</SECTION>
<SECTION>
<FILE>gtcpwrapperconnection</FILE>
<TITLE>GTcpWrapperConnection</TITLE>
GTcpWrapperConnection
g_tcp_wrapper_connection_new
g_tcp_wrapper_connection_get_base_io_stream
<SUBSECTION Standard>
GTcpWrapperConnectionClass
G_IS_TCP_WRAPPER_CONNECTION
G_IS_TCP_WRAPPER_CONNECTION_CLASS
G_TYPE_TCP_WRAPPER_CONNECTION
G_TCP_WRAPPER_CONNECTION
G_TCP_WRAPPER_CONNECTION_CLASS
G_TCP_WRAPPER_CONNECTION_GET_CLASS
<SUBSECTION Private>
GTcpWrapperConnectionPrivate
g_tcp_wrapper_connection_get_type
</SECTION>
<SECTION>
<FILE>gsocketcontrolmessage</FILE>
<TITLE>GSocketControlMessage</TITLE>
......
......@@ -105,6 +105,7 @@ g_socket_service_get_type
g_socket_type_get_type
g_srv_target_get_type
g_tcp_connection_get_type
g_tcp_wrapper_connection_get_type
g_themed_icon_get_type
g_threaded_socket_service_get_type
g_unix_connection_get_type
......
......@@ -373,11 +373,10 @@ libgio_2_0_la_SOURCES = \
gproxy.c \
gproxyaddress.c \
gproxyaddressenumerator.c \
gproxyconnection.c \
gproxyconnection.h \
gsocketservice.c \
gsrvtarget.c \
gtcpconnection.c \
gtcpwrapperconnection.c \
gthreadedsocketservice.c\
gthemedicon.c \
gthreadedresolver.c \
......@@ -528,6 +527,7 @@ gio_headers = \
gsocketservice.h \
gsrvtarget.h \
gtcpconnection.h \
gtcpwrapperconnection.h \
gthreadedsocketservice.h\
gthemedicon.h \
gvfs.h \
......
......@@ -117,6 +117,7 @@
#include <gio/gsocketservice.h>
#include <gio/gsrvtarget.h>
#include <gio/gtcpconnection.h>
#include <gio/gtcpwrapperconnection.h>
#include <gio/gthemedicon.h>
#include <gio/gthreadedsocketservice.h>
#include <gio/gvfs.h>
......
......@@ -1994,3 +1994,11 @@ g_pollable_output_stream_is_writable
g_pollable_output_stream_write_nonblocking
#endif
#endif
#if IN_HEADER(__G_TCP_WRAPPER_CONNECTION_H__)
#if IN_FILE(__G_TCP_WRAPPER_CONNECTION_C__)
g_tcp_wrapper_connection_get_type G_GNUC_CONST
g_tcp_wrapper_connection_get_base_io_stream
g_tcp_wrapper_connection_new
#endif
#endif
......@@ -191,6 +191,7 @@ typedef struct _GSrvTarget GSrvTarget;
* Since: 2.22
**/
typedef struct _GTcpConnection GTcpConnection;
typedef struct _GTcpWrapperConnection GTcpWrapperConnection;
/**
* GThreadedSocketService:
*
......
......@@ -34,16 +34,17 @@
#include <gio/gsocketconnection.h>
#include <gio/gproxyaddressenumerator.h>
#include <gio/gproxyaddress.h>
#include <gio/gproxyconnection.h>
#include <gio/gsimpleasyncresult.h>
#include <gio/gcancellable.h>
#include <gio/gioerror.h>
#include <gio/gsocket.h>
#include <gio/gnetworkaddress.h>
#include <gio/gnetworkservice.h>
#include <gio/gpollableiostream.h>
#include <gio/gproxy.h>
#include <gio/gsocketaddress.h>
#include <gio/gtcpconnection.h>
#include <gio/gtcpwrapperconnection.h>
#include "glibintl.h"
......@@ -679,14 +680,15 @@ g_socket_client_connect (GSocketClient *client,
g_clear_error (&last_error);
socket = create_socket (client, address, &last_error);
if (socket != NULL)
if (socket == NULL)
{
if (g_socket_connect (socket, address, cancellable, &last_error))
connection = g_socket_connection_factory_create_connection (socket);
g_object_unref (socket);
g_object_unref (address);
continue;
}
if (g_socket_connect (socket, address, cancellable, &last_error))
connection = g_socket_connection_factory_create_connection (socket);
if (connection &&
G_IS_PROXY_ADDRESS (address) &&
client->priv->enable_proxy)
......@@ -716,31 +718,30 @@ g_socket_client_connect (GSocketClient *client,
else if (proxy)
{
GIOStream *io_stream;
GTcpConnection *old_connection = G_TCP_CONNECTION (connection);
io_stream = g_proxy_connect (proxy,
G_IO_STREAM (old_connection),
G_IO_STREAM (connection),
proxy_addr,
cancellable,
&last_error);
g_object_unref (connection);
g_object_unref (proxy);
if (io_stream)
{
if (G_IS_SOCKET_CONNECTION (io_stream))
connection = G_SOCKET_CONNECTION (g_object_ref (io_stream));
connection = G_SOCKET_CONNECTION (io_stream);
else
connection = _g_proxy_connection_new (old_connection,
io_stream);
g_object_unref (io_stream);
{
connection = g_tcp_wrapper_connection_new (G_POLLABLE_IO_STREAM (io_stream),
socket);
g_object_unref (io_stream);
}
}
else
{
connection = NULL;
}
g_object_unref (old_connection);
g_object_unref (proxy);
}
else if (!g_hash_table_lookup_extended (client->priv->app_proxies,
protocol, NULL, NULL))
......@@ -753,6 +754,7 @@ g_socket_client_connect (GSocketClient *client,
}
}
g_object_unref (socket);
g_object_unref (address);
}
g_object_unref (enumerator);
......@@ -991,28 +993,30 @@ g_socket_client_proxy_connect_callback (GObject *object,
{
GSocketClientAsyncConnectData *data = user_data;
GIOStream *io_stream;
GTcpConnection *old_connection = G_TCP_CONNECTION (data->connection);
io_stream = g_proxy_connect_finish (G_PROXY (object),
result,
&data->last_error);
g_object_unref (data->connection);
if (io_stream)
{
if (G_IS_SOCKET_CONNECTION (io_stream))
data->connection = G_SOCKET_CONNECTION (g_object_ref (io_stream));
data->connection = G_SOCKET_CONNECTION (io_stream);
else
data->connection = _g_proxy_connection_new (old_connection,
io_stream);
g_object_unref (io_stream);
{
data->connection = g_tcp_wrapper_connection_new (G_POLLABLE_IO_STREAM (io_stream),
data->current_socket);
g_object_unref (io_stream);
}
}
else
{
data->connection = NULL;
g_object_unref (data->current_socket);
data->current_socket = NULL;
}
g_object_unref (old_connection);
g_socket_client_async_connect_complete (data);
}
......@@ -1038,6 +1042,8 @@ g_socket_client_proxy_connect (GSocketClientAsyncConnectData *data)
g_object_unref (data->connection);
data->connection = NULL;
g_object_unref (data->current_socket);
data->current_socket = NULL;
enumerator_next_async (data);
}
......@@ -1062,6 +1068,8 @@ g_socket_client_proxy_connect (GSocketClientAsyncConnectData *data)
g_object_unref (data->connection);
data->connection = NULL;
g_object_unref (data->current_socket);
data->current_socket = NULL;
enumerator_next_async (data);
}
......@@ -1074,8 +1082,6 @@ g_socket_client_socket_connected (GSocketClientAsyncConnectData *data)
data->connection =
g_socket_connection_factory_create_connection (data->current_socket);
g_object_unref (data->current_socket);
data->current_socket = NULL;
if (data->proxy_addr)
g_socket_client_proxy_connect (data);
......
......@@ -20,56 +20,71 @@
* Authors: Nicolas Dufresne <nicolas.dufresne@colllabora.co.uk>
*/
/**
* SECTION: gtcpwrapperconnection
* @title: GTcpWrapperConnection
* @short_description: a wrapper for non-#GSocketConnection-based
* #GIOStream<!-- -->s that are nonetheless based on a #GSocket
* @see_also: #GSocketConnection.
*
* A #GTcpWrapperConnection can be used to wrap a #GIOStream that is
* based on a #GSocket, but which is not actually a
* #GSocketConnection. This is used by #GSocketClient so that it can
* always return a #GSocketConnection, even when the connection it has
* actually created is not directly a #GSocketConnection.
*
* Since: 2.28
*/
#include "config.h"
#include "gproxyconnection.h"
#include "gtcpwrapperconnection.h"
#include "gtcpconnection.h"
#include "glibintl.h"
#define g_proxy_connection_get_type _g_proxy_connection_get_type
G_DEFINE_TYPE (GProxyConnection,
g_proxy_connection, G_TYPE_TCP_CONNECTION);
G_DEFINE_TYPE (GTcpWrapperConnection,
g_tcp_wrapper_connection, G_TYPE_TCP_CONNECTION);
enum
{
PROP_NONE,
PROP_IO_STREAM
PROP_BASE_IO_STREAM
};
struct _GProxyConnectionPrivate
struct _GTcpWrapperConnectionPrivate
{
GIOStream *io_stream;
GIOStream *base_io_stream;
};
static GInputStream *
g_proxy_connection_get_input_stream (GIOStream *io_stream)
g_tcp_wrapper_connection_get_input_stream (GIOStream *io_stream)
{
GProxyConnection *connection;
connection = G_PROXY_PROXY_CONNECTION (io_stream);
return g_io_stream_get_input_stream (connection->priv->io_stream);
GTcpWrapperConnection *connection = G_TCP_WRAPPER_CONNECTION (io_stream);
return g_io_stream_get_input_stream (connection->priv->base_io_stream);
}
static GOutputStream *
g_proxy_connection_get_output_stream (GIOStream *io_stream)
g_tcp_wrapper_connection_get_output_stream (GIOStream *io_stream)
{
GProxyConnection *connection;
connection = G_PROXY_PROXY_CONNECTION (io_stream);
return g_io_stream_get_output_stream (connection->priv->io_stream);
GTcpWrapperConnection *connection = G_TCP_WRAPPER_CONNECTION (io_stream);
return g_io_stream_get_output_stream (connection->priv->base_io_stream);
}
static void
g_proxy_connection_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
g_tcp_wrapper_connection_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GProxyConnection *connection = G_PROXY_PROXY_CONNECTION (object);
GTcpWrapperConnection *connection = G_TCP_WRAPPER_CONNECTION (object);
switch (prop_id)
{
case PROP_IO_STREAM:
g_value_set_object (value, connection->priv->io_stream);
case PROP_BASE_IO_STREAM:
g_value_set_object (value, connection->priv->base_io_stream);
break;
default:
......@@ -78,17 +93,17 @@ g_proxy_connection_get_property (GObject *object,
}
static void
g_proxy_connection_set_property (GObject *object,
g_tcp_wrapper_connection_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GProxyConnection *connection = G_PROXY_PROXY_CONNECTION (object);
GTcpWrapperConnection *connection = G_TCP_WRAPPER_CONNECTION (object);
switch (prop_id)
{
case PROP_IO_STREAM:
connection->priv->io_stream = G_IO_STREAM (g_value_dup_object (value));
case PROP_BASE_IO_STREAM:
connection->priv->base_io_stream = g_value_dup_object (value);
break;
default:
......@@ -97,59 +112,89 @@ g_proxy_connection_set_property (GObject *object,
}
static void
g_proxy_connection_finalize (GObject *object)
g_tcp_wrapper_connection_finalize (GObject *object)
{
GProxyConnection *connection = G_PROXY_PROXY_CONNECTION (object);
GTcpWrapperConnection *connection = G_TCP_WRAPPER_CONNECTION (object);
g_object_unref (connection->priv->io_stream);
if (connection->priv->base_io_stream)
g_object_unref (connection->priv->base_io_stream);
G_OBJECT_CLASS (g_proxy_connection_parent_class)->finalize (object);
G_OBJECT_CLASS (g_tcp_wrapper_connection_parent_class)->finalize (object);
}
static void
g_proxy_connection_class_init (GProxyConnectionClass *klass)
g_tcp_wrapper_connection_class_init (GTcpWrapperConnectionClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GIOStreamClass *stream_class = G_IO_STREAM_CLASS (klass);
g_type_class_add_private (klass, sizeof (GProxyConnectionPrivate));
g_type_class_add_private (klass, sizeof (GTcpWrapperConnectionPrivate));
gobject_class->set_property = g_proxy_connection_set_property;
gobject_class->get_property = g_proxy_connection_get_property;
gobject_class->finalize = g_proxy_connection_finalize;
gobject_class->set_property = g_tcp_wrapper_connection_set_property;
gobject_class->get_property = g_tcp_wrapper_connection_get_property;
gobject_class->finalize = g_tcp_wrapper_connection_finalize;
stream_class->get_input_stream = g_proxy_connection_get_input_stream;
stream_class->get_output_stream = g_proxy_connection_get_output_stream;
stream_class->get_input_stream = g_tcp_wrapper_connection_get_input_stream;
stream_class->get_output_stream = g_tcp_wrapper_connection_get_output_stream;
g_object_class_install_property (gobject_class,
PROP_IO_STREAM,
g_param_spec_object ("io-stream",
P_("IO Stream"),
P_("The altered streams"),
G_TYPE_SOCKET_CONNECTION,
PROP_BASE_IO_STREAM,
g_param_spec_object ("base-io-stream",
P_("Base IO Stream"),
P_("The wrapped GIOStream"),
G_TYPE_IO_STREAM,
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
}
static void
g_proxy_connection_init (GProxyConnection *connection)
g_tcp_wrapper_connection_init (GTcpWrapperConnection *connection)
{
connection->priv = G_TYPE_INSTANCE_GET_PRIVATE (connection,
G_TYPE_PROXY_CONNECTION,
GProxyConnectionPrivate);
G_TYPE_TCP_WRAPPER_CONNECTION,
GTcpWrapperConnectionPrivate);
}
/**
* g_tcp_wrapper_connection_new:
* @base_io_stream: the #GIOStream to wrap
* @socket: the #GSocket associated with @base_io_stream
*
* Wraps @base_io_stream and @socket together as a #GSocketConnection.
*
* Return value: the new #GSocketConnection.
*
* Since: 2.28
*/
GSocketConnection *
_g_proxy_connection_new (GTcpConnection *connection,
GIOStream *io_stream)
g_tcp_wrapper_connection_new (GIOStream *base_io_stream,
GSocket *socket)
{
GSocket *socket;
g_return_val_if_fail (G_IS_IO_STREAM (base_io_stream), NULL);
g_return_val_if_fail (G_IS_SOCKET (socket), NULL);
g_return_val_if_fail (g_socket_get_family (socket) == G_SOCKET_FAMILY_IPV4 ||
g_socket_get_family (socket) == G_SOCKET_FAMILY_IPV6, NULL);
g_return_val_if_fail (g_socket_get_socket_type (socket) == G_SOCKET_TYPE_STREAM, NULL);
return g_object_new (G_TYPE_TCP_WRAPPER_CONNECTION,
"base-io-stream", base_io_stream,
"socket", socket,
NULL);
}
socket = g_socket_connection_get_socket (G_SOCKET_CONNECTION (connection));
/**
* g_tcp_wrapper_connection_get_base_io_stream:
* @conn: a #GTcpWrapperConnection
*
* Get's @conn's base #GIOStream
*
* Return value: (transfer none): @conn's base #GIOStream
*/
GIOStream *
g_tcp_wrapper_connection_get_base_io_stream (GTcpWrapperConnection *conn)
{
g_return_val_if_fail (G_IS_TCP_WRAPPER_CONNECTION (conn), NULL);
return G_SOCKET_CONNECTION (g_object_new (G_TYPE_PROXY_CONNECTION,
"io-stream", io_stream,
"socket", socket,
NULL));
return conn->priv->base_io_stream;
}
......@@ -24,46 +24,45 @@
#error "Only <gio/gio.h> can be included directly."
#endif
#ifndef __G_PROXY_PROXY_CONNECTION_H__
#define __G_PROXY_PROXY_CONNECTION_H__
#ifndef __G_TCP_WRAPPER_CONNECTION_H__
#define __G_TCP_WRAPPER_CONNECTION_H__
#include <glib-object.h>
#include <gio/gtcpconnection.h>
G_BEGIN_DECLS
#define G_TYPE_PROXY_CONNECTION (_g_proxy_connection_get_type ())
#define G_PROXY_PROXY_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
G_TYPE_PROXY_CONNECTION, GProxyConnection))
#define G_PROXY_PROXY_CONNECTION_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \
G_TYPE_PROXY_CONNECTION, GProxyConnectionClass))
#define G_IS_PROXY_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
G_TYPE_PROXY_CONNECTION))
#define G_IS_PROXY_CONNECTION_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \
G_TYPE_PROXY_CONNECTION))
#define G_PROXY_PROXY_CONNECTION_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \
G_TYPE_PROXY_CONNECTION, GProxyConnectionClass))
#define G_TYPE_TCP_WRAPPER_CONNECTION (g_tcp_wrapper_connection_get_type ())
#define G_TCP_WRAPPER_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
G_TYPE_TCP_WRAPPER_CONNECTION, GTcpWrapperConnection))
#define G_TCP_WRAPPER_CONNECTION_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \
G_TYPE_TCP_WRAPPER_CONNECTION, GTcpWrapperConnectionClass))
#define G_IS_TCP_WRAPPER_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
G_TYPE_TCP_WRAPPER_CONNECTION))
#define G_IS_TCP_WRAPPER_CONNECTION_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \
G_TYPE_TCP_WRAPPER_CONNECTION))
#define G_TCP_WRAPPER_CONNECTION_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \
G_TYPE_TCP_WRAPPER_CONNECTION, GTcpWrapperConnectionClass))
typedef struct _GProxyConnection GProxyConnection;
typedef struct _GProxyConnectionPrivate GProxyConnectionPrivate;
typedef struct _GProxyConnectionClass GProxyConnectionClass;
typedef struct _GTcpWrapperConnectionPrivate GTcpWrapperConnectionPrivate;
typedef struct _GTcpWrapperConnectionClass GTcpWrapperConnectionClass;
struct _GProxyConnectionClass
struct _GTcpWrapperConnectionClass
{
GTcpConnectionClass parent_class;
};
struct _GProxyConnection
struct _GTcpWrapperConnection
{
GTcpConnection parent_instance;
GProxyConnectionPrivate *priv;
GTcpWrapperConnectionPrivate *priv;
};
GType _g_proxy_connection_get_type (void) G_GNUC_CONST;
GType g_tcp_wrapper_connection_get_type (void) G_GNUC_CONST;
GSocketConnection *_g_proxy_connection_new (GTcpConnection *connection,
GIOStream *io_stream);
GSocketConnection *g_tcp_wrapper_connection_new (GIOStream *base_io_stream,
GSocket *socket);
GIOStream *g_tcp_wrapper_connection_get_base_io_stream (GTcpWrapperConnection *conn);
G_END_DECLS
#endif /* __G_PROXY_PROXY_CONNECTION_H__ */
#endif /* __G_TCP_WRAPPER_CONNECTION_H__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment