GNetwork Library

1. OVERVIEW:
================================================================================
GNetwork is a networking wrapper written in pure C against the Glib/GObject
object framework.

Requires:
  GLib 2.3+ with thread support
  GConf 2.0
Optional SSL support:
  GNUTLS 0.7 (recommended) or OpenSSL 0.9.6.

The intention here is to provide a useful and easy-to-develop-against sockets
wrapper for GNOME2 & GTK+ 2.0 programs which require TCP/IP connection
capabilities. It can be used by programs which do not use GNOME or GTK+ anyways,
however. It is NOT recommended or intended for high-load server situations,
just user applications which need TCP/IP networking. Proxies are supported
completely transparently, using the same settings as gnome-vfs.


2. BUGS:
================================================================================
Bugs can be reported at http://bugzilla.gnome.org/, against the libgnetwork
module: http://bugzilla.gnome.org/enter_bug.cgi?product=libgnetwork


3. OBJECTS:
================================================================================
GNetwork provides the following interfaces and interfaces:

	GNetworkConnection
	+- GNetworkSslConnection
	|  +- GNetworkTcpConnection
	+- GNetworkUnixConnection
	+- GNetworkUdpConnection
	GNetworkServer
	+- GNetworkTcpServer
	+- GNetworkUdpServer
	+- GNetworkUnixServer

These are either GObjects or GInterfaces.

3.1 GNetworkConnection:
-----------------------
The GNetworkConnection interface is an interface which wraps the standard system
methods for handling outgoing socket connections.

3.1.1 GNetworkSslConnection:
-----------------------
The GNetworkSslConnection interface is a an add-on interface to
GNetworkConnection for objects which want a standard means to access optional
SSL support.

3.1.1.1 GNetworkTcpConnection:
----------------------------
The GNetworkTcpConnection object implements the GNetworkConnection interface
for standard TCP/IP sockets, and the GNetworkSslConnection interface to access
optional SSL support.

3.1.2 GNetworkUdpConnection:
----------------------------
The GNetworkUdpConnection object implements the GNetworkConnection interface
for UDP (connection-less) sockets (not implemented yet).

3.1.3 GNetworkUnixConnection:
----------------------------
The GNetworkUnixConnection object implements the GNetworkConnection interface
for standard UNIX domain sockets (not implemented yet).

3.2 GNetworkServer:
-------------------
The GNetworkServer interface is a interface which wraps the standard system
methods for handling incoming socket connections. Implementations must create
GNetworkConnection objects as needed to handle incoming connections.

3.2.1 GNetworkTcpServer:
------------------------
The GNetworkTcpServer object is an implementation of the GNetworkServer
interface for standard TCP/IP sockets, including optional SSL support.

3.2.2 GNetworkUdpConnection:
----------------------------
The GNetworkUdpConnection object implements the GNetworkConnection interface
for UDP (connection-less) sockets (not implemented yet).

3.2.3 GNetworkUnixConnection:
----------------------------
The GNetworkUnixConnection object implements the GNetworkConnection interface
for standard UNIX domain sockets (not implemented yet).





4. Simple Examples:
================================================================================

4.1 GNetworkTcpConnection:
--------------------------
Example connecting to port 80 of localhost without SSL:

  #define HOST "localhost"

  /* A GFunc to be added with g_idle_add, that is, the GMainLoop should've
     already been started by the time this function is called. */
  gboolean
  do_tcp_connection (gpointer data)
  {
    GObject *connection;

    connection = gnetwork_tcp_connection_new (HOST, 80, GNETWORK_TCP_PROXY_HTTP,
                                              FALSE);
    g_signal_connect (connection, "notify::tcp-status", status_cb, NULL);
    g_signal_connect (connection, "error", error_cb, NULL);
    g_signal_connect (connection, "received", recv_cb, NULL);
    g_signal_connect (connection, "sent", sent_cb, NULL);
    gnetwork_connection_open (GTCP_CONNECTION (connection));

    return FALSE;
  }

  void
  status_cb (GObject *connection, GParamSpec *pspec, gpointer user_data)
  {
    GNetworkTcpConnectionStatus status;
    gchar *str;

    status = gnetwork_tcp_connection_get_tcp_status (GNETWORK_TCP_CONNECTION
						     (connection));

    switch (status)
    {
    case GNETWORK_TCP_CONNECTION_CLOSING:
      g_message ("Closing connection.");
      break;
    case GNETWORK_TCP_CONNECTION_CLOSED:
      g_message ("Connection closed.");
      break;
    case GNETWORK_TCP_CONNECTION_LOOKUP:
      g_message ("Looking up host: %s.", HOST);
      break;
    case GNETWORK_TCP_CONNECTION_OPENING:
      g_message ("Contacting host");
      break;
    case GNETWORK_TCP_CONNECTION_PROXYING:
      str = gnetwork_tcp_proxy_get_host (GNETWORK_TCP_PROXY_HTTP);
      g_message ("Traversing proxy: %s.", str);
      g_free (str);
      break;
    case GNETWORK_TCP_CONNECTION_AUTHENTICATING:
      /* We're not using SSL */
      break;
    case GNETWORK_TCP_CONNECTION_OPEN:
      g_message ("The connection with %s is open.", HOST);
      gnetwork_connection_send (GNETWORK_CONNECTION (connection),
                                "HTTP/1.1\r\nGET /index.html\r\n\r\n", -1);
      break;

    default:
      g_assert_not_reached ();
      break;
    }
  }

  void
  recv_cb (GNetworkConnection *connection, gconstpointer data, gulong length,
	   gpointer user_data)
  {
    g_message ("Recieved Data: '%s'", (gchar *) data);
  }

  void
  send_cb (GNetworkConnection *connection, gconstpointer data, gulong length,
	   gpointer user_data)
  {
    g_message ("Sent Data: '%s'", (gchar *) data);
  }

  void
  error_cb (GNetworkConnection *connection, GError *error, gpointer user_data)
  {
    switch (error->domain)
    {
    case G_IO_CHANNEL_ERROR:
      g_print ("IO Error: ");
      break;
    case GNETWORK_CONNECTION_ERROR:
      g_print ("Connection Error: ");
      break;
    case GNETWORK_TCP_PROXY_ERROR:
      g_print ("Proxy Error: ");
      break;
    case GNETWORK_SSL_ERROR:
    case GNETWORK_SSL_CERT_ERROR:
      /* We're not using SSL */
      return;
      break;

    default:
      g_assert_not_reached ();
      break;
    }

    g_print ("%s\n", error->message);
  }

