/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright (C) 2010 Collabora, Ltd.
 * Copyright (C) 2014 Red Hat, Inc.
 *
 * 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>
 *          Marc-André Lureau <marcandre.lureau@redhat.com>
 */

#include "config.h"

#include "ghttpproxy.h"

#include <string.h>
#include <stdlib.h>

#include "giomodule.h"
#include "giomodule-priv.h"
#include "giostream.h"
#include "ginputstream.h"
#include "glibintl.h"
#include "goutputstream.h"
#include "gproxy.h"
#include "gproxyaddress.h"
#include "gsocketconnectable.h"
#include "gtask.h"
#include "gtlsclientconnection.h"
#include "gtlsconnection.h"


struct _GHttpProxy
{
  GObject parent;
};

struct _GHttpProxyClass
{
  GObjectClass parent_class;
};

static void g_http_proxy_iface_init (GProxyInterface *proxy_iface);

#define g_http_proxy_get_type _g_http_proxy_get_type
G_DEFINE_TYPE_WITH_CODE (GHttpProxy, g_http_proxy, G_TYPE_OBJECT,
                         G_IMPLEMENT_INTERFACE (G_TYPE_PROXY,
                                                g_http_proxy_iface_init)
                         _g_io_modules_ensure_extension_points_registered ();
                         g_io_extension_point_implement (G_PROXY_EXTENSION_POINT_NAME,
                                                         g_define_type_id,
                                                         "http",
                                                         0))

static void
g_http_proxy_init (GHttpProxy *proxy)
{
}

static gchar *
create_request (GProxyAddress  *proxy_address,
                gboolean       *has_cred,
                GError        **error)
{
  const gchar *hostname;
  gint port;
  const gchar *username;
  const gchar *password;
  GString *request;
  gchar *ascii_hostname;

  if (has_cred)
    *has_cred = FALSE;

  hostname = g_proxy_address_get_destination_hostname (proxy_address);
  ascii_hostname = g_hostname_to_ascii (hostname);
  if (!ascii_hostname)
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                           _("Invalid hostname"));
      return NULL;
    }
  port = g_proxy_address_get_destination_port (proxy_address);
  username = g_proxy_address_get_username (proxy_address);
  password = g_proxy_address_get_password (proxy_address);

  request = g_string_new (NULL);

  g_string_append_printf (request,
                          "CONNECT %s:%i HTTP/1.0\r\n"
                          "Host: %s:%i\r\n"
                          "Proxy-Connection: keep-alive\r\n"
                          "User-Agent: GLib/%i.%i\r\n",
                          ascii_hostname, port,
                          ascii_hostname, port,
                          GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION);
  g_free (ascii_hostname);

  if (username != NULL && password != NULL)
    {
      gchar *cred;
      gchar *base64_cred;

      if (has_cred)
        *has_cred = TRUE;

      cred = g_strdup_printf ("%s:%s", username, password);
      base64_cred = g_base64_encode ((guchar *) cred, strlen (cred));
      g_free (cred);
      g_string_append_printf (request,
                              "Proxy-Authorization: Basic %s\r\n",
                              base64_cred);
      g_free (base64_cred);
    }

  g_string_append (request, "\r\n");

  return g_string_free (request, FALSE);
}

static gboolean
check_reply (const gchar  *buffer,
             gboolean      has_cred,
             GError      **error)
{
  gint err_code;
  const gchar *ptr = buffer + 7;

  if (strncmp (buffer, "HTTP/1.", 7) != 0 || (*ptr != '0' && *ptr != '1'))
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED,
                           _("Bad HTTP proxy reply"));
      return FALSE;
    }

  ptr++;
  while (*ptr == ' ')
    ptr++;

  err_code = atoi (ptr);

  if (err_code < 200 || err_code >= 300)
    {
      switch (err_code)
        {
          case 403:
            g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_NOT_ALLOWED,
                                 _("HTTP proxy connection not allowed"));
            break;
          case 407:
            if (has_cred)
              g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_AUTH_FAILED,
                                   _("HTTP proxy authentication failed"));
            else
              g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_NEED_AUTH,
                                   _("HTTP proxy authentication required"));
            break;
          default:
            g_set_error (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED,
                         _("HTTP proxy connection failed: %i"), err_code);
        }

      return FALSE;
    }

  return TRUE;
}

#define HTTP_END_MARKER "\r\n\r\n"

