summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann <sandmann@redhat.com>2007-07-30 22:23:13 -0400
committerSøren Sandmann <sandmann@redhat.com>2007-07-30 22:23:13 -0400
commit5e42cfed15542f68153a279b9dac2dfc6153888d (patch)
treedbee0aec9e835be3a5540091f770a79cfab1613e
parent09e6dd2aacd7f7485c1edae78058d6f1bc2cefd2 (diff)
Various stuff
-rwxr-xr-xTODO12
-rw-r--r--src/lachttp.c11
-rw-r--r--src/lactlsconnection.c216
3 files changed, 109 insertions, 130 deletions
diff --git a/TODO b/TODO
index fdedb80..f3541b4 100755
--- a/TODO
+++ b/TODO
@@ -19,6 +19,18 @@ correctness:
to it doesn't spin whent it gets a POLLERR that noone cares
about.
+ * TLS
+ - Implement the rest of the connection methods
+
+ - Make a wrapper Connection class that can be either
+ an SSL or a TCP connection.
+
+ - Move shared code to the wrapper
+
+ - Make sure TLSConnection sends events at the right
+ time. (Ie., never directly in response to a method
+ call). Make sure it's properly reentrant.
+
* SIGPIPE?
- ignore it around calls to send()?
diff --git a/src/lachttp.c b/src/lachttp.c
index 24335aa..b385ff1 100644
--- a/src/lachttp.c
+++ b/src/lachttp.c
@@ -726,6 +726,7 @@ real_parse_header (LacHttpRequest *request, const gchar *input)
if (empty_line (input))
{
+ g_print ("DONE with headers\n");
/* see RFC 2616 [HTTP], section 4.4
*/
if (request->type == HEAD_REQUEST ||
@@ -738,6 +739,7 @@ real_parse_header (LacHttpRequest *request, const gchar *input)
}
else if (request->seen_transfer_encoding_chunked)
{
+ g_print ("chunked\n");
request->parser_state = EXPECT_CHUNK_HEADER;
}
else if (request->content_length == 0)
@@ -749,6 +751,7 @@ real_parse_header (LacHttpRequest *request, const gchar *input)
}
else if (request->content_length > 0)
{
+ g_print ("length delimited: %d\n", request->content_length);
request->parser_state = EXPECT_LENGTH_DELIMITED_BODY;
}
#if 0
@@ -805,15 +808,13 @@ real_parse_header (LacHttpRequest *request, const gchar *input)
if (endptr != header_content + strlen (header_content))
{
/* The Content-Length header is garbage, ignore it. */
-#if 0
g_print ("-------------> content_length is garbage\n");
-#endif
request->content_length = -1;
}
-#if 0
else
+ {
g_print ("content-length: %d\n", request->content_length);
-#endif
+ }
}
else if (g_ascii_strcasecmp (header_name, "Connection") == 0)
{
@@ -2410,7 +2411,7 @@ http_transport_handle_close (HttpTransport *transport)
* We should perhaps special case that particular server
*/
- g_print ("Deceptive server lead us to believe that it supported pipelining, but it didn't\n");
+ g_print ("server indicated it supported pipelining, but it didn't\n");
http_host_transport_broken_server_notify (
transport->host, transport, 0);
diff --git a/src/lactlsconnection.c b/src/lactlsconnection.c
index 08177f9..08e14ac 100644
--- a/src/lactlsconnection.c
+++ b/src/lactlsconnection.c
@@ -29,7 +29,7 @@ struct _LacTlsConnection
LacConnection * tcp_connection;
LacTlsConnectionFunc callback;
gpointer data;
-
+
LacByteQueue * buffer;
LacByteQueue * unwritten;
@@ -58,9 +58,9 @@ static void
print_alert (gnutls_session session)
{
gnutls_alert_description_t d;
-
+
d = gnutls_alert_get (session);
-
+
g_print ("alert no: %d\n", d);
g_print ("alert: %s\n", gnutls_alert_get_name (d));
@@ -83,7 +83,7 @@ do_handshake (LacTlsConnection *tls)
#if 0
g_print (" handshake complete\n");
#endif
-
+
tls->need_handshake = FALSE;
/* FIXME: emit handshake event */
}
@@ -94,7 +94,7 @@ do_handshake (LacTlsConnection *tls)
{
g_print (" handshake error: %d (%s)\n",
res, gnutls_strerror (res));
-
+
if (res == GNUTLS_E_WARNING_ALERT_RECEIVED)
{
print_alert (tls->session);
@@ -103,7 +103,7 @@ do_handshake (LacTlsConnection *tls)
{
print_alert (tls->session);
}
-
+
/* FIXME: emit an error */
if (gnutls_error_is_fatal (res))
{
@@ -131,10 +131,10 @@ do_writes (LacTlsConnection *connection)
{
gsize n_written;
GError *err = NULL;
-
+
if (!lac_connection_is_connected (connection->tcp_connection))
return;
-
+
if (connection->need_handshake)
return;
@@ -142,11 +142,11 @@ do_writes (LacTlsConnection *connection)
{
gsize n_available;
const gchar *buffer;
-
+
n_written = 0;
-
+
buffer = lac_byte_queue_peek (connection->unwritten, &n_available);
-
+
if (n_available > 0)
{
n_written = gnutls_record_send (connection->session,
@@ -171,12 +171,76 @@ do_writes (LacTlsConnection *connection)
if (err)
{
emit_error (connection, err);
-
+
lac_connection_close (connection->tcp_connection);
}
}
static void
+handle_read (LacTlsConnection *tls,
+ const LacConnectionReadEvent *event)
+{
+ lac_byte_queue_append (tls->buffer, event->data, event->len);
+
+ do_handshake (tls);
+ do_writes (tls);
+
+ if (!tls->need_handshake)
+ {
+ LacByteQueue *queue;
+ gchar *buffer;
+ gssize n_read;
+ enum { BUF_SIZE = 8192 };
+ GError *err = NULL;
+
+ queue = lac_byte_queue_new ();
+
+ do
+ {
+ buffer = lac_byte_queue_alloc_tail (queue, BUF_SIZE);
+
+ n_read = gnutls_record_recv (tls->session, buffer, BUF_SIZE);
+
+ if (n_read < 0)
+ {
+ if (n_read != GNUTLS_E_INTERRUPTED &&
+ n_read != GNUTLS_E_AGAIN)
+ {
+ err = (GError *)0x01; /* FIXME - make a new error */
+ }
+
+ n_read = 0;
+ }
+
+ lac_byte_queue_delete_tail (queue, BUF_SIZE - n_read);
+ }
+ while (n_read > 0);
+
+ if (!lac_byte_queue_is_empty (queue))
+ {
+ LacConnectionEvent read_event;
+ gsize n_bytes;
+
+ read_event.type = LAC_CONNECTION_EVENT_READ;
+ read_event.read.byte_queue = queue;
+ read_event.read.data = lac_byte_queue_peek (queue, &n_bytes);
+ read_event.read.len = n_bytes;
+
+ tls->callback (tls, &read_event);
+ }
+
+ if (err)
+ {
+ emit_error (tls, err);
+
+ lac_connection_close (tls->tcp_connection);
+ }
+
+ lac_byte_queue_free (queue, TRUE);
+ }
+}
+
+static void
tcp_callback (LacConnection *connection,
const LacConnectionEvent *event)
{
@@ -186,92 +250,17 @@ tcp_callback (LacConnection *connection,
{
case LAC_CONNECTION_EVENT_CLOSE:
case LAC_CONNECTION_EVENT_ERROR:
- g_print ("SOMETHING HAPPENED \n");
tls->callback (tls, event);
break;
-
+
case LAC_CONNECTION_EVENT_CONNECT:
+ tls->callback (tls, event);
do_handshake (tls);
- g_print ("CONNECT HAPPENED\n");
- tls->callback (tls, event);
- do_writes (tls);
+ do_writes (tls);
break;
-
- case LAC_CONNECTION_EVENT_READ:
- g_print ("READ HAPPENED \n");
- /* add data to buffer */
-
- g_print ("bytes read: %d bytes: %x %x %x %x %x %x %x\n",
- event->read.len,
- event->read.data[0],
- event->read.data[1],
- event->read.data[2],
- event->read.data[3],
- event->read.data[4],
- event->read.data[5],
- event->read.data[6]);
- lac_byte_queue_append (tls->buffer, event->read.data, event->read.len);
-
- /* Writing sometimes requires data to be available for reading
- * from the TCP connection
- */
- do_handshake (tls);
- do_writes (tls);
-
- if (!tls->need_handshake)
- {
- LacByteQueue *queue;
- gchar *buffer;
- gssize n_read;
- enum { BUF_SIZE = 8192 };
- GError *err = NULL;
-
- queue = lac_byte_queue_new ();
-
- do
- {
- buffer = lac_byte_queue_alloc_tail (queue, BUF_SIZE);
-
- n_read = gnutls_record_recv (tls->session, buffer, BUF_SIZE);
-
- if (n_read < 0)
- {
- if (n_read != GNUTLS_E_INTERRUPTED &&
- n_read != GNUTLS_E_AGAIN)
- {
- err = (GError *)0x01; /* FIXME - make a new error */
- }
-
- n_read = 0;
- }
-
- lac_byte_queue_delete_tail (queue, BUF_SIZE - n_read);
- }
- while (n_read > 0);
-
- if (!lac_byte_queue_is_empty (queue))
- {
- LacConnectionEvent read_event;
- gsize n_bytes;
-
- read_event.type = LAC_CONNECTION_EVENT_READ;
- read_event.read.byte_queue = queue;
- read_event.read.data = lac_byte_queue_peek (queue, &n_bytes);
- read_event.read.len = n_bytes;
-
- tls->callback (tls, &read_event);
- }
-
- if (err)
- {
- emit_error (tls, err);
-
- lac_connection_close (tls->tcp_connection);
- }
-
- lac_byte_queue_free (queue, TRUE);
- }
+ case LAC_CONNECTION_EVENT_READ:
+ handle_read (tls, &event->read);
break;
}
}
@@ -282,20 +271,7 @@ tls_push (gnutls_transport_ptr_t tptr,
size_t n_bytes)
{
LacTlsConnection *tls = (LacTlsConnection *)tptr;
-
- g_print ("pushing some data (%d bytes)\n", n_bytes);
-#if 0
- g_print ("bytes pushed: bytes: %x %x %x %x %x %x %x\n",
- data[0],
- data[1],
- data[2],
- data[3],
- data[4],
- data[5],
- data[6]);
-#endif
-
lac_connection_write (tls->tcp_connection, data, n_bytes);
return n_bytes;
@@ -309,25 +285,26 @@ tls_pull (gnutls_transport_ptr_t tptr,
LacTlsConnection *tls = (LacTlsConnection *)tptr;
const gchar *buf;
gsize n_available;
-
+
buf = lac_byte_queue_peek (tls->buffer, &n_available);
-
+
if (n_available > 0)
{
gsize minimum = n_bytes < n_available? n_bytes : n_available;
-
+
memcpy (data, buf, minimum);
-
+
errno = 0;
-
+
lac_byte_queue_delete_head (tls->buffer, minimum);
return minimum;
}
else
{
+ /* FIXME: we should use the 'set_errno' function from gnutls */
errno = EAGAIN;
-
+
return -1;
}
}
@@ -339,8 +316,7 @@ lac_tls_connection_new (const LacAddress *address,
gpointer data)
{
LacTlsConnection *tls = g_new0 (LacTlsConnection, 1);
- const int kx_prio[] = { GNUTLS_KX_ANON_DH, 0 };
-
+
tls->tcp_connection = lac_connection_new (address, port, tcp_callback, tls);
tls->need_handshake = TRUE;
tls->callback = callback;
@@ -350,7 +326,7 @@ lac_tls_connection_new (const LacAddress *address,
gnutls_global_init ();
gnutls_anon_allocate_client_credentials (&tls->anoncred);
-
+
/* sets the trusted cas file
*/
gnutls_certificate_allocate_credentials (&tls->xcred);
@@ -363,15 +339,8 @@ lac_tls_connection_new (const LacAddress *address,
gnutls_init (&tls->session, GNUTLS_CLIENT);
gnutls_set_default_priority (tls->session);
-#if 0
- gnutls_kx_set_priority (tls->session, kx_prio);
-#endif
gnutls_credentials_set (tls->session, GNUTLS_CRD_CERTIFICATE, tls->xcred);
-#if 0
- gnutls_credentials_set (tls->session,
- GNUTLS_CRD_ANON, tls->anoncred);
-#endif
-
+
gnutls_transport_set_ptr (tls->session, (gnutls_transport_ptr_t)tls);
gnutls_transport_set_push_function (tls->session, tls_push);
gnutls_transport_set_pull_function (tls->session, tls_pull);
@@ -384,10 +353,7 @@ lac_tls_connection_write (LacTlsConnection *tls,
const gchar *data,
guint len)
{
- g_print ("len: %d\n", len);
lac_byte_queue_append (tls->unwritten, data, len);
-
- g_print ("user write: %s\n", data);
do_writes (tls);
}