$OpenBSD: patch-daemon_gvfshttpinputstream_c,v 1.1 2013/12/21 13:21:49 ajacoutot Exp $

From 957f11be4d02c4cb2ee8b3a1181e7973d297eea7 Mon Sep 17 00:00:00 2001
From: Ross Lagerwall <rosslagerwall@gmail.com>
Date: Sun, 08 Dec 2013 10:44:06 +0000
Subject: http: Fix segfault when seeking on read

From ee9743d30107fb86ba58d3bf78c85ef2792797b4 Mon Sep 17 00:00:00 2001
From: Ross Lagerwall <rosslagerwall@gmail.com>
Date: Sun, 08 Dec 2013 11:02:35 +0000
Subject: http: Ensure the range header is updated

From 81a5cbafb95435ab73611be61a01672d6a0580de Mon Sep 17 00:00:00 2001
From: Ross Lagerwall <rosslagerwall@gmail.com>
Date: Sun, 08 Dec 2013 11:01:40 +0000
Subject: http: Fix the SEEK_END offset calculation

From 0775a4adee787a5032ed876db1e3bac237e60ed0 Mon Sep 17 00:00:00 2001
From: Ross Lagerwall <rosslagerwall@gmail.com>
Date: Sun, 08 Dec 2013 11:04:45 +0000
Subject: http: Allow seek past end of file

--- daemon/gvfshttpinputstream.c.orig	Sat Dec 21 14:11:39 2013
+++ daemon/gvfshttpinputstream.c	Sat Dec 21 14:11:50 2013
@@ -45,6 +45,7 @@ typedef struct {
   GInputStream *stream;
 
   char *range;
+  goffset request_offset;
   goffset offset;
 
 } GVfsHttpInputStreamPrivate;
@@ -117,11 +118,11 @@ g_vfs_http_input_stream_ensure_request (GInputStream *
       g_assert_no_error (error);
       priv->msg = soup_request_http_get_message (SOUP_REQUEST_HTTP (priv->req));
       priv->offset = 0;
-
-      if (priv->range)
-	soup_message_headers_replace (priv->msg->request_headers, "Range", priv->range);
     }
 
+  if (priv->range)
+    soup_message_headers_replace (priv->msg->request_headers, "Range", priv->range);
+
   return priv->req;
 }
 
@@ -330,7 +331,8 @@ read_send_callback (GObject      *object,
   ReadAfterSendData *rasd = g_task_get_task_data (task);
   GError *error = NULL;
 
-  if (!soup_request_send_finish (SOUP_REQUEST (object), result, &error))
+  priv->stream = soup_request_send_finish (SOUP_REQUEST (object), result, &error);
+  if (!priv->stream)
     {
       g_task_return_error (task, error);
       g_object_unref (task);
@@ -338,6 +340,14 @@ read_send_callback (GObject      *object,
     }
   if (!SOUP_STATUS_IS_SUCCESSFUL (priv->msg->status_code))
     {
+      if (priv->msg->status_code == SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE)
+        {
+          g_input_stream_close (priv->stream, NULL, NULL);
+          g_task_return_int (task, 0);
+          g_clear_object (&priv->stream);
+          g_object_unref (task);
+          return;
+        }
       g_task_return_new_error (task,
 			       SOUP_HTTP_ERROR,
 			       priv->msg->status_code,
@@ -475,7 +485,7 @@ g_vfs_http_input_stream_seek (GSeekable     *seekable,
       if (content_length)
 	{
 	  type = G_SEEK_SET;
-	  offset = content_length - offset;
+	  offset = priv->request_offset + content_length + offset;
 	}
     }
 
@@ -511,6 +521,7 @@ g_vfs_http_input_stream_seek (GSeekable     *seekable,
 
     case G_SEEK_SET:
       priv->range = g_strdup_printf ("bytes=%"G_GUINT64_FORMAT"-", (guint64)offset);
+      priv->request_offset = offset;
       priv->offset = offset;
       break;
 
