diff options
author | Søren Sandmann <sandmann@redhat.com> | 2007-08-01 15:13:58 -0400 |
---|---|---|
committer | Søren Sandmann <sandmann@redhat.com> | 2007-08-01 15:13:58 -0400 |
commit | 86728957672c727903b5196ee0e12c0229cce404 (patch) | |
tree | 20bbe2d8c79f8c210dbd73475bc33b1b5bf2fdb4 | |
parent | b2ae3979ad3c3634fe9e4f84951d67bae172f656 (diff) |
Lots of fixes
-rw-r--r-- | src/lac.h | 6 | ||||
-rw-r--r-- | src/lacbytequeue.c | 63 | ||||
-rw-r--r-- | src/lacdns-query.c | 15 | ||||
-rw-r--r-- | src/lachttp.c | 118 | ||||
-rw-r--r-- | src/lactcpconnection.c | 7 |
5 files changed, 102 insertions, 107 deletions
@@ -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) |