[gupnp] Fix handling byte range request



commit ef42978326b1d02e3db6c50790b1aeb421fd4a87
Author: Lukasz Pawlik <lukasz pawlik comarch com>
Date:   Thu Feb 23 09:16:19 2012 +0100

    Fix handling byte range request
    
    Previously some syntactical valid byte ranges were not handled properly.
    In example for bytes=0-0 (first byte) in request gupnp returned whole file
    content. Also Content-Length was not set correctly. For bytes=33-66 in
    request, Content-Length: 99 was set but there was only 33 bytes in response
    body. This patch fix both issues.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=670518

 libgupnp/gupnp-context.c |   67 ++++++++++++++++++++++++++--------------------
 1 files changed, 38 insertions(+), 29 deletions(-)
---
diff --git a/libgupnp/gupnp-context.c b/libgupnp/gupnp-context.c
index 70e3679..e8ce360 100644
--- a/libgupnp/gupnp-context.c
+++ b/libgupnp/gupnp-context.c
@@ -916,58 +916,67 @@ host_path_handler (SoupServer        *server,
         status = SOUP_STATUS_OK;
 
         if (msg->method == SOUP_METHOD_GET) {
-                gsize offset, length;
                 gboolean have_range;
                 SoupBuffer *buffer;
+                SoupRange *ranges;
+                int nranges;
 
                 /* Find out range */
                 have_range = FALSE;
 
-                offset = 0;
-                length = st.st_size;
+                if (soup_message_headers_get_ranges (msg->request_headers,
+                                                     st.st_size,
+                                                     &ranges,
+                                                     &nranges))
+                        have_range = TRUE;
 
-                if (!http_request_get_range (msg,
-                                             &have_range,
-                                             &offset,
-                                             &length)) {
-                        soup_message_set_status
-                                (msg,
-                                 SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE);
-
-                        goto DONE;
-                }
-
-                if (have_range && (length > st.st_size - offset ||
+                /* We do not support mulipart/byteranges so only first first */
+                /* range from request is handled */
+                if (have_range && (ranges[0].end > st.st_size ||
                                    st.st_size < 0 ||
-                                   (off_t) offset >= st.st_size)) {
+                                   ranges[0].start >= st.st_size ||
+                                   ranges[0].start > ranges[0].end)) {
                         soup_message_set_status
                                 (msg,
                                  SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE);
+                        soup_message_headers_free_ranges (msg->request_headers,
+                                                          ranges);
 
                         goto DONE;
                 }
 
                 /* Add requested content */
                 buffer = soup_buffer_new_with_owner
-                             (g_mapped_file_get_contents (mapped_file) + offset,
-                              length,
+                             (g_mapped_file_get_contents (mapped_file),
+                              g_mapped_file_get_length (mapped_file),
                               mapped_file,
                               (GDestroyNotify) g_mapped_file_unref);
 
-                soup_message_body_append_buffer (msg->response_body, buffer);
-
-                soup_buffer_free (buffer);
-
-                /* Set status */
+                /* Set range and status */
                 if (have_range) {
-                        http_response_set_content_range (msg,
-                                                         offset,
-                                                         offset + length,
-                                                         st.st_size);
-
+                        SoupBuffer *range_buffer;
+
+                        soup_message_body_truncate (msg->response_body);
+                        soup_message_headers_set_content_range (
+                                                          msg->response_headers,
+                                                          ranges[0].start,
+                                                          ranges[0].end,
+                                                          buffer->length);
+                        range_buffer = soup_buffer_new_subbuffer (
+                                           buffer,
+                                           ranges[0].start,
+                                           ranges[0].end - ranges[0].start + 1);
+                        soup_message_body_append_buffer (msg->response_body,
+                                                         range_buffer);
                         status = SOUP_STATUS_PARTIAL_CONTENT;
-                }
 
+                        soup_message_headers_free_ranges (msg->request_headers,
+                                                          ranges);
+                        soup_buffer_free (range_buffer);
+                } else
+                        soup_message_body_append_buffer (msg->response_body, buffer);
+
+                soup_buffer_free (buffer);
         } else if (msg->method == SOUP_METHOD_HEAD) {
                 char *length;
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]