Don't start from header_len offset. (soup_finish_read): Don't copy the
authorAlex Graveley <alex@ximian.com>
Thu, 14 Jun 2001 22:26:17 +0000 (22:26 +0000)
committerAlex Graveley <orph@src.gnome.org>
Thu, 14 Jun 2001 22:26:17 +0000 (22:26 +0000)
2001-06-14  Alex Graveley  <alex@ximian.com>

* 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
libsoup/soup-message.c
libsoup/soup-private.h
libsoup/soup-queue.c

index 85a182b..8099f2b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,24 @@
 2001-06-14  Alex Graveley  <alex@ximian.com>
 
+       * 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  <alex@ximian.com>
+
        * 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
index ed47375..a4965ea 100644 (file)
@@ -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;
index 73ba00b..575886b 100644 (file)
@@ -81,7 +81,7 @@ struct _SoupMessagePrivate {
        guint           timeout_tag;
 
        guint           write_len;
-       guint           header_len;
+       gboolean        headers_done;
 
        guint           content_length;
        gboolean        is_chunked;
index fc734f8..4de9ef7 100644 (file)
@@ -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;
                }