diff -r d0f3a028347a -r 59927b2d3b75 loudmouth/src/lm-proxy.c --- a/loudmouth/src/lm-proxy.c Tue Feb 02 01:10:06 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,490 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2004 Imendio AB - * Copyright (C) 2004 Josh Beam - * - * This program 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 program 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 program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include - -#include -#include - -#ifndef G_OS_WIN32 - -#include -#include - -#else /* G_OS_WIN32 */ - -#include - -#endif /* G_OS_WIN32 */ - -#include "lm-internals.h" -#include "lm-proxy.h" -#include "lm-debug.h" -#include "lm-utils.h" - -struct _LmProxy { - LmProxyType type; - gchar *server; - guint port; - gchar *username; - gchar *password; - guint io_watch; - - gint ref_count; -}; - -static void proxy_free (LmProxy *proxy); -static gboolean proxy_http_negotiate (LmProxy *proxy, - gint fd, - const gchar *server, - guint port); -static gboolean proxy_negotiate (LmProxy *proxy, - gint fd, - const gchar *server, - guint port); -static gboolean proxy_http_read_cb (GIOChannel *source, - GIOCondition condition, - gpointer data); -static gboolean proxy_read_cb (GIOChannel *source, - GIOCondition condition, - gpointer data); - -static void -proxy_free (LmProxy *proxy) -{ - g_free (proxy->server); - g_free (proxy->username); - g_free (proxy->password); - - g_free (proxy); -} - -static gboolean -proxy_http_negotiate (LmProxy *proxy, gint fd, const gchar *server, guint port) -{ - gchar *str; - - if (proxy->username && proxy->password) { - gchar *tmp1; - gchar *tmp2; - - tmp1 = g_strdup_printf ("%s:%s", - proxy->username, - proxy->password); - tmp2 = _lm_utils_base64_encode (tmp1); - g_free (tmp1); - - str = g_strdup_printf ("CONNECT %s:%u HTTP/1.1\r\nHost: %s:%u\r\nProxy-Authorization: Basic %s\r\n\r\n", - server, port, - server, port, - tmp2); - g_free (tmp2); - } else { - str = g_strdup_printf ("CONNECT %s:%u HTTP/1.1\r\nHost: %s:%u\r\n\r\n", - server, port, - server, port); - } - - send (fd, str, strlen (str), 0); - g_free (str); - return TRUE; -} - -/* returns TRUE when connected through proxy */ -static gboolean -proxy_http_read_cb (GIOChannel *source, GIOCondition condition, gpointer data) -{ - gchar buf[512]; - gsize bytes_read; - GError *error = NULL; - - g_io_channel_read_chars (source, buf, 512, &bytes_read, &error); - - if (bytes_read < 16) { - return FALSE; - } - - if (strncmp (buf, "HTTP/1.1 200", 12) != 0 && - strncmp (buf, "HTTP/1.0 200", 12) != 0) { - return FALSE; - } - - if (strncmp (buf + (bytes_read - 4), "\r\n\r\n", 4) != 0) { - return FALSE; - } - UNUSED_FORMAL_PARAM(condition); - UNUSED_FORMAL_PARAM(data); - return TRUE; -} - -static gboolean -proxy_read_cb (GIOChannel *source, GIOCondition condition, gpointer data) -{ - LmConnectData *connect_data; - LmConnection *connection; - LmProxy *proxy; - gboolean retval = FALSE; - - connect_data = (LmConnectData *) data; - connection = connect_data->connection; - proxy = lm_connection_get_proxy (connection); - - g_return_val_if_fail (proxy != NULL, FALSE); - - if (lm_connection_is_open (connection)) { - return FALSE; - } - - switch (lm_proxy_get_type (proxy)) { - default: - case LM_PROXY_TYPE_NONE: - g_assert_not_reached (); - break; - case LM_PROXY_TYPE_HTTP: - retval = proxy_http_read_cb (source, condition, data); - break; - } - - if (retval == TRUE) { - g_source_remove (proxy->io_watch); - _lm_socket_succeeded ((LmConnectData *) data); - } - //retval is false - //route call to connect_cb - else - { - _lm_socket_failed_with_error(connect_data, _LM_SOCK_EINVAL); - } - return FALSE; -} - -gboolean -proxy_negotiate (LmProxy *proxy, gint fd, const gchar *server, guint port) -{ - g_return_val_if_fail (proxy != NULL, FALSE); - - switch (proxy->type) { - case LM_PROXY_TYPE_NONE: - return TRUE; - case LM_PROXY_TYPE_HTTP: - return proxy_http_negotiate (proxy, fd, server, port); - default: - g_assert_not_reached (); - } - - return FALSE; -} - -gboolean -_lm_proxy_connect_cb (GIOChannel *source, GIOCondition condition, gpointer data) -{ - LmConnection *connection; - LmConnectData *connect_data; - LmProxy *proxy; - int error; - socklen_t len; - - connect_data = (LmConnectData *) data; - connection = connect_data->connection; - proxy = lm_connection_get_proxy (connection); - - g_return_val_if_fail (proxy != NULL, FALSE); - - if (condition == G_IO_ERR) { - len = sizeof (error); - _lm_sock_get_error (connect_data->fd, &error, &len); - _lm_socket_failed_with_error (connect_data, error); - return FALSE; - } else if (condition == G_IO_OUT) { - if (!proxy_negotiate (lm_connection_get_proxy (connection), connect_data->fd, lm_connection_get_server (connection), lm_connection_get_port (connection))) { - _lm_socket_failed (connect_data); - return FALSE; - } - - proxy->io_watch = g_io_add_watch (connect_data->io_channel, - G_IO_IN|G_IO_ERR, - (GIOFunc) proxy_read_cb, - connect_data); - } else { - g_assert_not_reached (); - } - UNUSED_FORMAL_PARAM(source); - return FALSE; -} - -/** - * lm_proxy_new - * @type: the type of the new proxy - * - * Creates a new Proxy. Used #lm_connection_set_proxy to make a connection - * user this proxy. - * - * Return value: a newly create proxy - **/ -EXPORT_C LmProxy * -lm_proxy_new (LmProxyType type) -{ - LmProxy *proxy; - - proxy = g_new0 (LmProxy, 1); - - proxy->ref_count = 1; - proxy->type = type; - - switch (proxy->type) { - case LM_PROXY_TYPE_HTTP: - proxy->port = 8000; - break; - default: - proxy->port = 0; - } - - return proxy; -} - -/** - * lm_proxy_new_with_server - * @type: the type of the new proxy - * @server: the proxy server - * @port: the proxy server port - * - * Creates a new Proxy. Use #lm_connection_set_proxy to make a connection - * user this proxy. - * - * Return value: a newly create proxy - **/ -EXPORT_C LmProxy * -lm_proxy_new_with_server (LmProxyType type, - const gchar *server, - guint port) -{ - LmProxy *proxy; - - proxy = lm_proxy_new (type); - lm_proxy_set_server (proxy, server); - lm_proxy_set_port (proxy, port); - - return proxy; -} - -/** - * lm_proxy_get_type - * @proxy: an #LmProxy - * - * Fetches the proxy type - * - * Return value: the type - **/ -EXPORT_C LmProxyType -lm_proxy_get_type (LmProxy *proxy) -{ - g_return_val_if_fail (proxy != NULL, LM_PROXY_TYPE_NONE); - - return proxy->type; -} - -/** - * lm_proxy_set_type - * @proxy: an #LmProxy - * @type: an LmProxyType - * - * Sets the proxy type for @proxy to @type. - **/ -EXPORT_C void -lm_proxy_set_type (LmProxy *proxy, LmProxyType type) -{ - g_return_if_fail (proxy != NULL); - - proxy->type = type; -} - -/** - * lm_proxy_get_server: - * @proxy: an #LmProxy - * - * Fetches the server address that @proxy is using. - * - * Return value: the proxy server address - **/ -EXPORT_C const gchar * -lm_proxy_get_server (LmProxy *proxy) -{ - g_return_val_if_fail (proxy != NULL, NULL); - - return proxy->server; -} - -/** - * lm_proxy_set_server: - * @proxy: an #LmProxy - * @server: Address of the proxy server - * - * Sets the server address for @proxy to @server. - **/ -EXPORT_C void -lm_proxy_set_server (LmProxy *proxy, const gchar *server) -{ - g_return_if_fail (proxy != NULL); - g_return_if_fail (server != NULL); - - g_free (proxy->server); - proxy->server = _lm_utils_hostname_to_punycode (server); -} - -/** - * lm_proxy_get_port: - * @proxy: an #LmProxy - * - * Fetches the port that @proxy is using. - * - * Return value: The port - **/ -EXPORT_C guint -lm_proxy_get_port (LmProxy *proxy) -{ - g_return_val_if_fail (proxy != NULL, 0); - - return proxy->port; -} - -/** - * lm_proxy_set_port: - * @proxy: an #LmProxy - * @port: proxy server port - * - * Sets the server port that @proxy will be using. - **/ -EXPORT_C void -lm_proxy_set_port (LmProxy *proxy, guint port) -{ - g_return_if_fail (proxy != NULL); - - proxy->port = port; -} - -/** - * lm_proxy_get_username: - * @proxy: an #LmProxy - * - * Fetches the username that @proxy is using. - * - * Return value: the username - **/ -EXPORT_C const gchar * -lm_proxy_get_username (LmProxy *proxy) -{ - g_return_val_if_fail (proxy != NULL, NULL); - - return proxy->username; -} - -/** - * lm_proxy_set_username: - * @proxy: an #LmProxy - * @username: Username - * - * Sets the username for @proxy to @username or %NULL to unset. - **/ -EXPORT_C void -lm_proxy_set_username (LmProxy *proxy, const gchar *username) -{ - g_return_if_fail (proxy != NULL); - - g_free (proxy->username); - - if (username) { - proxy->username = g_strdup (username); - } else { - proxy->username = NULL; - } -} -/** - * lm_proxy_get_password: - * @proxy: an #LmProxy - * - * Fetches the password that @proxy is using. - * - * Return value: the proxy password - **/ -EXPORT_C const gchar * -lm_proxy_get_password (LmProxy *proxy) -{ - g_return_val_if_fail (proxy != NULL, NULL); - - return proxy->password; -} - -/** - * lm_proxy_set_password: - * @proxy: an #LmProxy - * @password: Password - * - * Sets the password for @proxy to @password or %NULL to unset. - **/ -EXPORT_C void -lm_proxy_set_password (LmProxy *proxy, const gchar *password) -{ - g_return_if_fail (proxy != NULL); - - g_free (proxy->password); - - if (password) { - proxy->password = g_strdup (password); - } else { - proxy->password = NULL; - } -} - -/** - * lm_proxy_ref: - * @proxy: an #LmProxy - * - * Adds a reference to @proxy. - * - * Return value: the proxy - **/ -EXPORT_C LmProxy * -lm_proxy_ref (LmProxy *proxy) -{ - g_return_val_if_fail (proxy != NULL, NULL); - - proxy->ref_count++; - return proxy; -} - -/** - * lm_proxy_unref - * @proxy: an #LmProxy - * - * Removes a reference from @proxy. When no more references are present - * @proxy is freed. - **/ -EXPORT_C void -lm_proxy_unref (LmProxy *proxy) -{ - g_return_if_fail (proxy != NULL); - - proxy->ref_count--; - - if (proxy->ref_count == 0) { - proxy_free (proxy); - } -}