summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann <sandmann@redhat.com>2007-08-01 15:13:58 -0400
committerSøren Sandmann <sandmann@redhat.com>2007-08-01 15:13:58 -0400
commit86728957672c727903b5196ee0e12c0229cce404 (patch)
tree20bbe2d8c79f8c210dbd73475bc33b1b5bf2fdb4
parentb2ae3979ad3c3634fe9e4f84951d67bae172f656 (diff)
Lots of fixes
-rw-r--r--src/lac.h6
-rw-r--r--src/lacbytequeue.c63
-rw-r--r--src/lacdns-query.c15
-rw-r--r--src/lachttp.c118
-rw-r--r--src/lactcpconnection.c7
5 files changed, 102 insertions, 107 deletions
diff --git a/src/lac.h b/src/lac.h
index dc4f84e..3f21ce7 100644
--- a/src/lac.h
+++ b/src/lac.h
@@ -203,8 +203,11 @@ void lac_byte_queue_append (LacByteQueue *queue,
void lac_byte_queue_append_printf (LacByteQueue *queue,
const gchar *fmt,
...);
+void lac_byte_queue_swap_content (LacByteQueue *q1,
+ LacByteQueue *q2);
void lac_byte_queue_transfer_data (LacByteQueue *dest,
- LacByteQueue *src);
+ LacByteQueue *src,
+ gssize n_bytes);
void lac_byte_queue_delete_head (LacByteQueue *queue,
gsize size);
void lac_byte_queue_delete_tail (LacByteQueue *queue,
@@ -456,6 +459,7 @@ typedef struct {
typedef struct {
LacHttpEventType type;
+ LacByteQueue * byte_queue;
const guint8 * data;
gsize length;
} LacHttpContentEvent;
diff --git a/src/lacbytequeue.c b/src/lacbytequeue.c
index 075f157..23df1a9 100644
--- a/src/lacbytequeue.c
+++ b/src/lacbytequeue.c
@@ -197,9 +197,12 @@ lac_byte_queue_append (LacByteQueue *queue,
const gchar *bytes,
gsize n_bytes)
{
- gchar *tail = lac_byte_queue_alloc_tail (queue, n_bytes);
+ if (n_bytes > 0)
+ {
+ gchar *tail = lac_byte_queue_alloc_tail (queue, n_bytes);
- memcpy (tail, bytes, n_bytes);
+ memcpy (tail, bytes, n_bytes);
+ }
}
void
@@ -242,24 +245,60 @@ lac_byte_queue_steal (LacByteQueue *queue,
return result;
}
-/* Transfer data from @src to @dest, if possible without copying.
- * The data is appended to @dest's data if @dest is not empty
+void
+lac_byte_queue_swap_content (LacByteQueue *queue1,
+ LacByteQueue *queue2)
+{
+ gsize tmp1;
+ gchar *tmp2;
+
+ tmp1 = queue1->segment_size;
+ queue1->segment_size = queue2->segment_size;
+ queue2->segment_size = tmp1;
+
+ tmp2 = queue1->segment;
+ queue1->segment = queue2->segment;
+ queue2->segment = tmp2;
+
+ tmp2 = queue1->start;
+ queue1->start = queue2->start;
+ queue2->start = tmp2;
+
+ tmp2 = queue1->end;
+ queue1->end = queue2->end;
+ queue2->end = tmp2;
+}
+
+
+/* Transfer n_bytes data from the head of @src to tail of @dest,
+ * if possible without copying. The data is appended to @dest's data
+ * if @dest is not empty
*/
void
lac_byte_queue_transfer_data (LacByteQueue *dest,
- LacByteQueue *src)
+ LacByteQueue *src,
+ gssize n_bytes)
{
+ gsize total = src->end - src->start;
+ if (n_bytes < 0 || n_bytes > total)
+ n_bytes = total;
+
if (lac_byte_queue_is_empty (dest))
{
- if (dest->segment)
- g_free (dest->segment);
+ char *source = src->start;
+ gboolean swap_contents = FALSE;
- dest->segment_size = src->segment_size;
- dest->segment = src->segment;
- dest->start = src->start;
- dest->end = src->end;
+ if (n_bytes > total / 2)
+ {
+ source = src->start + n_bytes;
+ n_bytes = total - n_bytes;
+ swap_contents = TRUE;
+ }
- initialize (src);
+ lac_byte_queue_append (dest, source, n_bytes);
+
+ if (swap_contents)
+ lac_byte_queue_swap_content (dest, src);
}
else
{
diff --git a/src/lacdns-query.c b/src/lacdns-query.c
index e1ee981..dba8e92 100644
--- a/src/lacdns-query.c
+++ b/src/lacdns-query.c
@@ -157,7 +157,20 @@ emit_no_such_name (DnsQuery *query)
if (dns_query_next_name (query))
{
if (!dns_query_cache_lookup (query))
- dns_query_ask_server (query);
+ {
+ /* We need to delete the list of uncachable records
+ * here since as soon as we return from analyze_reply()
+ * the content will be freed, and this query may
+ * survive longer than that.
+ *
+ * In the the other emit() functions we call
+ * do_callback() which takes care of the problem.
+ */
+ while (g_queue_pop_head (query->uncachable_records))
+ ;
+
+ dns_query_ask_server (query);
+ }
return;
}
diff --git a/src/lachttp.c b/src/lachttp.c
index 343f4ad..8ac79b5 100644
--- a/src/lachttp.c
+++ b/src/lachttp.c
@@ -521,9 +521,6 @@ request_get_line (LacHttpRequest *request, gchar **result)
gsize n_bytes;
const gchar *unparsed = lac_byte_queue_peek (request->unparsed, &n_bytes);
-#if 0
- g_print ("unparsed: %s\n", request->unparsed->str);
-#endif
lf_pos = strchr (unparsed, LF);
if (!lf_pos)
@@ -535,15 +532,9 @@ request_get_line (LacHttpRequest *request, gchar **result)
/* n_bytes > strlen (unparsed)
* means that we have received a '\0' byte
*/
-#if 0
- g_print ("either we received a nul byte, or we received something without a linefeed\n");
-#endif
return ERROR;
}
-#if 0
- g_print ("line NEED_MORE_DATA\n");
-#endif
return NEED_MORE_DATA;
}
@@ -552,18 +543,8 @@ request_get_line (LacHttpRequest *request, gchar **result)
*result = g_strstrip (g_strndup (unparsed, line_len));
/* delete up to and including the LF */
-#if 0
- printf ("line ok\n");
- printf ("before: %s\n", g_strndup (unparsed, 128));
- printf ("deleting %d\n", line_len + 1);
-#endif
-
lac_byte_queue_delete_head (request->unparsed, line_len + 1);
-#if 0
- printf ("after: %s\n", g_strndup (lac_byte_queue_peek_data (request->unparsed, NULL), 128));
-#endif
-
return OK;
}
@@ -638,10 +619,6 @@ static ParseResult
real_parse_status_line (LacHttpRequest *request, const char *input)
{
gchar *endptr;
-
-#if 0
- g_print ("parsing status line: %s\n", input);
-#endif
/* HTTP */
if (strncmp (input, "HTTP", 4) != 0)
@@ -728,7 +705,6 @@ 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 ||
@@ -741,7 +717,6 @@ 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)
@@ -753,7 +728,6 @@ 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
@@ -778,12 +752,7 @@ real_parse_header (LacHttpRequest *request, const gchar *input)
colon = strchr (input, ':');
if (!colon)
{
-#if 0
- g_print ("Header line without colon: \n");
-
- g_print (" %s\n", input);
-#endif
-
+ g_print ("no colon in header\n");
return ERROR;
}
@@ -829,7 +798,9 @@ real_parse_header (LacHttpRequest *request, const gchar *input)
}
else if (g_ascii_strcasecmp (header_content, "keep-alive") == 0)
{
+#if 0
g_print ("CONNECTION: KEEP-ALIVE\n");
+#endif
request->seen_connection_keep_alive = TRUE;
}
}
@@ -870,14 +841,14 @@ static ParseResult
real_parse_chunk_header (LacHttpRequest *request, const gchar *input)
{
gchar *endptr;
+
+ g_print ("input: %s\n", input);
/* size */
request->current_chunk_size = strtol (input, &endptr, 16);
if (endptr == input)
{
-#if 0
g_print ("bad chunk header\n");
-#endif
return ERROR;
}
@@ -937,9 +908,7 @@ request_parse_chunk_data (LacHttpRequest *request)
}
else
{
-#if 0
g_print ("chunk data not followed by CRLF\n");
-#endif
return ERROR;
}
}
@@ -1040,7 +1009,7 @@ request_parse_response (LacHttpRequest *request,
g_print ("received: %d\n", len);
#endif
- lac_byte_queue_transfer_data (request->unparsed, bytes);
+ lac_byte_queue_transfer_data (request->unparsed, bytes, -1);
while (lac_byte_queue_get_length (request->unparsed) > 0)
{
@@ -1096,7 +1065,7 @@ request_parse_response (LacHttpRequest *request,
#if 0
g_assert (lac_byte_queue_get_length (request->unparsed) < len);
#endif
- lac_byte_queue_transfer_data (bytes, request->unparsed);
+ lac_byte_queue_transfer_data (bytes, request->unparsed, -1);
return TRUE;
break;
@@ -1391,36 +1360,39 @@ request_emit_content (LacHttpRequest *request,
gsize length,
LacByteQueue *queue)
{
- gint bytes_to_emit;
LacHttpEvent *event = g_new (LacHttpEvent, 1);
+ gssize bytes_to_ignore;
+ LacByteQueue *copy;
if (!request->sent_begin_content)
request_emit_begin_content (request, -1);
-
- bytes_to_emit = length;
-
- if (request->n_content_bytes < request->n_ignore_bytes)
+
+ bytes_to_ignore = request->n_ignore_bytes - request->n_content_bytes;
+ request->n_content_bytes += length;
+
+ if (bytes_to_ignore > 0)
{
- bytes_to_emit = length -
- (request->n_ignore_bytes - request->n_content_bytes);
+ if (bytes_to_ignore >= length)
+ bytes_to_ignore = length;
+
+ lac_byte_queue_delete_head (queue, bytes_to_ignore);
+ length -= bytes_to_ignore;
}
-
- request->n_content_bytes += length;
-
- if (bytes_to_emit > 0)
+
+ copy = lac_byte_queue_new ();
+ lac_byte_queue_transfer_data (copy, queue, length);
+
+ if (length > 0)
{
- const gchar *data = lac_byte_queue_peek (queue, NULL);
-
- data = data + (length - bytes_to_emit);
-
+ const gchar *data = lac_byte_queue_peek (copy, NULL);
+
event->type = LAC_HTTP_EVENT_CONTENT;
- event->content.length = bytes_to_emit;
- event->content.data = g_memdup (data, bytes_to_emit);
+ event->content.length = length;
+ event->content.byte_queue = copy;
+ event->content.data = g_memdup (data, length);
request_queue_event (request, event);
}
-
- lac_byte_queue_delete_head (queue, length);
}
static void
@@ -2262,15 +2234,8 @@ http_transport_handle_read (HttpTransport *transport,
g_assert (transport->current);
- if (!request_parse_response (transport->current, read_event->byte_queue))
-
-#if 0
- lac_byte_queue_delete_head (read_event->byte_queue, used);
-
- write_log_file (transport, len, used, read_event);
-
- if (used < 0)
-#endif
+ if (!request_parse_response (transport->current,
+ read_event->byte_queue))
{
GError *err = g_error_new (LAC_HTTP_ERROR,
LAC_HTTP_ERROR_MALFORMED_RESPONSE,
@@ -2278,7 +2243,7 @@ http_transport_handle_read (HttpTransport *transport,
http_host_transport_will_close_notify (transport->host, transport);
- g_print ("malformed response\n");
+ g_print ("malformed response: %s\n", lac_uri_string (transport->current->uri));
if (!transport->broken_server && transport->did_pipeline)
{
server_choked_on_pipeline (transport, 5000);
@@ -2295,35 +2260,16 @@ http_transport_handle_read (HttpTransport *transport,
}
if (request_done_parsing (transport->current))
- {
-#if 0
- g_print ("RESPONSE SUCCESFULLY PARSED\n");
-#endif
++transport->successful_requests;
- }
if (transport->pipelining)
{
-#if 0
- g_print ("pipelining\n");
-#endif
if (request_connection_will_close (transport->current))
{
-#if 0
- g_print ("closing after successful requests: %d\n",
- transport->successful_requests);
-#endif
-#if 0
- g_print ("%p CONNECITON WILL CLOSE\n", transport);
-#endif
if ((transport->successful_requests > 1 ||
g_queue_is_empty (transport->in_progress)) &&
request_connection_is_1_1 (transport->current))
{
-#if 0
- if (g_queue_is_empty (transport->in_progress))
- g_print ("nothing in progress\n");
-#endif
/* This is an HTTP/1.1 server, where we have either
* seen pipelining work, or we have never sent more
* than one request, so we won't tell the host object
diff --git a/src/lactcpconnection.c b/src/lactcpconnection.c
index 31c9e7d..d72fbd3 100644
--- a/src/lactcpconnection.c
+++ b/src/lactcpconnection.c
@@ -412,13 +412,6 @@ lac_tcp_connection_get_data (LacTcpConnection *connection)
}
void
-lac_tcp_connection_write_queue (LacTcpConnection *connection,
- LacByteQueue *queue)
-{
- lac_byte_queue_transfer_data (connection->unwritten, queue);
-}
-
-void
lac_tcp_connection_write (LacTcpConnection *connection,
const gchar *data,
guint len)