diff options
author | Søren Sandmann <sandmann@redhat.com> | 2007-07-30 22:23:13 -0400 |
---|---|---|
committer | Søren Sandmann <sandmann@redhat.com> | 2007-07-30 22:23:13 -0400 |
commit | 5e42cfed15542f68153a279b9dac2dfc6153888d (patch) | |
tree | dbee0aec9e835be3a5540091f770a79cfab1613e | |
parent | 09e6dd2aacd7f7485c1edae78058d6f1bc2cefd2 (diff) |
Various stuff
-rwxr-xr-x | TODO | 12 | ||||
-rw-r--r-- | src/lachttp.c | 11 | ||||
-rw-r--r-- | src/lactlsconnection.c | 216 |
3 files changed, 109 insertions, 130 deletions
@@ -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); } |