/* 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, see <http://www.gnu.org/licenses/>.
 *
 * 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
 * @include: gio/gio.h
 *
 * 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.
 *
 * Returns: (transfer full): 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: (allow-none): 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.
 *
 * Returns: (transfer full): 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: (allow-none): a #GCancellable
 * @callback: (scope async): a #GAsyncReadyCallback
 * @user_data: (closure): 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 #GAsyncResult
 * @error: return #GError
 *
 * See g_proxy_connect().
 *
 * Returns: (transfer full): 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().
 *
 * Returns: %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);
}
