2004-03-17 Mikael Hallendal <micke@imendio.com>
* Synced from SVN.
* Released 0.16
* configure.in: Bumped to 0.16
* NEWS: Updated for 0.16
2004-03-17 Mikael Hallendal <micke@imendio.com>
* docs/reference/*: Updated documentation.
* loudmouth/*: Fixed the documentation in a couple of places.
2004-03-17 Mikael Hallendal <micke@imendio.com>
* loudmouth/lm-connection.[ch]
(lm_connection_new_with_context):
- Added to be able to give what context the connection should be
running in.
- All internal functions are updated to use the context or NULL if
lm_connection_new was called.
- Should make it possible to use several LmConnections in various
threads.
2004-03-17 Mikael Hallendal <micke@imendio.com>
* loudmouth/lm-connection.c:
* loudmouth/lm-internal.h:
* loudmouth/lm-proxy.c:
- Make the HTTP proxy support asynchronous. Patch from Josh Beam.
- Re-enable the HTTP proxy support.
* examples/lm-send-sync.c:
* examples/lm-send-async.c:
* examples/test-http-proxy.c:
- Added two of the old examples and a new one to test out the HTTP
proxy support.
2004-03-17 Mikael Hallendal <micke@imendio.com>
* configure.in: Generate examples/Makefile
* loudmouth/test-jid.c: Removed
* loudmouth/test-lm.c: Moved to examples/
* exmples/*: Moved out from loudmouth/
--- a/AUTHORS Thu Feb 05 22:18:20 2004 +0000
+++ b/AUTHORS Thu Mar 18 00:04:59 2004 +0000
@@ -1,2 +1,1 @@
Mikael Hallendal <micke@imendio.com>
-
--- a/ChangeLog Thu Feb 05 22:18:20 2004 +0000
+++ b/ChangeLog Thu Mar 18 00:04:59 2004 +0000
@@ -1,3 +1,48 @@
+2004-03-17 Mikael Hallendal <micke@imendio.com>
+
+ * Synced from SVN.
+
+ * Released 0.16
+
+ * configure.in: Bumped to 0.16
+ * NEWS: Updated for 0.16
+
+2004-03-17 Mikael Hallendal <micke@imendio.com>
+
+ * docs/reference/*: Updated documentation.
+ * loudmouth/*: Fixed the documentation in a couple of places.
+
+2004-03-17 Mikael Hallendal <micke@imendio.com>
+
+ * loudmouth/lm-connection.[ch]
+ (lm_connection_new_with_context):
+ - Added to be able to give what context the connection should be
+ running in.
+ - All internal functions are updated to use the context or NULL if
+ lm_connection_new was called.
+ - Should make it possible to use several LmConnections in various
+ threads.
+
+2004-03-17 Mikael Hallendal <micke@imendio.com>
+
+ * loudmouth/lm-connection.c:
+ * loudmouth/lm-internal.h:
+ * loudmouth/lm-proxy.c:
+ - Make the HTTP proxy support asynchronous. Patch from Josh Beam.
+ - Re-enable the HTTP proxy support.
+ * examples/lm-send-sync.c:
+ * examples/lm-send-async.c:
+ * examples/test-http-proxy.c:
+ - Added two of the old examples and a new one to test out the HTTP
+ proxy support.
+
+2004-03-17 Mikael Hallendal <micke@imendio.com>
+
+ * configure.in: Generate examples/Makefile
+ * loudmouth/test-jid.c: Removed
+ * loudmouth/test-lm.c: Moved to examples/
+ * exmples/*: Moved out from loudmouth/
+
2004-02-05 Mikael Hallendal <micke@imendio.com>
* README: Updated information about website and bug reporting
--- a/Makefile.am Thu Feb 05 22:18:20 2004 +0000
+++ b/Makefile.am Thu Mar 18 00:04:59 2004 +0000
@@ -2,7 +2,7 @@
MONO_SUBDIR = mono
endif
-SUBDIRS = loudmouth docs
+SUBDIRS = loudmouth docs examples
EXTRA_DIST = \
loudmouth-1.0.pc.in \
--- a/NEWS Thu Feb 05 22:18:20 2004 +0000
+++ b/NEWS Thu Mar 18 00:04:59 2004 +0000
@@ -1,3 +1,12 @@
+Changes in 0.16:
+----------------
+* Support for giving the context to which an LmConnection should run in
+ (should solve issues when wanting to run several LmConnections in various
+ threads)
+* HTTP proxy support
+* Memory leak fix
+* Distribute the win32-config.h file needed to build on Windows.
+
Changes in 0.15.1:
------------------
* Require GnuTLS >= 1.0.0
--- a/configure.in Thu Feb 05 22:18:20 2004 +0000
+++ b/configure.in Thu Mar 18 00:04:59 2004 +0000
@@ -2,7 +2,7 @@
AM_CONFIG_HEADER(config.h)
-AM_INIT_AUTOMAKE(loudmouth, 0.15.1)
+AM_INIT_AUTOMAKE(loudmouth, 0.16)
AM_MAINTAINER_MODE
@@ -179,6 +179,7 @@
docs/Makefile
docs/reference/Makefile
loudmouth/Makefile
+examples/Makefile
loudmouth-1.0.pc
loudmouth.spec])
@@ -188,13 +189,11 @@
dnl ==========================================================================
echo "
- Loudmouth $VERSION
- =========================================
+ Loudmouth $VERSION from Imendio HB
+ ==================================
prefix: ${prefix}
compiler: ${CC}
- cflags: ${CFLAGS}
-
"
dnl if test x$enable_mono = xyes ; then
@@ -208,15 +207,12 @@
dnl "
dnl fi
-echo \
echo \
-" Enable SSL ${ac_ssl}
-"
+" Enable SSL ${ac_ssl}"
echo \
" Enable Debug: ${enable_debug}
"
-
echo \
" Now type 'make' to build Loudmouth
"
--- a/docs/reference/loudmouth-docs.sgml Thu Feb 05 22:18:20 2004 +0000
+++ b/docs/reference/loudmouth-docs.sgml Thu Mar 18 00:04:59 2004 +0000
@@ -14,5 +14,6 @@
<xi:include href="xml/lm-message-handler.xml"/>
<xi:include href="xml/lm-message-node.xml"/>
<xi:include href="xml/lm-ssl.xml"/>
+ <xi:include href="xml/lm-proxy.xml"/>
</chapter>
</book>
--- a/docs/reference/loudmouth-sections.txt Thu Feb 05 22:18:20 2004 +0000
+++ b/docs/reference/loudmouth-sections.txt Thu Mar 18 00:04:59 2004 +0000
@@ -21,9 +21,10 @@
lm_connection_set_server
lm_connection_get_port
lm_connection_set_port
-lm_connection_supports_ssl
-lm_connection_get_use_ssl
-lm_connection_set_use_ssl
+lm_connection_get_ssl
+lm_connection_set_ssl
+lm_connection_get_proxy
+lm_connection_set_proxy
lm_connection_send
lm_connection_send_with_reply
lm_connection_send_with_reply_and_block
@@ -90,6 +91,7 @@
<SECTION>
<FILE>lm-ssl</FILE>
+LmSSL
LmCertificateStatus
LmSSLStatus
LmSSLResponse
@@ -100,3 +102,23 @@
lm_ssl_ref
lm_ssl_unref
</SECTION>
+
+<SECTION>
+<FILE>lm-proxy</FILE>
+LmProxy
+LmProxyType
+lm_proxy_new
+lm_proxy_new_with_server
+lm_proxy_get_type
+lm_proxy_set_type
+lm_proxy_get_server
+lm_proxy_set_server
+lm_proxy_get_port
+lm_proxy_set_port
+lm_proxy_get_username
+lm_proxy_set_username
+lm_proxy_get_password
+lm_proxy_set_password
+lm_proxy_ref
+lm_proxy_unref
+</SECTION>
--- a/docs/reference/tmpl/lm-connection.sgml Thu Feb 05 22:18:20 2004 +0000
+++ b/docs/reference/tmpl/lm-connection.sgml Thu Mar 18 00:04:59 2004 +0000
@@ -6,7 +6,44 @@
<!-- ##### SECTION Long_Description ##### -->
<para>
+An example of how to use Loudmouth with the synchronous API.
+<informalexample><programlisting><![CDATA[
+int
+main (int argc, char **argv)
+{
+ LmConnection *connection;
+ GError *error = NULL;
+ gint i;
+ LmMessage *m;
+ connection = lm_connection_new ("myserver");
+
+ if (!lm_connection_open_and_block (connection, &error)) {
+ g_error ("Failed to open: %s\n", error->message);
+ }
+
+ if (!lm_connection_authenticate_and_block (connection,
+ "username", "password",
+ "resource",
+ &error)) {
+ g_error ("Failed to authenticate: %s\n", error->message);
+ }
+
+ m = lm_message_new ("recipient", LM_MESSAGE_TYPE_MESSAGE);
+ lm_message_node_add_child (m->node, "body", "message");
+
+ if (!lm_connection_send (connection, m, &error)) {
+ g_error ("Send failed: %s\n", error->message);
+ }
+
+ lm_message_unref (m);
+
+ lm_connection_close (connection, NULL);
+ lm_connection_unref (connection);
+
+ return 0;
+}
+]]></programlisting></informalexample>
</para>
<!-- ##### SECTION See_Also ##### -->
@@ -215,6 +252,42 @@
@port:
+<!-- ##### FUNCTION lm_connection_get_ssl ##### -->
+<para>
+
+</para>
+
+@connection:
+@Returns:
+
+
+<!-- ##### FUNCTION lm_connection_set_ssl ##### -->
+<para>
+
+</para>
+
+@connection:
+@ssl:
+
+
+<!-- ##### FUNCTION lm_connection_get_proxy ##### -->
+<para>
+
+</para>
+
+@connection:
+@Returns:
+
+
+<!-- ##### FUNCTION lm_connection_set_proxy ##### -->
+<para>
+
+</para>
+
+@connection:
+@proxy:
+
+
<!-- ##### FUNCTION lm_connection_send ##### -->
<para>
--- a/docs/reference/tmpl/lm-ssl.sgml Thu Feb 05 22:18:20 2004 +0000
+++ b/docs/reference/tmpl/lm-ssl.sgml Thu Mar 18 00:04:59 2004 +0000
@@ -6,14 +6,29 @@
<!-- ##### SECTION Long_Description ##### -->
<para>
-Use this together with an #LmConnection to get the connection to use SSL.
+Use this together with an #LmConnection to get the connection to use SSL. Example of how to use the #LmSSL API.
</para>
+<informalexample><programlisting><![CDATA[
+LmConnection *connection;
+LmSSL *ssl;
+
+connection = lm_connection_new ("myserver");
+ssl = lm_ssl_new (NULL, my_ssl_func, NULL, NULL);
+lm_connection_set_ssl (connection, ssl);
+...
+]]></programlisting></informalexample>
<!-- ##### SECTION See_Also ##### -->
<para>
</para>
+<!-- ##### STRUCT LmSSL ##### -->
+<para>
+This should not be accessed directly. Use the accessor functions as described below.
+</para>
+
+
<!-- ##### ENUM LmCertificateStatus ##### -->
<para>
Provides information of the status of a certain certificate.
@@ -49,7 +64,7 @@
This function is called if something goes wrong during the connecting phase.
</para>
-@ssl: An #LmSSL.
+@ssl: An #LmSSL.
@status: The status informing what went wrong.
@user_data: User data provided in the callback.
@Returns: User should return #LM_SSL_RESPONSE_CONTINUE if connection should proceed and otherwise #LM_SSL_RESPONSE_STOP.
--- a/loudmouth/Makefile.am Thu Feb 05 22:18:20 2004 +0000
+++ b/loudmouth/Makefile.am Thu Mar 18 00:04:59 2004 +0000
@@ -49,15 +49,3 @@
# an explicit dependency here so alm generated files get built
$(OBJECTS): $(built_sources)
-
-noinst_PROGRAMS = test-lm
-
-test_lm_SOURCES = \
- test-lm.c
-
-test_lm_LDADD = \
- $(LOUDMOUTH_LIBS) \
- libloudmouth-1.la \
- $(NULL)
-
-
--- a/loudmouth/lm-connection.c Thu Feb 05 22:18:20 2004 +0000
+++ b/loudmouth/lm-connection.c Thu Mar 18 00:04:59 2004 +0000
@@ -51,58 +51,49 @@
} HandlerData;
typedef struct {
- LmConnection *connection;
-
- /* struct to save resolved address */
- struct addrinfo *resolved_addrs;
- struct addrinfo *current_addr;
- int fd;
- GIOChannel *io_channel;
-} LmConnectData;
-
-typedef struct {
GSource source;
LmConnection *connection;
} LmIncomingSource;
struct _LmConnection {
/* Parameters */
- gchar *server;
- guint port;
+ GMainContext *context;
+ gchar *server;
+ guint port;
- LmSSL *ssl;
+ LmSSL *ssl;
- LmProxy *proxy;
+ LmProxy *proxy;
- LmParser *parser;
- gchar *stream_id;
+ LmParser *parser;
+ gchar *stream_id;
- GHashTable *id_handlers;
- GSList *handlers[LM_MESSAGE_TYPE_UNKNOWN];
+ GHashTable *id_handlers;
+ GSList *handlers[LM_MESSAGE_TYPE_UNKNOWN];
/* Communication */
- GIOChannel *io_channel;
- guint io_watch_in;
- guint io_watch_err;
- guint io_watch_hup;
- guint fd;
+ GIOChannel *io_channel;
+ guint io_watch_in;
+ guint io_watch_err;
+ guint io_watch_hup;
+ guint fd;
- guint open_id;
- LmCallback *open_cb;
+ guint open_id;
+ LmCallback *open_cb;
- gboolean cancel_open;
- LmCallback *close_cb;
- LmCallback *auth_cb;
- LmCallback *register_cb;
+ gboolean cancel_open;
+ LmCallback *close_cb;
+ LmCallback *auth_cb;
+ LmCallback *register_cb;
- LmCallback *disconnect_cb;
+ LmCallback *disconnect_cb;
- LmQueue *incoming_messages;
- GSource *incoming_source;
+ LmQueue *incoming_messages;
+ GSource *incoming_source;
LmConnectionState state;
- gint ref_count;
+ gint ref_count;
};
typedef enum {
@@ -170,6 +161,12 @@
LmDisconnectReason reason);
static void connection_do_connect (LmConnectData *connect_data);
+static guint connection_add_watch (LmConnection *connection,
+ GIOChannel *channel,
+ GIOCondition condition,
+ GIOFunc func,
+ gpointer user_data);
+
static GSourceFuncs incoming_funcs = {
@@ -265,8 +262,8 @@
lm_queue_push_tail (connection->incoming_messages, m);
}
-static gboolean
-connection_succeeded (LmConnectData *connect_data)
+gboolean
+_lm_connection_succeeded (LmConnectData *connect_data)
{
LmConnection *connection = connect_data->connection;
LmMessage *m;
@@ -313,20 +310,26 @@
g_io_channel_set_flags (connection->io_channel,
flags & G_IO_FLAG_NONBLOCK, NULL);
- connection->io_watch_in = g_io_add_watch (connection->io_channel,
- G_IO_IN,
- (GIOFunc) connection_in_event,
- connection);
+ connection->io_watch_in =
+ connection_add_watch (connection,
+ connection->io_channel,
+ G_IO_IN,
+ (GIOFunc) connection_in_event,
+ connection);
- connection->io_watch_err = g_io_add_watch (connection->io_channel,
- G_IO_ERR,
- (GIOFunc) connection_error_event,
+ connection->io_watch_err =
+ connection_add_watch (connection,
+ connection->io_channel,
+ G_IO_ERR,
+ (GIOFunc) connection_error_event,
connection);
- connection->io_watch_hup = g_io_add_watch (connection->io_channel,
- G_IO_HUP,
- (GIOFunc) connection_hup_event,
- connection);
-
+ connection->io_watch_hup =
+ connection_add_watch (connection,
+ connection->io_channel,
+ G_IO_HUP,
+ (GIOFunc) connection_hup_event,
+ connection);
+
if (!connection_send (connection,
"<?xml version='1.0' encoding='UTF-8'?>", -1,
NULL)) {
@@ -355,8 +358,8 @@
return FALSE;
}
-static void
-connection_failed_with_error (LmConnectData *connect_data, int error)
+void
+_lm_connection_failed_with_error (LmConnectData *connect_data, int error)
{
g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET,
"Connection failed: %s (error %d)\n",
@@ -377,10 +380,10 @@
}
}
-static void
-connection_failed (LmConnectData *connect_data)
+void
+_lm_connection_failed (LmConnectData *connect_data)
{
- connection_failed_with_error (connect_data,errno);
+ _lm_connection_failed_with_error (connect_data,errno);
}
static gboolean
@@ -400,16 +403,10 @@
/* get the real error from the socket */
getsockopt (connect_data->fd, SOL_SOCKET, SO_ERROR,
&error, &len);
- connection_failed_with_error (connect_data, error);
+ _lm_connection_failed_with_error (connect_data, error);
return FALSE;
} else if (condition == G_IO_OUT) {
- if (connect_data->connection->proxy) {
- if (!_lm_proxy_negotiate (connection->proxy, connect_data->fd, connection->server, connection->port)) {
- connection_failed (connect_data);
- return FALSE;
- }
- }
- connection_succeeded (connect_data);
+ _lm_connection_succeeded (connect_data);
} else {
g_assert_not_reached ();
}
@@ -454,7 +451,7 @@
addr->ai_protocol);
if (fd < 0) {
- connection_failed (connect_data);
+ _lm_connection_failed (connect_data);
return;
}
@@ -466,16 +463,50 @@
if (res < 0 && errno != EINPROGRESS) {
close (fd);
- connection_failed (connect_data);
+ _lm_connection_failed (connect_data);
return;
}
connect_data->io_channel = g_io_channel_unix_new (fd);
- g_io_add_watch (connect_data->io_channel, G_IO_OUT|G_IO_ERR,
- (GIOFunc) connection_connect_cb, connect_data);
+ if (connection->proxy) {
+ connection_add_watch (connection,
+ connect_data->io_channel,
+ G_IO_OUT|G_IO_ERR,
+ (GIOFunc) _lm_proxy_connect_cb,
+ connect_data);
+ } else {
+ connection_add_watch (connection,
+ connect_data->io_channel,
+ G_IO_OUT|G_IO_ERR,
+ (GIOFunc) connection_connect_cb,
+ connect_data);
+ }
+
return;
}
+static guint
+connection_add_watch (LmConnection *connection,
+ GIOChannel *channel,
+ GIOCondition condition,
+ GIOFunc func,
+ gpointer user_data)
+{
+ GSource *source;
+ guint id;
+
+ g_return_val_if_fail (channel != NULL, 0);
+
+ source = g_io_create_watch (channel, condition);
+
+ g_source_set_callback (source, (GSourceFunc)func, user_data, NULL);
+
+ id = g_source_attach (source, connection->context);
+ g_source_unref (source);
+
+ return id;
+}
+
/* Returns directly */
/* Setups all data needed to start the connection attempts */
static gboolean
@@ -503,7 +534,7 @@
/* source thingie for messages and stuff */
connection->incoming_source = connection_create_source (connection);
- g_source_attach (connection->incoming_source,NULL);
+ g_source_attach (connection->incoming_source, connection->context);
lm_verbose ("Connecting to: %s:%d\n",
connection->server, connection->port);
@@ -1022,7 +1053,8 @@
} else {
connection->server = NULL;
}
-
+
+ connection->context = NULL;
connection->port = LM_CONNECTION_DEFAULT_PORT;
connection->ssl = NULL;
connection->proxy = NULL;
@@ -1048,6 +1080,29 @@
return connection;
}
+/**
+ * lm_connection_new_with_context:
+ * @server: The hostname to the server for the connection.
+ * @context: The context this connection should be running in.
+ *
+ * Creates a new closed connection running in a certain context. To open the
+ * connection call #lm_connection_open. @server can be #NULL but must be set
+ * before calling #lm_connection_open.
+ *
+ * Return value: A newly created LmConnection, should be unreffed with lm_connection_unref().
+ **/
+LmConnection *
+lm_connection_new_with_context (const gchar *server, GMainContext *context)
+{
+ LmConnection *connection;
+
+ connection = lm_connection_new (server);
+ connection->context = context;
+
+ g_main_context_ref (connection->context);
+
+ return connection;
+}
/**
* lm_connection_open:
@@ -1101,8 +1156,8 @@
}
while ((state = lm_connection_get_state (connection)) == LM_CONNECTION_STATE_CONNECTING) {
- if (g_main_context_pending (NULL)) {
- g_main_context_iteration (NULL, TRUE);
+ if (g_main_context_pending (connection->context)) {
+ g_main_context_iteration (connection->context, TRUE);
} else {
usleep (10);
}
@@ -1461,7 +1516,6 @@
}
}
-#if 0
/**
* lm_connection_get_proxy:
* @connection: an #LmConnection
@@ -1485,7 +1539,6 @@
*
* Sets the proxy to use for this connection.
*
- * Return value: The proxy or %NULL if no proxy is used. Notice that @connection can't be open while doing this.
**/
void
lm_connection_set_proxy (LmConnection *connection, LmProxy *proxy)
@@ -1504,7 +1557,6 @@
connection->proxy = lm_proxy_ref (proxy);
}
-#endif
/**
* lm_connection_send:
@@ -1614,7 +1666,7 @@
const gchar *m_id;
gint n;
- g_main_context_iteration (NULL, TRUE);
+ g_main_context_iteration (connection->context, TRUE);
if (lm_queue_is_empty (connection->incoming_messages)) {
continue;
@@ -1637,7 +1689,7 @@
g_free (id);
connection->incoming_source = connection_create_source (connection);
- g_source_attach (connection->incoming_source, NULL);
+ g_source_attach (connection->incoming_source, connection->context);
return reply;
}
--- a/loudmouth/lm-connection.h Thu Feb 05 22:18:20 2004 +0000
+++ b/loudmouth/lm-connection.h Thu Mar 18 00:04:59 2004 +0000
@@ -75,6 +75,8 @@
gpointer user_data);
LmConnection *lm_connection_new (const gchar *server);
+LmConnection *lm_connection_new_with_context (const gchar *server,
+ GMainContext *context);
gboolean lm_connection_open (LmConnection *connection,
LmResultFunction function,
gpointer user_data,
@@ -117,13 +119,9 @@
LmSSL * lm_connection_get_ssl (LmConnection *connection);
void lm_connection_set_ssl (LmConnection *connection,
LmSSL *ssl);
-/*
- * These will most likely change in the API
- *
LmProxy * lm_connection_get_proxy (LmConnection *connection);
void lm_connection_set_proxy (LmConnection *connection,
LmProxy *proxy);
-*/
gboolean lm_connection_send (LmConnection *connection,
LmMessage *message,
GError **error);
--- a/loudmouth/lm-internals.h Thu Feb 05 22:18:20 2004 +0000
+++ b/loudmouth/lm-internals.h Thu Mar 18 00:04:59 2004 +0000
@@ -33,6 +33,20 @@
GDestroyNotify notify;
} LmCallback;
+typedef struct {
+ LmConnection *connection;
+
+ /* struct to save resolved address */
+ struct addrinfo *resolved_addrs;
+ struct addrinfo *current_addr;
+ int fd;
+ GIOChannel *io_channel;
+} LmConnectData;
+
+void _lm_connection_failed_with_error (LmConnectData *connect_data,
+ int error);
+void _lm_connection_failed (LmConnectData *connect_data);
+gboolean _lm_connection_succeeded (LmConnectData *connect_data);
LmCallback * _lm_utils_new_callback (gpointer func,
gpointer data,
GDestroyNotify notify);
@@ -52,6 +66,9 @@
gint fd,
const gchar *server,
guint port);
+gboolean _lm_proxy_connect_cb (GIOChannel *source,
+ GIOCondition condition,
+ gpointer data);
void _lm_ssl_initialize (LmSSL *ssl);
gboolean _lm_ssl_begin (LmSSL *ssl,
gint fd,
--- a/loudmouth/lm-proxy.c Thu Feb 05 22:18:20 2004 +0000
+++ b/loudmouth/lm-proxy.c Thu Mar 18 00:04:59 2004 +0000
@@ -1,7 +1,7 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Copyright (C) 2004 Imendio HB
- * Copyright (C) Josh Beam <josh@3ddrome.com>
+ * Copyright (C) 2004 Josh Beam <josh@3ddrome.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License as
@@ -39,6 +39,7 @@
guint port;
gchar *username;
gchar *password;
+ guint io_watch;
gint ref_count;
};
@@ -48,6 +49,12 @@
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)
@@ -62,10 +69,10 @@
static gboolean
proxy_http_negotiate (LmProxy *proxy, gint fd, const gchar *server, guint port)
{
- gint i, len;
- gchar buf[1024];
gchar *str;
+ g_print ("http negotiate\n");
+
if (proxy->username && proxy->password) {
gchar *tmp1;
gchar *tmp2;
@@ -88,39 +95,69 @@
}
send (fd, str, strlen (str), 0);
-
g_free (str);
+ return TRUE;
+}
- len = read (fd, buf, 12);
- if (len <= 0) {
+/* 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;
}
- buf[len] = '\0';
- if (strcmp (buf, "HTTP/1.1 200") != 0 &&
- strcmp (buf, "HTTP/1.0 200") != 0) {
+ 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;
}
- /* discard any headers that we don't need */
- for (i = 0; i < 4; i++) {
- len = read (fd, buf + i, 1);
- if (len <= 0) {
- return FALSE;
- }
- }
- while (strncmp (buf, "\r\n\r\n", 4) != 0) {
- for (i = 0; i < 3; i++) {
- buf[i] = buf[i + 1];
- }
-
- len = read (fd, buf + 3, 1);
- if (len <= 0) {
- return FALSE;
- }
+ 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;
}
- return TRUE;
+ if (retval == TRUE) {
+ g_source_remove (proxy->io_watch);
+ _lm_connection_succeeded ((LmConnectData *) data);
+ }
+
+ return FALSE;
}
gboolean
@@ -140,6 +177,42 @@
return FALSE;
}
+gboolean
+_lm_proxy_connect_cb (GIOChannel *source, GIOCondition condition, gpointer data)
+{
+ LmConnection *connection;
+ LmConnectData *connect_data;
+ LmProxy *proxy;
+ int error;
+ int len = sizeof(error);
+
+ 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) {
+ getsockopt (connect_data->fd, SOL_SOCKET, SO_ERROR,
+ &error, &len);
+ _lm_connection_failed_with_error (connect_data, error);
+ return FALSE;
+ } else if (condition == G_IO_OUT) {
+ if (!_lm_proxy_negotiate (lm_connection_get_proxy (connection), connect_data->fd, lm_connection_get_server (connection), lm_connection_get_port (connection))) {
+ _lm_connection_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 ();
+ }
+
+ return FALSE;
+}
+
/**
* lm_proxy_new
* @type: the type of the new proxy
@@ -171,6 +244,31 @@
}
/**
+ * 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
+ **/
+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
*
--- a/loudmouth/lm-proxy.h Thu Feb 05 22:18:20 2004 +0000
+++ b/loudmouth/lm-proxy.h Thu Mar 18 00:04:59 2004 +0000
@@ -33,6 +33,9 @@
} LmProxyType;
LmProxy * lm_proxy_new (LmProxyType type);
+LmProxy * lm_proxy_new_with_server (LmProxyType type,
+ const gchar *server,
+ guint port);
LmProxyType lm_proxy_get_type (LmProxy *proxy);
void lm_proxy_set_type (LmProxy *proxy,
--- a/loudmouth/loudmouth.h Thu Feb 05 22:18:20 2004 +0000
+++ b/loudmouth/loudmouth.h Thu Mar 18 00:04:59 2004 +0000
@@ -28,6 +28,7 @@
#include <loudmouth/lm-message.h>
#include <loudmouth/lm-message-handler.h>
#include <loudmouth/lm-message-node.h>
+#include <loudmouth/lm-proxy.h>
#include <loudmouth/lm-utils.h>
#undef LM_INSIDE_LOUDMOUTH_H
--- a/loudmouth/test-jid.c Thu Feb 05 22:18:20 2004 +0000
+++ b/loudmouth/test-jid.c Thu Mar 18 00:04:59 2004 +0000
@@ -1,28 +0,0 @@
-#include "lm-jid.h"
-
-int
-main (int argc, char **argv)
-{
- int i;
-
- if (argc < 2) {
- g_print ("Usage: %s <jid> <jid> ...\n", argv[0]);
- exit (1);
- }
-
- for (i = 1; i < argc; ++i) {
- LmJID *jid;
-
- jid = lm_jid_new (argv[i]);
-
- g_print ("=======( JID[%i] )=======\n", i);
- g_print ("# Name: '%s'\n", jid->name);
- g_print ("# Host: '%s'\n", jid->host);
- if (jid->resource) {
- g_print ("# Resource: '%s'\n", jid->resource);
- }
- g_print ("-------------------------\n");
- g_print ("# JID: '%s'\n", lm_jid_to_string (jid));
- g_print ("=========================\n\n");
- }
-}
--- a/loudmouth/test-lm.c Thu Feb 05 22:18:20 2004 +0000
+++ b/loudmouth/test-lm.c Thu Mar 18 00:04:59 2004 +0000
@@ -1,236 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Copyright (C) 2003 Imendio HB
- * Copyright (C) 2003 Mikael Hallendal <micke@imendio.com>
- *
- * 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 <config.h>
-
-#include <glib.h>
-#include <string.h>
-#include <stdlib.h>
-#include <loudmouth/loudmouth.h>
-#ifdef __WIN32__
-#include <winsock2.h>
-#endif
-#include "lm-internals.h"
-
-typedef struct {
- gchar *name;
- gchar *passwd;
-} UserInfo;
-
-static void
-free_user_info (UserInfo *info)
-{
- g_free (info->name);
- g_free (info->passwd);
-
- g_free (info);
-}
-
-static unsigned char expected_fingerprint[20];
-
-static void
-print_finger (const unsigned char *fpr, unsigned int size)
-{
- gint i;
- for (i = 0; i < size-1; i++)
- g_print ("%02X:", (unsigned char) fpr[i]);
- g_print ("%02X", (unsigned char) fpr[size-1]);
-}
-
-static LmSSLResponse
-ssl_cb (LmSSL *ssl, LmSSLStatus status, gpointer ud)
-{
- g_print ("SSL status: %d\n", status);
- switch (status) {
- case LM_SSL_STATUS_NO_CERT_FOUND:
- g_print ("No certificate found!\n");
- break;
- case LM_SSL_STATUS_UNTRUSTED_CERT:
- g_print ("Certificate is not trusted!\n");
- break;
- case LM_SSL_STATUS_CERT_EXPIRED:
- g_print ("Certificate has expired!\n");
- break;
- case LM_SSL_STATUS_CERT_NOT_ACTIVATED:
- g_print ("Certificate has not been activated!\n");
- break;
- case LM_SSL_STATUS_CERT_HOSTNAME_MISMATCH:
- g_print ("Certificate hostname does not match expected hostname!\n");
- break;
- case LM_SSL_STATUS_CERT_FINGERPRINT_MISMATCH: {
- const unsigned char *fpr = lm_ssl_get_fingerprint (ssl);
- g_print ("Certificate fingerprint does not match expected fingerprint!\n");
- g_print ("Remote fingerprint: ");
- print_finger (fpr, 16);
- g_print ("\nExpected fingerprint: ");
- print_finger (expected_fingerprint, 16);
- g_print ("\n");
- break;
- }
- case LM_SSL_STATUS_GENERIC_ERROR:
- g_print ("Generic SSL error!\n");
- break;
- }
-
- return LM_SSL_RESPONSE_CONTINUE;
-}
-
-static void
-authentication_cb (LmConnection *connection, gboolean result, gpointer ud)
-{
- g_print ("Auth: %d\n", result);
-
- if (result == TRUE) {
- LmMessage *m;
-
- m = lm_message_new_with_sub_type (NULL,
- LM_MESSAGE_TYPE_PRESENCE,
- LM_MESSAGE_SUB_TYPE_AVAILABLE);
- g_print (":: %s\n", lm_message_node_to_string (m->node));
-
- lm_connection_send (connection, m, NULL);
- lm_message_unref (m);
- }
-}
-
-static void
-connection_open_cb (LmConnection *connection, gboolean result, UserInfo *info)
-{
- g_print ("Connected callback\n");
- lm_connection_authenticate (connection,
- info->name, info->passwd, "TestLM",
- authentication_cb, NULL,FALSE, NULL);
- g_print ("Sent auth message\n");
-}
-
-static LmHandlerResult
-handle_messages (LmMessageHandler *handler,
- LmConnection *connection,
- LmMessage *m,
- gpointer user_data)
-{
- g_print ("Incoming message from: %s\n",
- lm_message_node_get_attribute (m->node, "from"));
-
- return LM_HANDLER_RESULT_REMOVE_MESSAGE;
-}
-
-int
-main (int argc, char **argv)
-{
- GMainLoop *main_loop;
- LmConnection *connection;
- LmMessageHandler *handler;
- gboolean result;
- UserInfo *info;
-#ifdef __WIN32__
- WORD wVersionRequested;
- WSADATA wsaData;
- int err;
-#endif
-
- if (argc < 4) {
- g_print ("Usage: test-lm <server> <username> <password>\n"
- " test-lm <server> <username> <password> <fingerprint>\n");
- return 1;
- }
-
-/* Needed to build on Win32. */
-#ifdef __WIN32__
- wVersionRequested = MAKEWORD( 2, 2 );
-
- err = WSAStartup( wVersionRequested, &wsaData );
- if ( err != 0 ) {
- /* Tell the user that we could not find a usable */
- /* WinSock DLL. */
- return;
- }
-
- /* Confirm that the WinSock DLL supports 2.2.*/
- /* Note that if the DLL supports versions greater */
- /* than 2.2 in addition to 2.2, it will still return */
- /* 2.2 in wVersion since that is the version we */
- /* requested. */
-
- if ( LOBYTE( wsaData.wVersion ) != 2 ||
- HIBYTE( wsaData.wVersion ) != 2 ) {
- /* Tell the user that we could not find a usable */
- /* WinSock DLL. */
- WSACleanup( );
- return;
- }
-#endif
-
- connection = lm_connection_new (argv[1]);
-
- if (argc > 4 && !lm_ssl_is_supported ()) {
- g_error ("No SSL support!");
- exit (1);
- }
-
-
- handler = lm_message_handler_new (handle_messages, NULL, NULL);
- lm_connection_register_message_handler (connection, handler,
- LM_MESSAGE_TYPE_MESSAGE,
- LM_HANDLER_PRIORITY_NORMAL);
-
- lm_message_handler_unref (handler);
-
- info = g_new0 (UserInfo, 1);
- info->name = g_strdup (argv[2]);
- info->passwd = g_strdup (argv[3]);
-
- if (argc > 4) {
- int i;
- char *p;
- LmSSL *ssl;
-
- lm_connection_set_port (connection,
- LM_CONNECTION_DEFAULT_PORT_SSL);
-
- for (i = 0, p = argv[4]; *p && *(p+1); i++, p += 3)
- expected_fingerprint[i] = (unsigned char) g_ascii_strtoull (p, NULL, 16);
-
- ssl = lm_ssl_new (expected_fingerprint,
- (LmSSLFunction) ssl_cb,
- info,
- (GDestroyNotify) free_user_info);
-
- lm_connection_set_ssl (connection, ssl);
-
- lm_ssl_unref (ssl);
- }
-
- result = lm_connection_open (connection,
- (LmResultFunction) connection_open_cb,
- info, NULL, NULL);
-
- if (!result) {
- g_print ("Opening connection failed: %d\n", result);
- } else {
- g_print ("Returned from the connection_open\n");
- }
-
- main_loop = g_main_loop_new (NULL, FALSE);
- g_main_loop_run (main_loop);
-
- return 0;
-}