/* 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.1 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)
 *
 * Find the `gio-proxy` extension point for a proxy implementation that supports
 * the specified protocol.
 *
 * Returns: (nullable) (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: (nullable): 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: (nullable): 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);
}