static GIOStream *
g_http_proxy_connect (GProxy         *proxy,
                      GIOStream      *io_stream,
                      GProxyAddress  *proxy_address,
                      GCancellable   *cancellable,
                      GError        **error)
{
  GInputStream *in;
  GOutputStream *out;
  gchar *buffer = NULL;
  gsize buffer_length;
  gssize bytes_read;
  gboolean has_cred;
  GIOStream *tlsconn = NULL;

  if (G_IS_HTTPS_PROXY (proxy))
    {
      tlsconn = g_tls_client_connection_new (io_stream,
                                             G_SOCKET_CONNECTABLE (proxy_address),
                                             error);
      if (!tlsconn)
        goto error;

#ifdef DEBUG
      {
        GTlsCertificateFlags tls_validation_flags = G_TLS_CERTIFICATE_VALIDATE_ALL;

        tls_validation_flags &= ~(G_TLS_CERTIFICATE_UNKNOWN_CA | G_TLS_CERTIFICATE_BAD_IDENTITY);
        g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (tlsconn),
                                                      tls_validation_flags);
      }
#endif

      if (!g_tls_connection_handshake (G_TLS_CONNECTION (tlsconn), cancellable, error))
        goto error;

      io_stream = tlsconn;
    }

  in = g_io_stream_get_input_stream (io_stream);
  out = g_io_stream_get_output_stream (io_stream);

  buffer = create_request (proxy_address, &has_cred, error);
  if (!buffer)
    goto error;
  if (!g_output_stream_write_all (out, buffer, strlen (buffer), NULL,
                                  cancellable, error))
    goto error;

  g_free (buffer);

  bytes_read = 0;
  buffer_length = 1024;
  buffer = g_malloc (buffer_length);

  /* Read byte-by-byte instead of using GDataInputStream
   * since we do not want to read beyond the end marker
   */
  do
    {
      gsize nread;

      nread = g_input_stream_read (in, buffer + bytes_read, 1, cancellable, error);
      if (nread == -1)
        goto error;

      if (nread == 0)
        break;

      ++bytes_read;

      if (bytes_read == buffer_length)
        {
          buffer_length = 2 * buffer_length;
          buffer = g_realloc (buffer, buffer_length);
        }

      *(buffer + bytes_read) = '\0';

      if (g_str_has_suffix (buffer, HTTP_END_MARKER))
        break;
    }
  while (TRUE);

  if (bytes_read == 0)
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED,
                           _("HTTP proxy server closed connection unexpectedly."));
      goto error;
    }

  if (!check_reply (buffer, has_cred, error))
    goto error;

  g_free (buffer);

  g_object_ref (io_stream);
  g_clear_object (&tlsconn);

  return io_stream;

error:
  g_clear_object (&tlsconn);
  g_free (buffer);
  return NULL;
}

typedef struct
{
  GIOStream *io_stream;
  GProxyAddress *proxy_address;
} ConnectAsyncData;

static void
free_connect_data (ConnectAsyncData *data)
{
  g_object_unref (data->io_stream);
  g_object_unref (data->proxy_address);
  g_slice_free (ConnectAsyncData, data);
}

static void
connect_thread (GTask        *task,
                gpointer      source_object,
                gpointer      task_data,
                GCancellable *cancellable)
{
  GProxy *proxy = source_object;
  ConnectAsyncData *data = task_data;
  GIOStream *res;
  GError *error = NULL;

  res = g_http_proxy_connect (proxy, data->io_stream, data->proxy_address,
                              cancellable, &error);

  if (res == NULL)
    g_task_return_error (task, error);
  else
    g_task_return_pointer (task, res, g_object_unref);
}

static void
g_http_proxy_connect_async (GProxy              *proxy,
                            GIOStream           *io_stream,
                            GProxyAddress       *proxy_address,
                            GCancellable        *cancellable,
                            GAsyncReadyCallback  callback,
                            gpointer             user_data)
{
  ConnectAsyncData *data;
  GTask *task;

  data = g_slice_new0 (ConnectAsyncData);
  data->io_stream = g_object_ref (io_stream);
  data->proxy_address = g_object_ref (proxy_address);

  task = g_task_new (proxy, cancellable, callback, user_data);
  g_task_set_source_tag (task, g_http_proxy_connect_async);
  g_task_set_task_data (task, data, (GDestroyNotify) free_connect_data);

  g_task_run_in_thread (task, connect_thread);
  g_object_unref (task);
}

static GIOStream *
g_http_proxy_connect_finish (GProxy        *proxy,
                             GAsyncResult  *result,
                             GError       **error)
{
  return g_task_propagate_pointer (G_TASK (result), error);
}

static gboolean
g_http_proxy_supports_hostname (GProxy *proxy)
{
  return TRUE;
}

static void
g_http_proxy_class_init (GHttpProxyClass *class)
{
}

static void
g_http_proxy_iface_init (GProxyInterface *proxy_iface)
{
  proxy_iface->connect = g_http_proxy_connect;
  proxy_iface->connect_async = g_http_proxy_connect_async;
  proxy_iface->connect_finish = g_http_proxy_connect_finish;
  proxy_iface->supports_hostname = g_http_proxy_supports_hostname;
}

struct _GHttpsProxy
{
  GHttpProxy parent;
};

struct _GHttpsProxyClass
{
  GHttpProxyClass parent_class;
};

#define g_https_proxy_get_type _g_https_proxy_get_type
G_DEFINE_TYPE_WITH_CODE (GHttpsProxy, g_https_proxy, G_TYPE_HTTP_PROXY,
                         G_IMPLEMENT_INTERFACE (G_TYPE_PROXY,
                                                g_http_proxy_iface_init)
                         _g_io_modules_ensure_extension_points_registered ();
                         g_io_extension_point_implement (G_PROXY_EXTENSION_POINT_NAME,
                                                         g_define_type_id,
                                                         "https",
                                                         0))

static void
g_https_proxy_init (GHttpsProxy *proxy)
{
}

static void
g_https_proxy_class_init (GHttpsProxyClass *class)
{
}
