/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright (C) 2010 Collabora Ltd.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * Author: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
 */

#include "config.h"

#include "gproxy.h"

#include "giomodule.h"
#include "giomodule-priv.h"
#include "glibintl.h"

/**
 * SECTION:gproxy
 * @short_description: Interface for proxy handling
 *
 * A #GProxy handles connecting to a remote host via a given type of
 * proxy server. It is implemented by the 'gio-proxy' extension point.
 * The extensions are named after their proxy protocol name. As an
 * example, a SOCKS5 proxy implementation can be retrieved with the
 * name 'socks5' using the function
 * g_io_extension_point_get_extension_by_name().
 *
 * Since: 2.26
 **/

G_DEFINE_INTERFACE (GProxy, g_proxy, G_TYPE_OBJECT)

static void
g_proxy_default_init (GProxyInterface *iface)
{
}

/**
 * g_proxy_get_default_for_protocol:
 * @protocol: the proxy protocol name (e.g. http, socks, etc)
 *
 * Lookup "gio-proxy" extension point for a proxy implementation that supports
 * specified protocol.
 *
 * Return value: return a #GProxy or NULL if protocol is not supported.
 *
 * Since: 2.26
 **/
GProxy *
g_proxy_get_default_for_protocol (const gchar *protocol)
{
  GIOExtensionPoint *ep;
  GIOExtension *extension;

  /* Ensure proxy modules loaded */
  _g_io_modules_ensure_loaded ();

  ep = g_io_extension_point_lookup (G_PROXY_EXTENSION_POINT_NAME);

  extension = g_io_extension_point_get_extension_by_name (ep, protocol);

  if (extension)
      return g_object_new (g_io_extension_get_type (extension), NULL);

  return NULL;
}

/**
 * g_proxy_connect:
 * @proxy: a #GProxy
 * @connection: a #GIOStream
 * @proxy_address: a #GProxyAddress
 * @cancellable: a #GCancellable
 * @error: return #GError
 *
 * Given @connection to communicate with a proxy (eg, a
 * #GSocketConnection that is connected to the proxy server), this
 * does the necessary handshake to connect to @proxy_address, and if
 * required, wraps the #GIOStream to handle proxy payload.
 *
 * Return value: a #GIOStream that will replace @connection. This might
 *               be the same as @connection, in which case a reference
 *               will be added.
 *
 * Since: 2.26
 */
GIOStream *
g_proxy_connect (GProxy            *proxy,
		 GIOStream         *connection,
		 GProxyAddress     *proxy_address,
		 GCancellable      *cancellable,
		 GError           **error)
{
  GProxyInterface *iface;

  g_return_val_if_fail (G_IS_PROXY (proxy), NULL);

  iface = G_PROXY_GET_IFACE (proxy);

  return (* iface->connect) (proxy,
			     connection,
			     proxy_address,
			     cancellable,
			     error);
}

/**
 * g_proxy_connect_async:
 * @proxy: a #GProxy
 * @connection: a #GIOStream
 * @proxy_address: a #GProxyAddress
 * @cancellable: a #GCancellable
 * @callback: a #GAsyncReadyCallback
 * @user_data: callback data
 *
 * Asynchronous version of g_proxy_connect().
 *
 * Since: 2.26
 */
void
g_proxy_connect_async (GProxy               *proxy,
		       GIOStream            *connection,
		       GProxyAddress        *proxy_address,
		       GCancellable         *cancellable,
		       GAsyncReadyCallback   callback,
		       gpointer              user_data)
{
  GProxyInterface *iface;

  g_return_if_fail (G_IS_PROXY (proxy));

  iface = G_PROXY_GET_IFACE (proxy);

  (* iface->connect_async) (proxy,
			    connection,
			    proxy_address,
			    cancellable,
			    callback,
			    user_data);
}

/**
 * g_proxy_connect_finish:
 * @proxy: a #GProxy
 * @result: a #GAsyncRetult
 * @error: return #GError
 *
 * See g_proxy_connect().
 *
 * Return value: a #GIOStream.
 *
 * Since: 2.26
 */
GIOStream *
g_proxy_connect_finish (GProxy       *proxy,
			GAsyncResult *result,
			GError      **error)
{
  GProxyInterface *iface;

  g_return_val_if_fail (G_IS_PROXY (proxy), NULL);

  iface = G_PROXY_GET_IFACE (proxy);

  return (* iface->connect_finish) (proxy, result, error);
}

/**
 * g_proxy_supports_hostname:
 * @proxy: a #GProxy
 *
 * Some proxy protocols expect to be passed a hostname, which they
 * will resolve to an IP address themselves. Others, like SOCKS4, do
 * not allow this. This function will return %FALSE if @proxy is
 * implementing such a protocol. When %FALSE is returned, the caller
 * should resolve the destination hostname first, and then pass a
 * #GProxyAddress containing the stringified IP address to
 * g_proxy_connect() or g_proxy_connect_async().
 *
 * Return value: %TRUE if hostname resolution is supported.
 *
 * Since: 2.26
 */
gboolean
g_proxy_supports_hostname (GProxy *proxy)
{
  GProxyInterface *iface;

  g_return_val_if_fail (G_IS_PROXY (proxy), FALSE);

  iface = G_PROXY_GET_IFACE (proxy);

  return (* iface->supports_hostname) (proxy);
}
