summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorsandmann <sandmann>2004-05-18 07:48:50 +0000
committersandmann <sandmann>2004-05-18 07:48:50 +0000
commitcc477a23dc9d7fb4b534d67265b3e3b2a442bb0a (patch)
tree291c79830282b84f849615afcd009684a62ce794 /tests
Initial revision
Diffstat (limited to 'tests')
-rwxr-xr-xtests/Makefile.am42
-rw-r--r--tests/activity.c124
-rw-r--r--tests/addr-test.c41
-rw-r--r--tests/cname-test.c42
-rw-r--r--tests/connection-test.c127
-rw-r--r--tests/connection2-test.c70
-rw-r--r--tests/dns-test-async.c65
-rw-r--r--tests/dns-test.c123
-rw-r--r--tests/dns-test2.c122
-rw-r--r--tests/dns-wait-test.c55
-rw-r--r--tests/dns2-test.c56
-rw-r--r--tests/htmlparser.c171
-rw-r--r--tests/htmlparser.h74
-rw-r--r--tests/http-test.c190
-rw-r--r--tests/lacwget.c672
-rw-r--r--tests/newdns-test.c117
-rw-r--r--tests/rdns-test-async.c78
-rw-r--r--tests/rdns-test.c56
-rw-r--r--tests/simple-test.c59
-rwxr-xr-xtests/trouble-sites.sh8
-rw-r--r--tests/udp-test.c88
-rw-r--r--tests/uri-test.c254
-rw-r--r--tests/watch-test.c108
23 files changed, 2742 insertions, 0 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100755
index 0000000..a18e4c2
--- /dev/null
+++ b/tests/Makefile.am
@@ -0,0 +1,42 @@
+TESTPROGRAMS = \
+ addr-test \
+ simple-test \
+ dns-test \
+ dns-test-async \
+ dns-test2 \
+ dns-wait-test \
+ rdns-test-async \
+ uri-test \
+ http-test \
+ connection-test \
+ connection2-test \
+ udp-test \
+ watch-test \
+ lacwget
+
+lacwget_SOURCES = \
+ lacwget.c \
+ htmlparser.c \
+ htmlparser.h
+
+noinst_PROGRAMS = $(TESTPROGRAMS)
+
+INCLUDES = -I$(top_srcdir)/src $(MODULES_XML_CFLAGS)
+
+addr_test_LDADD = $(top_builddir)/src/liblac-1.la
+simple_test_LDADD = $(top_builddir)/src/liblac-1.la
+dns_test_LDADD = $(top_builddir)/src/liblac-1.la
+dns_test_async_LDADD = $(top_builddir)/src/liblac-1.la
+dns_test2_LDADD = $(top_builddir)/src/liblac-1.la
+dns_wait_test_LDADD = $(top_builddir)/src/liblac-1.la
+rdns_test_async_LDADD = $(top_builddir)/src/liblac-1.la
+uri_test_LDADD = $(top_builddir)/src/liblac-1.la
+connection_test_LDADD = $(top_builddir)/src/liblac-1.la
+connection2_test_LDADD = $(top_builddir)/src/liblac-1.la
+http_test_LDADD = $(top_builddir)/src/liblac-1.la
+udp_test_LDADD = $(top_builddir)/src/liblac-1.la
+watch_test_LDADD = $(top_builddir)/src/liblac-1.la
+lacwget_LDADD = $(top_builddir)/src/liblac-1.la $(MODULES_XML_LIBS)
+lacwget_CFLAGS = $(MODULES_XML_CFLAGS)
+
+EXTRA_DIST = trouble-sites.sh
diff --git a/tests/activity.c b/tests/activity.c
new file mode 100644
index 0000000..6e80ee7
--- /dev/null
+++ b/tests/activity.c
@@ -0,0 +1,124 @@
+/* activity can be in one of four states:
+ *
+ * INIT
+ * RUNNING,
+ * CANCELED,
+ * TIMED_OUT,
+ * FINISHED
+ *
+ * lac_activity_wait() will return whenever the activity changes state, and
+ * whenever lac_activity_end() is called.
+ *
+ * it switches from INIT to RUNNING when lac_activity_begin() is called
+ * [what about time out?]
+ * it switches to FINISHED when lac_activity_end() is called the same
+ * number of times lac_activity_begin() has been called.
+ * it switches to TIMED_OUT when
+ * it switches to CANCELED when lac_activity_cancel has been called
+ * it switches from CANCELED or TIMED_OUT to RUNNING when
+ * lac_activity_continue() is called
+ *
+ * right after lac_actvity_new () the state of the activity is INIT
+ *
+ */
+
+void lac_address_new_lookup_from_name (name, activity, callback, data);
+void lac_address_new_from_name (name, activity, &addr, &err);
+
+/* trivial example */
+
+/* block until address (or error) arrives */
+lac_address_new_from_name ("slashdot.org", NULL, &addr, &err);
+
+
+/* simple example */
+static void
+on_cancel (GtkDialog *dialog, LacActivity *activity)
+{
+ lac_activity_cancel (activity);
+}
+
+activity = lac_activity_new ();
+
+g_signal_connect (dialog, "response", on_cancel, activity);
+
+lac_activity_set_timeout (activity, 5000);
+addr = lac_address_new_from_name ("slashdot.org", activity, &err);
+if (lac_activity_timed_out (activity) || lac_activity_canceled (activity))
+ /* canceled */;
+else
+ /* finished */;
+lac_activity_free (activity);
+
+
+/* callback example */
+activity = lac_activity_new ();
+lac_address_new_lookup_from_name (activity, "slashdot.org", cb, data);
+lac_activity_set_timeout (activity, 200);
+
+
+/* complex example */
+static void
+on_cancel (GtkDialog *dialog, LacActivity *activity)
+{
+ g_main_loop_quit (loop);
+}
+
+dialog = create_dialog ();
+
+activity = lac_activity_new ();
+f1 = lac_address_new_future_from_name (activity, "slashdot.org");
+f2 = lac_address_new_future_from_name (activity, "gnomedesktop.org");
+f3 = lac_address_new_future_from_name (activity, "news.kde.org");
+lac_activity_set_timeout (activity, 100);
+
+while (lac_activity_running (activity))
+{
+ lac_activity_wait (activity);
+
+ if (!addr1 && lac_future_ready (f1))
+ {
+ addr1 = lac_future_get_data (f1);
+ /* update label 1 */
+ }
+ else if (!addr2 && lac_future_ready (f2))
+ {
+ addr2 = lac_future_get_data (f2);
+ /* update label 2 */
+ }
+ else if (!addr3 && lac_future_ready (f3))
+ {
+ addr3 = lac_future_get_data (f3);
+ /* update label 3 */
+ }
+ else
+ {
+ elapsed = g_timer_elapsed (timer, NULL);
+ if (!lac_activity_canceled (activity) && elapsed < 5000)
+ {
+ gtk_progress_bar_set_percentage (pbar, 100 * (elapsed / 5000));
+ lac_activity_continue (activity);
+ }
+ }
+}
+
+gtk_widget_destroy (dialog);
+g_timer_destroy (timer);
+
+if (lac_activity_canceled (activity))
+{
+ /* user canceled */
+}
+else if (lac_activity_timed_out (activity))
+{
+ /* no response within 5000 seconds */
+}
+else
+{
+ /* activity finished normally */
+}
+
+lac_activity_free (activity);
+lac_future_free (future1);
+lac_future_free (future2);
+lac_future_free (future3);
diff --git a/tests/addr-test.c b/tests/addr-test.c
new file mode 100644
index 0000000..1553d44
--- /dev/null
+++ b/tests/addr-test.c
@@ -0,0 +1,41 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- */
+
+/* Lac - Library for asynchronous communication
+ * Copyright (C) 2002 Søren Sandmann (sandmann@daimi.au.dk)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <lac.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int
+main (int argc, char *argv[])
+{
+ int fd = lac_socket_udp(NULL);
+ int port;
+ LacAddress *loopback = lac_address_new_from_a_b_c_d (127, 0, 0, 1);
+ gchar buf[128];
+ LacAddress *my_address;
+
+ lac_sendto (fd, "Hello", strlen ("Hello"), loopback, 128, NULL);
+ g_print ("sent\n");
+ lac_recvfrom (fd, buf, sizeof (buf), &my_address, &port, NULL);
+
+ g_print ("my address: %s\n", lac_address_to_string (my_address));
+ return 0;
+}
diff --git a/tests/cname-test.c b/tests/cname-test.c
new file mode 100644
index 0000000..a57d956
--- /dev/null
+++ b/tests/cname-test.c
@@ -0,0 +1,42 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- */
+
+/* Lac - Library for asynchronous communication
+ * Copyright (C) 2002 Søren Sandmann (sandmann@daimi.au.dk)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <lac.h>
+
+static void
+disaster (GError *err)
+{
+ g_print ("error: %s\n", err->message);
+ exit (1);
+}
+
+int
+main (int argc, char *argv[])
+{
+ GError *err = NULL
+ int fd = lac_socket_udp (&err);
+ if (fd < 0)
+ disaster (err);
+
+ if (lac_send (fd, "Hello", strlen ("Hello"), &err) < 0)
+ disaster (err);
+
+
+}
diff --git a/tests/connection-test.c b/tests/connection-test.c
new file mode 100644
index 0000000..e928f43
--- /dev/null
+++ b/tests/connection-test.c
@@ -0,0 +1,127 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- */
+
+/* Lac - Library for asynchronous communication
+ * Copyright (C) 2002 Søren Sandmann (sandmann@daimi.au.dk)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <lac.h>
+#include <string.h>
+
+GMainLoop *main_loop;
+int n_connections = 0;
+
+static void
+connection_write (LacConnection *connection, gchar *str)
+{
+#if 0
+ g_print ("%s", str);
+#endif
+ lac_connection_write (connection, str, strlen (str));
+}
+
+static void
+conn_callback (LacConnection *connection, const LacConnectionEvent *event)
+{
+ gchar *s;
+
+ g_print ("connection to %s:80: ", (gchar *)lac_connection_get_data (connection));
+ switch (event->type)
+ {
+ case LAC_CONNECTION_EVENT_CONNECT:
+ g_print ("CONNECT\n");
+ connection_write (connection, "GET / HTTP/1.1\r\n");
+ connection_write (connection, "Host: ");
+ connection_write (connection, lac_connection_get_data (connection));
+ connection_write (connection, "\r\n\r\n");
+ break;
+
+ case LAC_CONNECTION_EVENT_READ:
+ g_print ("READ (%d bytes)\n", event->read.len);
+ s = g_new (guchar, event->read.len + 1);
+ strncpy (s, event->read.data, event->read.len);
+ s[event->read.len] = '\0';
+ g_print ("%s\n", s);
+ g_free (s);
+ break;
+
+ case LAC_CONNECTION_EVENT_CLOSE:
+ g_print ("CLOSE (%s)\n", event->close.remote_closed?
+ "remote" : "local");
+ lac_connection_unref (connection);
+ if (--n_connections == 0)
+ g_main_loop_quit (main_loop);
+ break;
+
+ case LAC_CONNECTION_EVENT_ERROR:
+ g_print ("ERROR (%s)\n", event->error.err->message);
+ lac_connection_unref (connection);
+ if (--n_connections == 0)
+ g_main_loop_quit (main_loop);
+ break;
+
+ default:
+ g_print ("event->type == %d?\n", event->type);
+ g_assert_not_reached ();
+ break;
+ }
+}
+
+static void
+callback (const LacAddress *addr, gpointer data, const GError *err)
+{
+ if (err)
+ {
+ g_print (" (%p) ", err->message);
+ g_print ("%s\n", err->message);
+ }
+ else
+ {
+ LacConnection *connection;
+
+ connection = lac_connection_new (addr, 80, conn_callback, data);
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+
+#if 0
+ lac_set_verbose (TRUE);
+#endif
+
+ if (argc > 1)
+ {
+ for (i = 1; i < argc; ++i)
+ {
+ ++n_connections;
+ lac_address_new_lookup_from_name (argv[i], callback, argv[i]);
+ }
+ }
+ else
+ {
+ g_print ("usage %s <names>\n", argv[0]);
+ return 1;
+ }
+
+ main_loop = g_main_loop_new (NULL, TRUE);
+ g_assert (main_loop);
+ g_main_loop_run (main_loop);
+
+ return 0;
+}
diff --git a/tests/connection2-test.c b/tests/connection2-test.c
new file mode 100644
index 0000000..c2bc370
--- /dev/null
+++ b/tests/connection2-test.c
@@ -0,0 +1,70 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- */
+
+/* Lac - Library for asynchronous communication
+ * Copyright (C) 2002 Søren Sandmann (sandmann@daimi.au.dk)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <lac.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/tcp.h>
+#include <string.h>
+
+int
+main (int argc, char *argv[])
+{
+ LacAddress *addr =
+ lac_address_new_from_name_wait ("www.toyota.co.jp", NULL, NULL);
+ int fd;
+ guchar blah[60000];
+ GTimer *timer;
+ int len;
+
+ g_assert (addr);
+
+ fd = lac_socket_tcp (NULL);
+
+ g_assert (fd > 0);
+
+ g_assert (lac_connect (fd, addr, 80, NULL));
+
+#define line1 "GET / HTTP/1.1\r\n"
+#define line2 "host: www.toyota.co.jp\r\n\r\n"
+
+ timer = g_timer_new ();
+
+ lac_send (fd, line1, strlen (line1), NULL);
+ lac_send (fd, line2, strlen (line2), NULL);
+
+ lac_set_nagle (fd, FALSE, NULL);
+ lac_set_nagle (fd, TRUE, NULL);
+
+#if 0
+ lac_send (fd, line1 line2, strlen (line1) + strlen (line2), NULL);
+#endif
+
+ while ((len = lac_recv (fd, blah, sizeof (blah), NULL)) > 0)
+ {
+ int i;
+ for (i = 0; i < len; ++i)
+ g_print ("%c", blah[i]);
+ }
+
+ g_print ("elapsed: %f\n", g_timer_elapsed (timer, NULL));
+
+ return 0;
+}
diff --git a/tests/dns-test-async.c b/tests/dns-test-async.c
new file mode 100644
index 0000000..2896349
--- /dev/null
+++ b/tests/dns-test-async.c
@@ -0,0 +1,65 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- */
+
+/* Lac - Library for asynchronous communication
+ * Copyright (C) 2002 Søren Sandmann (sandmann@daimi.au.dk)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <lac.h>
+
+static void
+callback (const LacAddress *addr, gpointer data, const GError *err)
+{
+ gchar *name = data;
+
+ g_print ("%s: ", name);
+
+ if (err)
+ {
+ g_print (" (%p) ", err->message);
+ g_print ("%s\n", err->message);
+ }
+ else
+ {
+ g_print ("%s\n", lac_address_to_string (addr));
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+ GMainLoop *main_loop;
+
+ lac_set_verbose (TRUE);
+
+ if (argc > 1)
+ {
+ for (i = 1; i < argc; ++i)
+ lac_address_new_lookup_from_name (argv[i], callback, argv[i]);
+ }
+ else
+ {
+ g_print ("usage %s <names>\n", argv[0]);
+ return 1;
+ }
+
+ main_loop = g_main_loop_new (NULL, TRUE);
+ g_assert (main_loop);
+ g_main_loop_run (main_loop);
+
+ return 0;
+}
diff --git a/tests/dns-test.c b/tests/dns-test.c
new file mode 100644
index 0000000..7844fab
--- /dev/null
+++ b/tests/dns-test.c
@@ -0,0 +1,123 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- */
+
+/* Lac - Library for asynchronous communication
+ * Copyright (C) 2002 Søren Sandmann (sandmann@daimi.au.dk)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <lac.h>
+#include <string.h>
+
+static int n_outstanding;
+static GMainLoop *main_loop;
+
+static void
+name_callback (const gchar *name, gpointer data, const GError *err)
+{
+ gchar *addr_str = data;
+
+ if (err)
+ {
+ g_print ("reverse %s: %s\n", addr_str, err->message);
+ }
+ else
+ {
+ g_print ("reverse %s: %s\n", addr_str, name);
+ }
+ g_free (addr_str);
+}
+
+static void
+callback (const GPtrArray *addresses, gpointer data, const GError *err)
+{
+ gchar *name = data;
+
+ if (err)
+ {
+ g_print ("%s: %s\n", name, err->message);
+ }
+ else
+ {
+ int i;
+
+ if (addresses->len == 0)
+ g_print ("this should not happen\n");
+ for (i = 0; i < addresses->len; ++i)
+ {
+ gchar *addr = lac_address_to_string (addresses->pdata[i]);
+ g_print ("%s: %s\n", name, addr);
+
+ lac_address_lookup_name (addresses->pdata[i], name_callback, addr);
+ }
+
+ }
+
+ if (!strstr (name, "again"))
+ {
+ gchar *tmp;
+
+ n_outstanding += 2;
+ lac_address_new_lookup_all_from_name (name, callback, g_strdup_printf ("%s again", name));
+
+ tmp = g_ascii_strup (name, -1);
+ lac_address_new_lookup_all_from_name (tmp, callback, g_strdup_printf ("%s (UPPER) again", name));
+ g_free (tmp);
+ }
+
+#if 0
+ if (--n_outstanding == 0)
+ g_main_quit (main_loop);
+#endif
+ g_free (name);
+}
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+
+ main_loop = g_main_loop_new (NULL, TRUE);
+ g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_ERROR |
+ G_LOG_LEVEL_CRITICAL);
+
+ lac_set_verbose (TRUE);
+
+#if 0
+ torture_test();
+#endif
+
+ if (argc > 1)
+ {
+ for (i = 1; i < argc; ++i)
+ {
+ ++n_outstanding;
+ lac_address_new_lookup_all_from_name (argv[i], callback, g_strdup (argv[i]));
+ }
+ }
+ else
+ {
+ g_print ("usage %s <names>\n", argv[0]);
+ return 1;
+ }
+
+ g_assert (main_loop);
+#if 0
+ g_timeout_add (12000, g_main_loop_quit, main_loop);
+#endif
+ g_main_loop_run (main_loop);
+
+ return 0;
+}
diff --git a/tests/dns-test2.c b/tests/dns-test2.c
new file mode 100644
index 0000000..c70b91b
--- /dev/null
+++ b/tests/dns-test2.c
@@ -0,0 +1,122 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- */
+
+/* Lac - Library for asynchronous communication
+ * Copyright (C) 2002, 2003 Søren Sandmann (sandmann@daimi.au.dk)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <lac.h>
+#include <string.h>
+
+static int n_outstanding;
+static GMainLoop *main_loop;
+
+static void
+name_callback (const gchar *name, gpointer data, const GError *err)
+{
+ gchar *addr_str = data;
+
+ if (err)
+ {
+ g_print ("reverse %s: %s\n", addr_str, err->message);
+ }
+ else
+ {
+ g_print ("reverse %s: %s\n", addr_str, name);
+ }
+ g_free (addr_str);
+}
+
+static void
+callback (const GPtrArray *addresses, gpointer data, const GError *err)
+{
+ const gchar *name = data;
+
+ if (err)
+ {
+ g_print ("%s: %s\n", name, err->message);
+ }
+ else
+ {
+ int i;
+
+ GQueue *reverse_lookups = g_queue_new ();
+
+ g_assert (addresses->len > 0);
+
+ g_print ("%s: ", name);
+ for (i = 0; i < addresses->len; ++i)
+ {
+ gchar *addr_str = lac_address_to_string (addresses->pdata[i]);
+
+ g_print ("%s ", addr_str);
+
+ g_queue_push_tail (reverse_lookups, addresses->pdata[i]);
+ g_queue_push_tail (reverse_lookups, addr_str);
+ }
+ g_print ("\n");
+
+ while (!g_queue_is_empty (reverse_lookups))
+ {
+ LacAddress *address = g_queue_pop_head (reverse_lookups);
+ gpointer addr_string = g_queue_pop_head (reverse_lookups);
+
+ lac_address_lookup_name (address, name_callback, addr_string);
+ }
+ g_queue_free (reverse_lookups);
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+
+ main_loop = g_main_loop_new (NULL, TRUE);
+ g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_ERROR |
+ G_LOG_LEVEL_CRITICAL);
+
+ lac_set_verbose (TRUE);
+
+ if (argc > 1)
+ {
+ for (i = 1; i < argc; ++i)
+ {
+ LacActivity activity;
+ ++n_outstanding;
+ activity = lac_address_new_lookup_all_from_name (
+ argv[i], callback, argv[i]);
+
+ if (i == 3 || i == 4)
+ {
+ g_print ("canceling\n");
+ lac_activity_cancel (activity);
+ }
+
+ }
+ }
+ else
+ {
+ g_print ("usage %s <names>\n", argv[0]);
+ return 1;
+ }
+
+ g_assert (main_loop);
+ g_timeout_add (500, g_main_loop_quit, main_loop);
+ g_main_loop_run (main_loop);
+
+ return 0;
+}
diff --git a/tests/dns-wait-test.c b/tests/dns-wait-test.c
new file mode 100644
index 0000000..224368c
--- /dev/null
+++ b/tests/dns-wait-test.c
@@ -0,0 +1,55 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- */
+
+/* Lac - Library for asynchronous communication
+ * Copyright (C) 2003 Søren Sandmann (sandmann@daimi.au.dk)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <lac.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/tcp.h>
+#include <string.h>
+
+static gboolean
+timeout (gpointer data)
+{
+ LacActivity activity = data;
+ g_print ("hej\n");
+ lac_activity_cancel (activity);
+ return FALSE;
+}
+
+int
+main (int argc, char *argv[])
+{
+ LacAddress *addr;
+ LacActivity activity;
+ int id;
+
+ if (argc < 2)
+ return 0;
+
+ id = g_timeout_add (10, lac_activity_cancel, activity);
+ addr = lac_address_new_from_name_wait (argv[1], &activity, NULL);
+
+ if (addr)
+ g_print ("address: %s\n", lac_address_to_string (addr));
+ else
+ g_print ("canceled\n");
+
+ return 0;
+}
diff --git a/tests/dns2-test.c b/tests/dns2-test.c
new file mode 100644
index 0000000..03ffa20
--- /dev/null
+++ b/tests/dns2-test.c
@@ -0,0 +1,56 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- */
+
+/* Lac - Library for asynchronous communication
+ * Copyright (C) 2002 Søren Sandmann (sandmann@daimi.au.dk)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <lac.h>
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+ LacAddress *addr;
+
+ lac_set_verbose (TRUE);
+
+ if (argc > 1)
+ {
+ for (i = 1; i < argc; ++i)
+ {
+ GError *err = NULL;
+ addr = lac_gethostbyname (argv[i], &err);
+
+ if (!addr)
+ {
+ g_print ("%s: error (%s)\n", argv[i], err->message);
+ g_error_free (err);
+ }
+ else
+ {
+ g_print ("%s: %s\n", argv[i], lac_address_to_str (addr));
+ lac_address_unref (addr);
+ }
+ }
+ return 0;
+ }
+ else
+ {
+ g_print ("usage %s <names>\n", argv[0]);
+ return 1;
+ }
+}
diff --git a/tests/htmlparser.c b/tests/htmlparser.c
new file mode 100644
index 0000000..b36a862
--- /dev/null
+++ b/tests/htmlparser.c
@@ -0,0 +1,171 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- */
+
+/* Lac - Library for asynchronous communication
+ * Copyright (C) 2002 Søren Sandmann (sandmann@daimi.au.dk)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "htmlparser.h"
+#include <libxml/HTMLparser.h>
+
+struct HtmlParser {
+ HtmlParserFunc callback;
+ gpointer data;
+ GString * unparsed;
+ xmlParserCtxt * xml_context;
+};
+
+static void
+start_element_cb (void *ctx,
+ const xmlChar *name,
+ const xmlChar **atts)
+{
+ HtmlParser *parser = ctx;
+ HtmlParserEvent event;
+ GPtrArray *attributes = g_ptr_array_new ();
+ int i;
+
+ event.type = HTML_PARSER_BEGIN_ELEMENT;
+ event.begin_element.name = name;
+
+ if (atts)
+ {
+ const xmlChar **s;
+ for (s = atts; *s != NULL; )
+ {
+ HtmlAttribute *attr = g_new (HtmlAttribute, 1);
+
+ attr->name = *s++;
+ attr->content = *s++;
+
+ g_ptr_array_add (attributes, attr);
+ }
+ }
+
+ event.begin_element.attributes = attributes;
+
+ parser->callback (parser, &event);
+
+ for (i = 0; i < attributes->len; ++i)
+ g_free (attributes->pdata[i]);
+ g_ptr_array_free (attributes, TRUE);
+}
+
+static void
+end_element_cb (void *ctx,
+ const xmlChar *name)
+{
+ HtmlParser *parser = ctx;
+ HtmlParserEvent event;
+
+ event.type = HTML_PARSER_END_ELEMENT;
+ event.end_element.name = name;
+
+ parser->callback (parser, &event);
+}
+
+static void
+comment_cb (void *ctx,
+ const xmlChar *comment)
+{
+ HtmlParser *parser = ctx;
+ HtmlParserEvent event;
+
+ event.type = HTML_PARSER_COMMENT;
+ event.comment.text = comment;
+
+ parser->callback (parser, &event);
+}
+
+static void
+end_document_cb (void *ctx)
+{
+ HtmlParser *parser = ctx;
+ HtmlParserEvent event;
+
+ event.type = HTML_PARSER_END_DOCUMENT;
+
+ parser->callback (parser, &event);
+}
+
+static htmlSAXHandler html_sax_handler = {
+ NULL, /* internalSubset */
+ NULL, /* isStandalone */
+ NULL, /* hasInternalSubset */
+ NULL, /* hasExternalSubset */
+ NULL, /* resolveEntity */
+ NULL, /* getEntity */
+ NULL, /* entityDecl */
+ NULL, /* notationDecl */
+ NULL, /* attributeDecl */
+ NULL, /* elementDecl */
+ NULL, /* unparsedEntityDecl */
+ NULL, /* setDocumentLocator */
+
+ NULL, /* startDocument */
+ end_document_cb, /* endDocument */
+ start_element_cb, /* startElement */
+ end_element_cb, /* endElement */
+ NULL, /* reference */
+ NULL, /* characters */
+ NULL, /* ignorableWhitespace */
+ NULL, /* processingInstruction */
+ comment_cb, /* comment */
+ NULL, /* warning */
+ NULL, /* error */
+ NULL, /* fatalError */
+ NULL, /* getParameterEntity */
+ NULL, /* cdataBlock */
+ NULL /* externalSubset */
+};
+
+HtmlParser *
+html_parser_new (HtmlParserFunc f,
+ gpointer data)
+{
+ HtmlParser *html_parser = g_new (HtmlParser, 1);
+
+ g_return_val_if_fail (f != NULL, NULL);
+
+ html_parser->callback = f;
+ html_parser->data = data;
+ html_parser->unparsed = g_string_new ("");
+ html_parser->xml_context = htmlCreatePushParserCtxt (
+ &html_sax_handler, html_parser, NULL, 0, NULL, -1);
+
+ return html_parser;
+}
+
+void
+html_parser_push_data (HtmlParser *parser,
+ const gchar *data,
+ guint len)
+{
+ htmlParseChunk (parser->xml_context, data, len, 0);
+}
+
+void
+html_parser_push_eof (HtmlParser *parser)
+{
+ htmlParseChunk (parser->xml_context, NULL, 0, 1);
+}
+
+gpointer
+html_parser_get_data (HtmlParser *parser)
+{
+ return parser->data;
+}
diff --git a/tests/htmlparser.h b/tests/htmlparser.h
new file mode 100644
index 0000000..28758ea
--- /dev/null
+++ b/tests/htmlparser.h
@@ -0,0 +1,74 @@
+/* Lac - Library for asynchronous communication
+ * Copyright (C) 2002 Søren Sandmann (sandmann@daimi.au.dk)
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <glib.h>
+
+typedef struct HtmlParser HtmlParser;
+
+typedef enum {
+ HTML_PARSER_BEGIN_ELEMENT,
+ HTML_PARSER_END_ELEMENT,
+ HTML_PARSER_COMMENT,
+ HTML_PARSER_END_DOCUMENT
+} HtmlParserEventType;
+
+typedef struct {
+ const char *name;
+ const char *content;
+} HtmlAttribute;
+
+typedef struct {
+ HtmlParserEventType type;
+ const gchar *name;
+ const GPtrArray *attributes; /* OF const HtmlAttribute * */
+} HtmlParserBeginElementEvent;
+
+typedef struct {
+ HtmlParserEventType type;
+ const gchar *name;
+} HtmlParserEndElementEvent;
+
+typedef struct {
+ HtmlParserEventType type;
+ const gchar *text;
+} HtmlParserComment;
+
+typedef struct {
+ HtmlParserEventType type;
+} HtmlParserEndDocument;
+
+typedef union HtmlParserEvent HtmlParserEvent;
+union HtmlParserEvent {
+ HtmlParserEventType type;
+ HtmlParserBeginElementEvent begin_element;
+ HtmlParserEndElementEvent end_element;
+ HtmlParserComment comment;
+ HtmlParserEndDocument end_document;
+};
+
+typedef void (* HtmlParserFunc) (HtmlParser *parser,
+ const HtmlParserEvent *event);
+
+HtmlParser *html_parser_new (HtmlParserFunc f,
+ gpointer data);
+void html_parser_push_data (HtmlParser *parser,
+ const gchar *data,
+ gsize len);
+void html_parser_push_eof (HtmlParser *parser);
+gpointer html_parser_get_data (HtmlParser *parser);
+
diff --git a/tests/http-test.c b/tests/http-test.c
new file mode 100644
index 0000000..240d563
--- /dev/null
+++ b/tests/http-test.c
@@ -0,0 +1,190 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- */
+
+/* Lac - Library for asynchronous communication
+ * Copyright (C) 2002 Søren Sandmann (sandmann@daimi.au.dk)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <lac.h>
+#include <string.h>
+#include <stdio.h>
+
+static int n_requests;
+GMainLoop *main_loop;
+
+#if 0
+static GPtrArray *outstanding_requests;
+static GPtrArray *error_requests;
+#endif
+
+static gboolean
+show_outstanding (gpointer data)
+{
+#if 0
+ int i;
+
+ g_print (">>>>> outstanding: %d\n", n_requests);
+ for (i = 0; i < outstanding_requests->len; ++i)
+ {
+ gchar *uri_str = lac_http_request_get_data (outstanding_requests->pdata[i]);
+ g_print (" %d: %s\n", i+1, uri_str);
+ }
+
+ g_print (">>>>> error requests: %d\n", error_requests->len);
+ for (i = 0; i < error_requests->len; ++i)
+ {
+ gchar *uri_str = lac_http_request_get_data (error_requests->pdata[i]);
+ g_print (" %d: %s\n", i+1, uri_str);
+ }
+
+#endif
+ return TRUE;
+}
+
+static void
+lac_http_callback (LacHttpRequest *request, const LacHttpEvent *event)
+{
+ gchar *uri_str = lac_http_request_get_data (request);
+ gchar *s;
+
+ switch (event->type)
+ {
+ case LAC_HTTP_EVENT_HOST_FOUND:
+ s = lac_address_to_string (event->host_found.address);
+ g_print ("%s: host found (%s)\n", uri_str, s);
+ g_free (s);
+ break;
+
+ case LAC_HTTP_EVENT_CONNECTING:
+ g_print ("%s: connecting\n", uri_str);
+ break;
+
+ case LAC_HTTP_EVENT_SENT:
+ g_print ("%s: sent (non-pipelined)\n", uri_str);
+ break;
+
+ case LAC_HTTP_EVENT_STATUS_LINE:
+ g_print ("%s: status line: %d %s\n", uri_str,
+ event->status_line.status_code, event->status_line.reason_phrase);
+ break;
+
+ case LAC_HTTP_EVENT_HEADER:
+ g_print ("%s: %s: %s\n", uri_str, event->header.header, event->header.value);
+ break;
+
+ case LAC_HTTP_EVENT_BEGIN_CONTENT:
+ g_print ("%s: begin content (length %d)\n", uri_str, event->begin_content.length);
+ break;
+
+ case LAC_HTTP_EVENT_CONTENT:
+ g_print ("%s: content chunk (size: %d)\n", uri_str, event->content.length);
+ break;
+
+ case LAC_HTTP_EVENT_END_CONTENT:
+ printf ("%s: end_content (total: %d)\n", uri_str, event->end_content.total);
+#if 0
+ g_ptr_array_remove (outstanding_requests, request);
+#endif
+ lac_http_request_unref (request);
+ if (--n_requests == 0)
+ g_main_loop_quit (main_loop);
+ break;
+
+ case LAC_HTTP_EVENT_ERROR:
+#if 0
+ g_ptr_array_remove (outstanding_requests, request);
+ g_ptr_array_add (error_requests, request);
+#endif
+ lac_http_request_unref (request);
+ g_print ("%s: error (%s)\n", uri_str, event->error.err->message);
+ if (--n_requests == 0)
+ g_main_loop_quit (main_loop);
+ break;
+
+ default:
+ g_print ("%s: UNKNOWN (%d)\n", uri_str, event->type);
+ break;
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+
+ g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_ERROR |
+ G_LOG_LEVEL_CRITICAL);
+
+
+ lac_set_verbose (TRUE);
+#if 0
+ outstanding_requests = g_ptr_array_new ();
+ error_requests = g_ptr_array_new ();
+#endif
+
+ if (argc > 1)
+ {
+ for (i = 1; i < argc; ++i)
+ {
+ LacHttpRequest *request;
+
+ LacUri *uri = lac_uri_new_from_str (NULL, argv[i]);
+ if (!uri)
+ {
+ g_print ("bad uri: %s\n", argv[i]);
+ continue;
+ }
+
+ request = lac_http_request_new_get (
+ uri, lac_http_callback, argv[i]);
+
+ lac_uri_free (uri);
+ lac_http_request_dispatch (request);
+
+#if 0
+ g_ptr_array_add (outstanding_requests, request);
+#endif
+
+ ++n_requests;
+ }
+ }
+ else
+ {
+ g_print ("usage %s <names>\n", argv[0]);
+ return 1;
+ }
+
+ main_loop = g_main_loop_new (NULL, TRUE);
+#if 0
+ g_timeout_add (38000, g_main_loop_quit, main_loop);
+#endif
+#if 0
+ g_timeout_add (5000, show_outstanding, NULL);
+#endif
+ g_print ("dispatched requests\n");
+ g_assert (main_loop);
+ g_main_loop_run (main_loop);
+ g_print ("after main loop\n");
+#if 0
+ g_print ("outstanding_requests->len = %d\n", outstanding_requests->len);
+ g_print ("error_requests->len = %d\n", error_requests->len);
+#endif
+#if 0
+ g_ptr_array_free (outstanding_requests, TRUE);
+ g_ptr_array_free (error_requests, TRUE);
+#endif
+ return 0;
+}
diff --git a/tests/lacwget.c b/tests/lacwget.c
new file mode 100644
index 0000000..f1eabbf
--- /dev/null
+++ b/tests/lacwget.c
@@ -0,0 +1,672 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- */
+
+/* Lac - Library for asynchronous communication
+ * Copyright (C) 2002, 2003 Søren Sandmann (sandmann@daimi.au.dk)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <lac.h>
+#include "htmlparser.h"
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+// #define g_print(...)
+
+static GMainLoop *main_loop;
+static GTimer *total = NULL;
+
+static gboolean do_download (LacUri *base_uri, const gchar *uri_str, gboolean try_parse);
+
+typedef struct Data {
+ gchar *uri_str;
+ gdouble time;
+ gdouble first_connect;
+ gdouble first_content;
+ gdouble first_image_tag;
+ gdouble first_idle;
+ gdouble first_parser_callback;
+ guint n_content_chunks;
+ guint n_parser_calls;
+ gdouble parser_eof;
+ gint n_images;
+ gint n_links;
+ gboolean try_parse;
+} Data;
+
+static GQueue *statistics = NULL;
+
+typedef struct PageInfo {
+ GTimer *timer;
+ gchar *main_uri;
+ LacUri *base_uri;
+ gdouble first_connect;
+ gdouble first_image_tag;
+ gdouble first_content;
+ gdouble first_idle;
+ gdouble first_parser_callback;
+ GString *unparsed;
+ gboolean eof;
+ HtmlParser *parser;
+ gint idle_id;
+ gint n_remaining_images;
+ gint n_images;
+ gint n_links;
+ gboolean done;
+ guint n_content_chunks;
+ guint n_parser_calls;
+ gdouble parser_eof;
+ gboolean is_redirect;
+ gboolean try_parse;
+} PageInfo;
+
+static GPtrArray *outstanding_page_infos;
+
+typedef struct ImageInfo {
+ FILE *f;
+ PageInfo *page_info;
+ gchar *uri_str;
+} ImageInfo;
+
+static gboolean
+print_outstanding (gpointer data)
+{
+ int i;
+
+ g_print ("outstanding:\n");
+ for (i = 0; i < outstanding_page_infos->len; ++i)
+ {
+ PageInfo *info = outstanding_page_infos->pdata[i];
+ if (info->try_parse)
+ g_print ("%s: %d images %s\n", info->main_uri, info->n_remaining_images, info->done? "- main page done" : "+ rest of main page");
+ }
+ return TRUE;
+}
+
+static gchar *
+truncat (gchar *str)
+{
+ enum {STRLEN = 200};
+ if (strlen (str) > STRLEN)
+ {
+ gchar *new_str = g_malloc (STRLEN + 1);
+ strncpy (new_str, str, STRLEN - 3);
+ strncpy (new_str + STRLEN - 3, "...", 3);
+ new_str[STRLEN] = '\0';
+ return new_str;
+ }
+ else
+ return str;
+}
+
+static void
+maybe_quit (PageInfo *info)
+{
+ if (info->n_remaining_images == 0 &&
+ ((info->try_parse && info->done && info->eof) ||
+ (!info->try_parse && info->eof)))
+ {
+ Data *data = g_new (Data, 1);
+
+ data->uri_str = info->main_uri;
+ data->time = g_timer_elapsed (info->timer, NULL);
+ data->first_connect = info->first_connect;
+ data->first_image_tag = info->first_image_tag;
+ data->first_content = info->first_content;
+ data->first_idle = info->first_idle;
+ data->first_parser_callback = info->first_parser_callback;
+ data->n_content_chunks = info->n_content_chunks;
+ data->n_parser_calls = info->n_parser_calls;
+ data->parser_eof = info->parser_eof;
+ data->n_images = info->n_images;
+ data->n_links = info->n_links;
+ data->try_parse = info->try_parse;
+
+ if (!statistics)
+ statistics = g_queue_new ();
+ g_queue_push_tail (statistics, data);
+
+ g_ptr_array_remove (outstanding_page_infos, info);
+ if (outstanding_page_infos->len == 0)
+ {
+ int total_requests = 0;
+ GList *list;
+
+#if 0
+ printf ("\n\n\n\n");
+#endif
+ for (list = statistics->head; list != NULL; list = list->next)
+ {
+ Data *data = list->data;
+ if (data->try_parse)
+ {
+ g_print ("%s:\n", data->uri_str);
+ g_print (" total: %f \n", data->time);
+ g_print (" connected: %f \n", data->first_connect);
+ g_print (" first content: %f \n", data->first_content);
+ g_print (" first idle: %f \n", data->first_idle);
+ g_print (" first parser callback: %f\n", data->first_parser_callback);
+ g_print (" first imgtag seen: %f\n", data->first_image_tag);
+ g_print (" push eof to parser: %f\n", data->parser_eof);
+ g_print (" content chunks: %d\n", data->n_content_chunks);
+ g_print (" parser calls: %d\n", data->n_parser_calls);
+ g_print (" number of images: %d\n", data->n_images);
+ g_print (" number of LINK/href elmts %d\n", data->n_links);
+ g_print ("\n");
+ total_requests += data->n_images + data->n_links + 1;
+ }
+ }
+ printf ("%d requests in ", total_requests);
+ printf ("total time: %f\n", g_timer_elapsed (total, NULL));
+ g_main_loop_quit (main_loop);
+#if 0
+ printf ("(press Ctrl-C to quit, or wait 5 seconds\n");
+ g_timeout_add (5000, g_main_loop_quit, main_loop);
+#endif
+ }
+ }
+}
+
+static gboolean
+parse_idle (gpointer data)
+{
+ PageInfo *page_info = data;
+
+ if (page_info->first_idle == -1.0)
+ page_info->first_idle = g_timer_elapsed (page_info->timer, NULL);
+
+ if (page_info->unparsed->len > 0)
+ {
+ page_info->n_parser_calls++;
+#if 0
+ g_print ("%f: push data (%d bytes)\n",
+ g_timer_elapsed (total, NULL), page_info->unparsed->len);
+#endif
+ if (page_info->try_parse)
+ html_parser_push_data (
+ page_info->parser, page_info->unparsed->str, page_info->unparsed->len);
+ g_string_truncate (page_info->unparsed, 0);
+ }
+
+ if (page_info->eof)
+ {
+ if (page_info->parser)
+ {
+ g_print ("%f: push eof\n",
+ g_timer_elapsed (total, NULL));
+ html_parser_push_eof (page_info->parser);
+ }
+ page_info->parser_eof = g_timer_elapsed (page_info->timer, NULL);
+ page_info->done = TRUE;
+ }
+
+ page_info->idle_id = 0;
+ maybe_quit (page_info);
+
+ return FALSE;
+}
+
+static void
+get_image (PageInfo *page_info, gchar *image_uri_str)
+{
+ if (do_download (page_info->base_uri, image_uri_str, FALSE))
+ ++page_info->n_images;
+}
+
+static void
+handle_img_element (PageInfo *page_info, const HtmlParserBeginElementEvent *event)
+{
+ int i;
+
+ if (page_info->first_image_tag == -1.0)
+ {
+ page_info->first_image_tag =
+ g_timer_elapsed (page_info->timer, NULL);
+ }
+
+ for (i = 0; i < event->attributes->len; ++i)
+ {
+ HtmlAttribute *attr =
+ event->attributes->pdata[i];
+
+ if (g_ascii_strcasecmp (attr->name, "src") == 0)
+ {
+ if (attr->content)
+ get_image (page_info, g_strdup (attr->content));
+ }
+ }
+}
+
+static void
+handle_link_element (PageInfo *page_info, const HtmlParserBeginElementEvent *event)
+{
+ int i;
+ gchar *uri = NULL;
+
+ for (i = 0; i < event->attributes->len; ++i)
+ {
+ HtmlAttribute *attr = event->attributes->pdata[i];
+
+ if (g_ascii_strcasecmp (attr->name, "href") == 0)
+ {
+ uri = g_strdup (attr->content);
+ break;
+ }
+ }
+
+ if (uri)
+ {
+ if (do_download (page_info->base_uri, uri, FALSE))
+ page_info->n_links++;
+ }
+}
+
+static void
+handle_base_element (PageInfo *page_info, const HtmlParserBeginElementEvent *event)
+{
+ int i;
+
+ gchar *uri = NULL;
+
+ for (i = 0; i < event->attributes->len; ++i)
+ {
+ HtmlAttribute *attr = event->attributes->pdata[i];
+
+ if (g_ascii_strcasecmp (attr->name, "href") == 0)
+ {
+ uri = g_strdup (attr->content);
+ break;
+ }
+ }
+
+ if (uri)
+ {
+ LacUri *new_base = lac_uri_new_from_str (page_info->base_uri, uri);
+ if (new_base)
+ {
+ printf ("new base: %s\n", lac_uri_string (new_base));
+ page_info->base_uri = new_base;
+ }
+ }
+}
+
+static void
+handle_frame_element (PageInfo *page_info, const HtmlParserBeginElementEvent *event)
+{
+ int i;
+
+ gchar *uri = NULL;
+
+ for (i = 0; i < event->attributes->len; ++i)
+ {
+ HtmlAttribute *attr = event->attributes->pdata[i];
+
+ if (g_ascii_strcasecmp (attr->name, "src") == 0)
+ {
+ uri = g_strdup (attr->content);
+ break;
+ }
+ }
+
+ if (uri)
+ {
+ do_download (page_info->base_uri, uri, TRUE);
+ }
+}
+
+
+static void
+handle_meta_element (PageInfo *page_info, const HtmlParserBeginElementEvent *event)
+{
+ int i;
+
+ gchar *uri = NULL;
+ gboolean is_refresh = FALSE;
+
+ for (i = 0; i < event->attributes->len; ++i)
+ {
+ HtmlAttribute *attr = event->attributes->pdata[i];
+
+ if (g_ascii_strcasecmp (attr->name, "http-equiv") == 0 &&
+ g_ascii_strcasecmp (attr->content, "refresh") == 0)
+ {
+ is_refresh = TRUE;
+ break;
+ }
+ }
+
+ if (!is_refresh)
+ return;
+
+ for (i = 0; i < event->attributes->len; ++i)
+ {
+ HtmlAttribute *attr = event->attributes->pdata[i];
+
+ if (g_ascii_strcasecmp (attr->name, "content") == 0)
+ {
+ char *lower_case = g_ascii_strdown (attr->content, -1);
+ const char *pos = strstr (lower_case, ";url=");
+
+ if (pos)
+ {
+ uri = g_strdup (attr->content + (pos - lower_case) + 5);
+ }
+
+ g_free (lower_case);
+ break;
+ }
+ }
+
+ if (uri)
+ {
+ do_download (page_info->base_uri, uri, TRUE);
+ }
+}
+
+static void
+parser_callback (HtmlParser *parser, const HtmlParserEvent *event)
+{
+ PageInfo *page_info = html_parser_get_data (parser);
+ if (page_info->first_parser_callback == -1.0)
+ page_info->first_parser_callback = g_timer_elapsed (page_info->timer, NULL);
+
+ switch (event->type)
+ {
+ case HTML_PARSER_BEGIN_ELEMENT:
+#if 0
+ g_print ("%f: begin %s\n",
+ g_timer_elapsed (total, NULL), event->begin_element.name);
+#endif
+ if (g_ascii_strcasecmp (event->begin_element.name, "img") == 0)
+ {
+ handle_img_element (page_info, &(event->begin_element));
+ }
+ else if (g_ascii_strcasecmp (event->begin_element.name, "link") == 0)
+ {
+ handle_link_element (page_info, &(event->begin_element));
+ }
+ else if (g_ascii_strcasecmp (event->begin_element.name, "frame") == 0)
+ {
+ handle_frame_element (page_info, &(event->begin_element));
+ }
+ else if (g_ascii_strcasecmp (event->begin_element.name, "base") == 0)
+ {
+ handle_base_element (page_info, &(event->begin_element));
+ }
+ else if (g_ascii_strcasecmp (event->begin_element.name, "meta") == 0)
+ {
+ handle_meta_element (page_info, &(event->begin_element));
+ }
+ break;
+
+ case HTML_PARSER_END_ELEMENT:
+#if 0
+ g_print ("%f: end %s\n",
+ g_timer_elapsed (total, NULL), event->end_element.name);
+#endif
+ break;
+
+ case HTML_PARSER_COMMENT:
+#if 0
+ g_print ("%f: comment\n", g_timer_elapsed (total, NULL));
+#endif
+#if 0
+ g_print ("%f: comment: %s\n",
+ g_timer_elapsed (total, NULL), event->comment.text);
+#endif
+ break;
+ case HTML_PARSER_END_DOCUMENT:
+ g_print ("END DOCUMENT REPORTED BY PARSER\n");
+ break;
+ }
+}
+
+static void
+queue_parse (PageInfo *info)
+{
+ if (!info->idle_id)
+ info->idle_id = g_idle_add (parse_idle, info);
+}
+
+static void
+http_callback (LacHttpRequest *request, const LacHttpEvent *event)
+{
+ PageInfo *page_info = lac_http_request_get_data (request);
+
+ switch (event->type)
+ {
+ case LAC_HTTP_EVENT_HOST_FOUND:
+ g_print ("%s: dns lookup complete at %f\n", page_info->main_uri,
+ g_timer_elapsed (total, NULL));
+ break;
+
+ case LAC_HTTP_EVENT_SENT:
+ page_info->first_connect = g_timer_elapsed (page_info->timer, NULL);
+ g_print ("%s: sent \n", page_info->main_uri);
+ break;
+
+ case LAC_HTTP_EVENT_CONNECTING:
+ break;
+
+ case LAC_HTTP_EVENT_STATUS_LINE:
+ g_print ("%s: status line: HTTP/%d.%d %d %s\n",
+ truncat (page_info->main_uri),
+ event->status_line.major,
+ event->status_line.minor,
+ event->status_line.status_code,
+ event->status_line.reason_phrase);
+ if (event->status_line.status_code == 302 ||
+ event->status_line.status_code == 301)
+ {
+ g_print ("IS REDIRECT!\n");
+ page_info->is_redirect = TRUE;
+ }
+ break;
+
+ case LAC_HTTP_EVENT_NO_STATUS_LINE:
+ g_print ("%s: no status line (HTTP/0.9 response)\n",
+ truncat (page_info->main_uri));
+ break;
+
+ case LAC_HTTP_EVENT_HEADER:
+ g_print ("%s: header (%s: %s)\n", page_info->main_uri, event->header.header, event->header.value);
+ if (page_info->is_redirect && g_ascii_strcasecmp (event->header.header, "Location") == 0)
+ {
+ do_download (page_info->base_uri, event->header.value, page_info->try_parse);
+ }
+ break;
+
+ case LAC_HTTP_EVENT_BEGIN_CONTENT:
+#if 0
+ g_print ("%s: begin content (length %d)\n", page_info->main_uri, event->begin_content.length);
+#endif
+ break;
+
+ case LAC_HTTP_EVENT_CONTENT:
+ g_print ("%s: content chunk (size: %d)\n", page_info->main_uri, event->content.length);
+#if 0
+ {
+ int i;
+ for (i = 0; i < event->content.length; ++i)
+ printf ("%c", event->content.data[i]);
+ }
+#endif
+ g_string_append_len (page_info->unparsed, event->content.data, event->content.length);
+ if (page_info->first_content == -1.0)
+ page_info->first_content = g_timer_elapsed (page_info->timer, NULL);
+
+ queue_parse (page_info);
+#if 0
+ parse_idle (page_info);
+#endif
+ page_info->n_content_chunks++;
+ break;
+
+ case LAC_HTTP_EVENT_END_CONTENT:
+#if 0
+ printf ("%s: end_content (total: %d)\n", page_info->main_uri, event->end_content.total);
+#endif
+ g_print ("%s: DONE (at total: %f, this page: %f\n",
+ truncat (page_info->main_uri),
+ g_timer_elapsed (total, NULL),
+ g_timer_elapsed (page_info->timer, NULL));
+ page_info->eof = TRUE;
+ queue_parse (page_info);
+
+#if 0
+ parse_idle (page_info);
+#endif
+ break;
+
+ case LAC_HTTP_EVENT_ERROR:
+ printf ("%s: error (%s)\n", truncat (page_info->main_uri), event->error.err->message);
+ page_info->eof = TRUE;
+ queue_parse (page_info);
+ break;
+
+ default:
+ g_warning ("%s: UNKNOWN (%d)\n", truncat (page_info->main_uri), event->type);
+ break;
+ }
+}
+
+static gboolean
+already_downloaded (const LacUri *uri)
+{
+ static GPtrArray *already;
+ int i;
+
+ if (!already)
+ already = g_ptr_array_new ();
+
+ for (i = 0; i < already->len; ++i)
+ {
+ if (lac_uri_equal (already->pdata[i], uri))
+ return TRUE;
+ }
+
+ g_ptr_array_add (already, lac_uri_copy (uri));
+ return FALSE;
+}
+
+static gboolean
+do_download (LacUri *base_uri, const gchar *uri_str, gboolean try_parse)
+{
+ LacHttpRequest *request;
+ PageInfo *page_info = g_new (PageInfo, 1);
+ LacUri *uri;
+ page_info->timer = g_timer_new ();
+ page_info->try_parse = try_parse;
+
+#if 0
+ printf ("uri: %s\n", uri_str);
+#endif
+
+ if (page_info->try_parse)
+ g_print ("DOWNLAOD TRUE %s ********\n", uri_str);
+
+ uri = lac_uri_new_from_str (base_uri, uri_str);
+ if (!uri)
+ {
+ printf ("bad uri: %s\n", uri_str);
+ return FALSE ;
+ }
+ else if (uri->scheme != LAC_SCHEME_HTTP)
+ {
+ printf ("not an http uri: %s\n", uri_str);
+ return FALSE;
+ }
+ if (already_downloaded (uri))
+ return FALSE;
+
+#if 0
+ printf ("download: %s\n", uri_str);
+#endif
+
+ request = lac_http_request_new_get (
+ uri, http_callback, page_info);
+
+ page_info->main_uri = g_strdup (uri_str);
+ page_info->base_uri = uri;
+ if (page_info->try_parse)
+ page_info->parser = html_parser_new (parser_callback, page_info);
+ else
+ page_info->parser = NULL;
+ page_info->n_remaining_images = 0;
+ page_info->n_images = 0;
+ page_info->n_links = 0;
+ page_info->done = FALSE;
+ page_info->idle_id = 0;
+ page_info->eof = FALSE;
+ page_info->unparsed = g_string_new ("");
+ page_info->first_connect = -1.0;
+ page_info->first_content = -1.0;
+ page_info->first_image_tag = -1.0;
+ page_info->first_idle = -1.0;
+ page_info->first_parser_callback = -1.0;
+ page_info->parser_eof = -1.0;
+ page_info->n_content_chunks = 0;
+ page_info->n_parser_calls = 0;
+ page_info->is_redirect = FALSE;
+
+ g_ptr_array_add (outstanding_page_infos, page_info);
+
+#if 0
+ printf ("length: %d\n", outstanding_page_infos->len);
+#endif
+
+ g_print ("dispatched %s at %f\n", page_info->main_uri, g_timer_elapsed (total, NULL));
+ lac_http_request_dispatch (request);
+ return TRUE;
+}
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+
+ g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_ERROR |
+ G_LOG_LEVEL_CRITICAL);
+
+
+ lac_set_verbose (TRUE);
+
+ outstanding_page_infos = g_ptr_array_new ();
+ total = g_timer_new ();
+ if (argc > 1)
+ {
+ for (i = 1; i < argc; ++i)
+ do_download (NULL, argv[i], TRUE);
+ }
+ else
+ {
+ printf ("usage %s <uris>\n", argv[0]);
+ return 1;
+ }
+
+ main_loop = g_main_loop_new (NULL, TRUE);
+#if 0
+ g_timeout_add (5000, (GSourceFunc) print_outstanding, NULL);
+ g_timeout_add (38000, (GSourceFunc) g_main_loop_quit, main_loop);
+#endif
+ g_print ("dispatched requests\n");
+ g_assert (main_loop);
+ if (outstanding_page_infos->len > 0)
+ g_main_loop_run (main_loop);
+
+ return g_timer_elapsed (total, NULL) * 10000;
+}
diff --git a/tests/newdns-test.c b/tests/newdns-test.c
new file mode 100644
index 0000000..db02abe
--- /dev/null
+++ b/tests/newdns-test.c
@@ -0,0 +1,117 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- */
+
+/* Lac - Library for asynchronous communication
+ * Copyright (C) 2002 Søren Sandmann (sandmann@daimi.au.dk)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <lac.h>
+#include <string.h>
+
+static int n_outstanding;
+static GMainLoop *main_loop;
+
+static void
+name_callback (const gchar *name, gpointer data, const GError *err)
+{
+ gchar *addr_str = data;
+
+ if (err)
+ {
+ g_print ("reverse %s: %s\n", addr_str, err->message);
+ }
+ else
+ {
+ g_print ("reverse %s: %s\n", addr_str, name);
+ }
+ g_free (addr_str);
+}
+
+static void
+callback (const GPtrArray *addresses, gpointer data, const GError *err)
+{
+ gchar *name = data;
+
+ if (err)
+ {
+ g_print ("%s: %s\n", name, err->message);
+ }
+ else
+ {
+ int i;
+
+ if (addresses->len == 0)
+ g_print ("this should not happen\n");
+ for (i = 0; i < addresses->len; ++i)
+ {
+ gchar *addr = lac_address_to_str (addresses->pdata[i]);
+ g_print ("%s: %s\n", name, addr);
+
+ lac_dns_get_name (addresses->pdata[i], name_callback, addr);
+ }
+
+ }
+
+ if (!strstr (name, "again"))
+ {
+ gchar *tmp;
+
+ n_outstanding += 2;
+ lac_dns_get_addresses (name, callback, g_strdup_printf ("%s again", name));
+
+ tmp = g_ascii_strup (name, -1);
+ lac_dns_get_addresses (tmp, callback, g_strdup_printf ("%s (UPPER) again", name));
+ g_free (tmp);
+ }
+
+ if (--n_outstanding == 0)
+ g_main_quit (main_loop);
+ g_free (name);
+}
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+
+ main_loop = g_main_loop_new (NULL, TRUE);
+ g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_ERROR |
+ G_LOG_LEVEL_CRITICAL);
+
+ lac_set_verbose (TRUE);
+
+ if (argc > 1)
+ {
+ for (i = 1; i < argc; ++i)
+ {
+ ++n_outstanding;
+ lac_dns_get_addresses (argv[i], callback, g_strdup (argv[i]));
+ }
+ }
+ else
+ {
+ g_print ("usage %s <names>\n", argv[0]);
+ return 1;
+ }
+
+ g_assert (main_loop);
+#if 0
+ g_timeout_add (200, g_main_loop_quit, main_loop);
+#endif
+ g_main_loop_run (main_loop);
+
+ return 0;
+}
diff --git a/tests/rdns-test-async.c b/tests/rdns-test-async.c
new file mode 100644
index 0000000..a16151b
--- /dev/null
+++ b/tests/rdns-test-async.c
@@ -0,0 +1,78 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- */
+
+/* Lac - Library for asynchronous communication
+ * Copyright (C) 2002 Søren Sandmann (sandmann@daimi.au.dk)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <lac.h>
+
+static void
+rcallback (const gchar *name, gpointer data, const GError *err)
+{
+ gchar *lookup_name = data;
+
+ if (err)
+ {
+ g_print ("%s: (error %s)\n", lookup_name, err->message);
+ }
+ else
+ {
+ g_print ("%s: %s\n", lookup_name, name);
+ }
+}
+
+static void
+callback (const LacAddress *addr, gpointer data, const GError *err)
+{
+ gchar *name = data;
+
+ if (err)
+ {
+ g_print ("%s: error: %s\n", name, err->message);
+ }
+ else
+ {
+ g_print ("%s: %s\n", name, lac_address_to_string (addr));
+ lac_address_lookup_name (addr, rcallback, name);
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+ GMainLoop *main_loop;
+
+ lac_set_verbose (TRUE);
+
+ if (argc > 1)
+ {
+ for (i = 1; i < argc; ++i)
+ lac_address_new_lookup_from_name (argv[i], callback, argv[i]);
+ }
+ else
+ {
+ g_print ("usage %s <names>\n", argv[0]);
+ return 1;
+ }
+
+ main_loop = g_main_loop_new (NULL, TRUE);
+ g_assert (main_loop);
+ g_main_loop_run (main_loop);
+
+ return 0;
+}
diff --git a/tests/rdns-test.c b/tests/rdns-test.c
new file mode 100644
index 0000000..b5fa0be
--- /dev/null
+++ b/tests/rdns-test.c
@@ -0,0 +1,56 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- */
+
+/* Lac - Library for asynchronous communication
+ * Copyright (C) 2002 Søren Sandmann (sandmann@daimi.au.dk)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <lac.h>
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+ LacAddress *addr;
+
+ lac_verbose = TRUE;
+
+ if (argc > 1)
+ {
+ for (i = 1; i < argc; ++i)
+ {
+ GError *err = NULL;
+ addr = lac_gethostbyname (argv[i], &err);
+
+ if (!addr)
+ {
+ g_print ("%s: error (%s)\n", argv[i], err->message);
+ g_error_free (err);
+ }
+ else
+ {
+ g_print ("%s: %s\n", argv[i], lac_address_to_str (addr));
+ lac_address_unref (addr);
+ }
+ }
+ return 0;
+ }
+ else
+ {
+ g_print ("usage %s <names>\n", argv[0]);
+ return 1;
+ }
+}
diff --git a/tests/simple-test.c b/tests/simple-test.c
new file mode 100644
index 0000000..6f1189f
--- /dev/null
+++ b/tests/simple-test.c
@@ -0,0 +1,59 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- */
+
+/* Lac - Library for asynchronous communication
+ * Copyright (C) 2002 Søren Sandmann (sandmann@daimi.au.dk)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "lac.h"
+#include <string.h>
+
+GMainLoop *main_loop;
+
+static void
+callback (const LacAddress *addr, gpointer data, const GError *err)
+{
+ if (addr)
+ {
+ GError *err2 = NULL;
+ int fd = lac_socket_tcp (NULL);
+ if (!lac_connect (fd, addr, 80, &err2))
+ {
+ g_print ("huh: %s\n", err->message);
+ }
+ else
+ g_print ("ok\n");
+
+ addr = lac_address_new_from_a_b_c_d (130, 225, 18, 72);
+
+ g_print (
+ "This should be 130.225.18.72 -> %s\n", lac_address_to_string (addr));
+ }
+ else
+ {
+ g_print ("error: %s\n", err->message);
+ }
+ g_main_quit (main_loop);
+}
+
+int
+main (int argc, char *argv[])
+{
+ lac_address_new_lookup_from_name ("slashdot.org", callback, NULL);
+
+ g_main_loop_run (main_loop);
+ return 0;
+}
diff --git a/tests/trouble-sites.sh b/tests/trouble-sites.sh
new file mode 100755
index 0000000..b87c859
--- /dev/null
+++ b/tests/trouble-sites.sh
@@ -0,0 +1,8 @@
+echo ==================================== www.ssp.dk
+lacwget http://www.ssp.dk/
+echo ==================================== www.adobe.com
+lacwget http://www.adobe.com
+echo ==================================== www.bold.dk
+lacwget http://www.bold.dk
+echo ==================================== www.sandra-bullock.org
+lacwget http://www.sandra-bullock.org
diff --git a/tests/udp-test.c b/tests/udp-test.c
new file mode 100644
index 0000000..d91254d
--- /dev/null
+++ b/tests/udp-test.c
@@ -0,0 +1,88 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- */
+
+/* Lac - Library for asynchronous communication
+ * Copyright (C) 2002 Søren Sandmann (sandmann@daimi.au.dk)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <lac.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+ GMainLoop *main_loop;
+ gchar buffer[5000];
+
+ LacAddress *addr;
+ GError *err = NULL;
+ int fd;
+
+ addr = lac_address_new_from_localhost_wait (NULL, NULL);
+ if (!addr)
+ {
+ g_print ("can't find local IP address \n");
+ }
+ else
+ {
+ char *str = lac_address_to_string (addr);
+ g_print ("local IP address is: %s\n", str);
+ g_free (str);
+ }
+
+ addr = lac_address_new_from_a_b_c_d (130, 225, 18, 72);
+ fd = lac_socket_udp (NULL);
+ if (!lac_connect (fd, addr, 53, &err))
+ {
+ g_print ("connect: %s\n", err->message);
+ exit (1);
+ }
+ else
+ g_print ("connect ok (to %s)\n", lac_address_to_string (addr));
+
+#define MSG "asd jkl;faqpwoe8rusjldklsdf jklajks ls jkf ljkasdf jlsdfsdfa j"
+
+ i = lac_send (fd, MSG, strlen (MSG), &err);
+ if (err)
+ {
+ g_print ("send: %s\n", err->message);
+ exit (1);
+ }
+ g_print ("sent %d\n", i);
+
+ i = lac_recv (fd, buffer, sizeof (buffer), &err);
+ if (err)
+ {
+ g_print ("recv: %s\n", err->message);
+ exit (1);
+ }
+ else
+ {
+ if (i == 0)
+ g_print ("i == 0\n");
+ else
+ while (i > 0)
+ printf ("%c", buffer[i--]);
+ g_print ("\n");
+ }
+
+ lac_close (fd, &err);
+
+ return 0;
+}
diff --git a/tests/uri-test.c b/tests/uri-test.c
new file mode 100644
index 0000000..4285013
--- /dev/null
+++ b/tests/uri-test.c
@@ -0,0 +1,254 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- */
+
+/* Lac - Library for asynchronous communication
+ * Copyright (C) 2000 Søren Sandmann (sandmann@daimi.au.dk)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "lac.h"
+
+static void
+print_uri (LacUri *uri, gchar *base_uri_str, gchar *uri_str)
+{
+ g_print ("-----------------------------------------\n");
+ if (base_uri_str)
+ g_print ("base uri: %s\n", base_uri_str);
+ g_print ("uri: %s\n", uri_str);
+ g_print ("\n");
+
+ switch (uri->scheme)
+ {
+ case LAC_SCHEME_UNKNOWN:
+ g_print ("UNKNOWN\n");
+ g_print (" scheme: %s\n", uri->u.unknown.scheme);
+ g_print (" authority: %s\n", uri->u.unknown.authority);
+ g_print (" path: %s\n", uri->u.unknown.path);
+ g_print (" query: %s\n", uri->u.unknown.query);
+ g_print (" fragment: %s\n", uri->fragment);
+ break;
+ case LAC_SCHEME_HTTP:
+ g_print ("HTTP\n");
+ g_print (" host: %s\n", uri->u.http.host);
+ g_print (" port: %d\n", uri->u.http.port);
+ g_print (" path: %s\n", uri->u.http.path);
+ g_print (" query: %s\n", uri->u.http.query);
+ g_print (" fragment: %s\n", uri->fragment);
+ break;
+ case LAC_SCHEME_FTP:
+ g_print ("FTP\n");
+ g_print (" host: %s\n", uri->u.ftp.host);
+ g_print (" username: %s\n", uri->u.ftp.username);
+ g_print (" password: %s\n", uri->u.ftp.password);
+ g_print (" port: %d\n", uri->u.ftp.port);
+ g_print (" path: %s\n", uri->u.ftp.path);
+ g_print (" type: ");
+ switch (uri->u.ftp.type)
+ {
+ case LAC_FTP_TYPE_A:
+ g_print ("a\n");
+ break;
+ case LAC_FTP_TYPE_I:
+ g_print ("i\n");
+ break;
+ case LAC_FTP_TYPE_D:
+ g_print ("d\n");
+ break;
+ case LAC_FTP_TYPE_NONE:
+ g_print ("none\n");
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+ g_print (" fragment %s\n", uri->fragment);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+int
+main ()
+{
+ LacUri *uri;
+ LacUri *base_uri;
+ gchar *uri_str;
+ gchar *base_uri_str;
+
+ uri_str = "//www.daimi.au.dk/baz.html?asdf#//qwer";
+ base_uri_str = NULL;
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ uri_str = "http:baz::?####";
+ base_uri_str = NULL;
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ uri_str = "/index.html#interesting";
+ base_uri_str = NULL;
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ uri_str = "//www:80/index.html#interesting";
+ base_uri_str = NULL;
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ uri_str = "#//www:80/index.html#interesting";
+ base_uri_str = NULL;
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ uri_str = ":/#//www:80/index.html#interesting";
+ base_uri_str = NULL;
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ uri_str = "mailto:sandmann@daimi.au.dk:80";
+ base_uri_str = NULL;
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ uri_str = "http://www.daimi.au.dk:1324786912387461234/baz.html";
+ base_uri_str = NULL;
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ uri_str = "http://www.daimi.au.dk:8080/baz.html?asdf#//qwer";
+ base_uri_str = NULL;
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ uri_str = "HtTp://www:-1/baz.html?asdf#asdff";
+ base_uri_str = NULL;
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ uri_str = "HtTp://wWWWWWWWWw.baz:::::as:lkj1/baz.html?asdf#asdff";
+ base_uri_str = NULL;
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ uri_str = "";
+ base_uri_str = NULL;
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ uri_str = "http:#?";
+ base_uri_str = NULL;
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ uri_str = "http://sandmann:baz@www.daimi.au.dk/index.html";
+ base_uri_str = NULL;
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ uri_str = "ftp://ftp.daimi.au.dk/~biasdf";
+ base_uri_str = NULL;
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ uri_str = "ftp://sandmann:asdf@ftp.daimi.au.dk/~biasdf";
+ base_uri_str = NULL;
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ uri_str = "ftp://:asdf@ftp.daimi.au.dk/~biasdf";
+ base_uri_str = NULL;
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ uri_str = "ftp://foo:bar@ftp.daimi.au.dk/~biasdf";
+ base_uri_str = NULL;
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ uri_str = "ftp://foo:bar@ftp.com/~biasdf;type=d";
+ base_uri_str = NULL;
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ uri_str = "ftp://foo:bar@ftp.com/~biasdf;type=x";
+ base_uri_str = NULL;
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ uri_str = "file://foo:bar@ftp.com/~biasdf;type=x";
+ base_uri_str = NULL;
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ uri_str = "file:///users/sandmann/public_html/index.html";
+ base_uri_str = NULL;
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ uri_str = "ftp:///users/sandmann/public_html/index.html";
+ base_uri_str = NULL;
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ uri_str = "/users/sandman/public_html/index.html";
+ base_uri_str = NULL;
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ uri_str = "//images.slashdot.org/topics/topictech2.gif";
+ base_uri_str = NULL;
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ uri_str = "../images/euroheader.gif";
+ base_uri_str = NULL;
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ uri_str = "Http:.................";
+ base_uri_str = NULL;
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ base_uri_str = "http://www.europa.com/";
+ base_uri = lac_uri_new_from_str (NULL, base_uri_str);
+ uri_str = "../images/euroheader.gif";
+ uri = lac_uri_new_from_str (base_uri, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ base_uri_str = NULL;
+ uri_str = "ftp://birnan:emfle@birnan.com:345/images/euroheader.gif";
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ base_uri_str = NULL;
+ uri_str = "//../birnan.html";
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ base_uri_str = NULL;
+ uri_str = "///../birnan.html";
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ base_uri_str = NULL;
+ uri_str = "../birnan.html";
+ uri = lac_uri_new_from_str (NULL, uri_str);
+ print_uri (uri, base_uri_str, uri_str);
+
+ return 0;
+}
diff --git a/tests/watch-test.c b/tests/watch-test.c
new file mode 100644
index 0000000..91ccf42
--- /dev/null
+++ b/tests/watch-test.c
@@ -0,0 +1,108 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- */
+
+/* Lac - Library for asynchronous communication
+ * Copyright (C) 2002 Søren Sandmann (sandmann@daimi.au.dk)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <lac.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+
+GMainLoop *main_loop;
+
+static void
+do_write (gint fd)
+{
+ g_print ("write %d\n", fd);
+#if 0
+#define MSG "GET / HTTP/1.1\r\nhost: www.daimi.au.dk\r\n\r\n"
+#endif
+#define MSG "GET /\r\n\r\n"
+ lac_send (fd, MSG, strlen (MSG), NULL);
+ lac_fd_set_write_callback (fd, NULL);
+}
+
+static void
+do_read (gint fd)
+{
+ gchar buf [8192];
+ gint len;
+ gint i;
+
+ len = lac_recv (fd, buf, sizeof (buf), NULL);
+
+ if (len == 0)
+ {
+ g_print ("hangup in read()\n");
+ lac_fd_remove_watch (fd);
+ g_main_quit (main_loop);
+ }
+ else if (len > 0)
+ {
+ for (i = 0; i < len; ++i)
+ printf ("%c", buf[i]);
+ }
+ else if (len < 0)
+ {
+ g_print ("error: %s\n", g_strerror (errno));
+ }
+
+ lac_fd_remove_watch (fd);
+ lac_close (fd, NULL);
+}
+
+static void
+do_hangup (gint fd)
+{
+ g_print ("Abortive close (whatever that means for a TCP connection).\n");
+ lac_fd_remove_watch (fd);
+ g_main_quit (main_loop);
+}
+
+int
+main (int argc, char *argv[])
+{
+#if 0
+ int i;
+#endif
+
+ LacAddress *addr;
+ GError *err = NULL;
+ int fd;
+
+ addr = lac_address_new_from_name_wait ("www.daimi.au.dk.", NULL, NULL);
+ g_print ("address is: %s\n", lac_address_to_string (addr));
+ fd = lac_socket_tcp (NULL);
+ if (!lac_connect (fd, addr, 80, &err))
+ {
+ g_print ("huh: %s\n", err->message);
+ }
+ else
+ g_print ("ok\n");
+
+ lac_fd_add_watch (fd, GINT_TO_POINTER (fd));
+ lac_fd_set_write_callback (fd, do_write);
+ lac_fd_set_read_callback (fd, do_read);
+ lac_fd_set_hangup_callback (fd, do_hangup);
+ lac_fd_set_error_callback (fd, do_read);
+
+ main_loop = g_main_loop_new (NULL, TRUE);
+ g_main_loop_run (main_loop);
+
+ return 0;
+}