From 76c52c4321cca3d28ee87c981c009250d0bd9848 Mon Sep 17 00:00:00 2001 From: Alex Graveley Date: Thu, 14 Jun 2001 22:26:17 +0000 Subject: [PATCH] Don't start from header_len offset. (soup_finish_read): Don't copy the 2001-06-14 Alex Graveley * src/soup-core/soup-queue.c (soup_read_chunk): Don't start from header_len offset. (soup_finish_read): Don't copy the recv_buf, just reference it. Don't free recv_buf. (soup_queue_read_cb): Handle truncating chunks, also truncate recv_buf after finishing headers. Make recv_buf contents public for chunk handlers. * src/soup-core/soup-message.c (soup_message_cleanup): Don't free the recv_buf->data, as we no longer copy it. * src/soup-core/soup-httpd.c: Update to missing header_len field. * src/soup-core/soup-private.h: change SoupMessage.header_len to a boolean headers_done. As we now truncate the buffer after downloading headers. --- ChangeLog | 19 ++++++++++++++ libsoup/soup-message.c | 4 +-- libsoup/soup-private.h | 2 +- libsoup/soup-queue.c | 67 ++++++++++++++++++++++++++++++-------------------- 4 files changed, 62 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index 85a182b..8099f2b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,24 @@ 2001-06-14 Alex Graveley + * src/soup-core/soup-queue.c (soup_read_chunk): Don't start from + header_len offset. + (soup_finish_read): Don't copy the recv_buf, just reference + it. Don't free recv_buf. + (soup_queue_read_cb): Handle truncating chunks, also truncate + recv_buf after finishing headers. Make recv_buf contents public + for chunk handlers. + + * src/soup-core/soup-message.c (soup_message_cleanup): Don't free + the recv_buf->data, as we no longer copy it. + + * src/soup-core/soup-httpd.c: Update to missing header_len field. + + * src/soup-core/soup-private.h: change SoupMessage.header_len to a + boolean headers_done. As we now truncate the buffer after + downloading headers. + +2001-06-14 Alex Graveley + * src/soup-core/soup-message.c (soup_message_set_flags): Remove redirect handler if option is removed. (soup_message_remove_handler): Added. Remove handler given diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c index ed47375..a4965ea 100644 --- a/libsoup/soup-message.c +++ b/libsoup/soup-message.c @@ -102,12 +102,12 @@ soup_message_cleanup (SoupMessage *req) req->priv->conn = NULL; } if (req->priv->recv_buf) { - g_byte_array_free (req->priv->recv_buf, TRUE); + g_byte_array_free (req->priv->recv_buf, FALSE); req->priv->recv_buf = NULL; } req->priv->write_len = 0; - req->priv->header_len = 0; + req->priv->headers_done = FALSE; req->priv->content_length = 0; req->priv->is_chunked = FALSE; req->priv->cur_chunk_len = 0; diff --git a/libsoup/soup-private.h b/libsoup/soup-private.h index 73ba00b..575886b 100644 --- a/libsoup/soup-private.h +++ b/libsoup/soup-private.h @@ -81,7 +81,7 @@ struct _SoupMessagePrivate { guint timeout_tag; guint write_len; - guint header_len; + gboolean headers_done; guint content_length; gboolean is_chunked; diff --git a/libsoup/soup-queue.c b/libsoup/soup-queue.c index fc734f8..4de9ef7 100644 --- a/libsoup/soup-queue.c +++ b/libsoup/soup-queue.c @@ -128,11 +128,6 @@ soup_read_chunk (SoupMessage *req) gint chunk_len = req->priv->cur_chunk_len; GByteArray *arr = req->priv->recv_buf; - if (!chunk_idx) { - chunk_len = 0; - chunk_idx = req->priv->header_len; - } - while (chunk_idx + chunk_len + 5 <= arr->len) { gint new_len = 0; gint len = 0, j; @@ -146,6 +141,7 @@ soup_read_chunk (SoupMessage *req) g_byte_array_set_size (arr, arr->len - 2); } + /* Convert the size of the next chunk from hex */ while ((tolower (*i) >= 'a' && tolower (*i) <= 'f') || (*i >= '0' && *i <= '9')) len++, i++; @@ -186,18 +182,11 @@ soup_read_chunk (SoupMessage *req) static void soup_finish_read (SoupMessage *req) { - GByteArray *arr = req->priv->recv_buf; - gint index = req->priv->header_len; SoupErrorCode err; req->response.owner = SOUP_BUFFER_SYSTEM_OWNED; - req->response.length = arr->len - index ; - req->response.body = g_memdup (&arr->data [index], - req->response.length + 1); - req->response.body [req->response.length] = '\0'; - - g_byte_array_free (arr, TRUE); - req->priv->recv_buf = NULL; + req->response.length = req->priv->recv_buf->len; + req->response.body = req->priv->recv_buf->data; req->status = SOUP_STATUS_FINISHED; @@ -218,8 +207,7 @@ soup_queue_read_cb (GIOChannel* iochannel, gchar read_buf [RESPONSE_BLOCK_SIZE]; gint bytes_read = 0; gboolean read_done = FALSE; - gint index = req->priv->header_len; - GByteArray *arr = req->priv->recv_buf; + GByteArray *arr; GIOError error; SoupErrorCode err; @@ -230,31 +218,60 @@ soup_queue_read_cb (GIOChannel* iochannel, if (error == G_IO_ERROR_AGAIN) return TRUE; - + if (error != G_IO_ERROR_NONE) { soup_message_issue_callback (req, SOUP_ERROR_IO); return FALSE; } + arr = req->priv->recv_buf; + if (!arr) arr = req->priv->recv_buf = g_byte_array_new (); - if (bytes_read) g_byte_array_append (arr, read_buf, bytes_read); + if (req->priv->headers_done && + req->priv->msg_flags & SOUP_MESSAGE_OVERWRITE_CHUNKS) { + req->priv->cur_chunk_len -= arr->len - req->priv->cur_chunk_idx; + req->priv->cur_chunk_idx = 0; + req->priv->content_length -= arr->len; + g_byte_array_set_size (arr, 0); + } - if (!index) { - index = soup_substring_index (arr->data, arr->len, "\r\n\r\n"); - if (index < 0) return TRUE; + if (bytes_read) + g_byte_array_append (arr, read_buf, bytes_read); - req->priv->header_len = index + 4; + if (!req->priv->headers_done) { + gint index = soup_substring_index (arr->data, + arr->len, + "\r\n\r\n"); + if (index < 0) return TRUE; /* Terminate Headers */ arr->data [index + 3] = '\0'; + index += 4; if (!soup_parse_headers (req) || !soup_process_headers (req)) return FALSE; + + g_memmove (arr->data, &arr->data [index], arr->len - index); + g_byte_array_set_size (arr, arr->len - index); + + req->priv->headers_done = TRUE; } + /* Allow the chunk parser to strip the data stream */ + if (bytes_read == 0) + read_done = TRUE; + else if (req->priv->is_chunked) + read_done = soup_read_chunk (req); + else if (req->priv->content_length == arr->len) + read_done = TRUE; + /* Don't call chunk handlers if we didn't actually read anything */ if (bytes_read != 0) { + req->response.owner = SOUP_BUFFER_SYSTEM_OWNED; + req->response.length = arr->len; + req->response.body = arr->data; + err = soup_message_run_handlers (req, SOUP_HANDLER_BODY_CHUNK); if (err) { soup_message_issue_callback (req, err); @@ -263,10 +280,6 @@ soup_queue_read_cb (GIOChannel* iochannel, return FALSE; } - if (bytes_read == 0) read_done = TRUE; - else if (req->priv->is_chunked) read_done = soup_read_chunk (req); - else if (req->priv->content_length==arr->len-index-4) read_done = TRUE; - if (read_done) { soup_finish_read (req); return FALSE; @@ -306,7 +319,7 @@ soup_queue_error_cb (GIOChannel* iochannel, soup_message_issue_callback (req, SOUP_ERROR_IO); break; case SOUP_STATUS_READING_RESPONSE: - if (req->priv->header_len && !conn_closed) { + if (req->priv->headers_done && !conn_closed) { soup_finish_read (req); break; } -- 2.7.4