+Optimization of neon "http" handler to avoid resetting connection on seek().
[captive.git] / src / install / acquire / cabinet.c
index ade7d80..3967631 100644 (file)
@@ -32,6 +32,7 @@
 #include <signal.h>
 #include <setjmp.h>
 #include <sys/time.h>
+#include "cabinet-memory.h"
 
 #include <captive/macros.h>
 
@@ -101,7 +102,7 @@ static void handler_SIGALRM(int signo)
 /* FIXME: This is hack.
  * Correct way would be to use 'GnomeVFSCancellation'
  * to abort 'GnomeVFSInetConnection' acting as 'GnomeVFSSocket'.
- * This abort should be handled from 'http'/'httpcaptive' handler
+ * This abort should be handled from 'http' handler
  * but gnome_vfs_cancellation_cancel() cannot be invoked from
  * the asynchronous slave thread.
  */
@@ -126,6 +127,7 @@ GnomeVFSHandle *handle_new;
 struct sigaction oldact;
 int errint;
 struct itimerval itimerval;
+GnomeVFSFileSize offset_current;
 
                if ((*ui_progress)(NULL))
                        return GNOME_VFS_ERROR_INTERRUPTED;
@@ -148,7 +150,13 @@ struct itimerval itimerval;
                                        &itimerval,     /* value */
                                        NULL);  /* ovalue */
                        g_assert(errint==0);
-                       errvfsresult=gnome_vfs_seek(*acquire_cabinet->handlep,GNOME_VFS_SEEK_START,offset);
+                       /* Optimization avoid resetting connection
+                        * in neon "http" handler of: FC4 gnome-vfs2-2.10.0-5
+                        * http://bugzilla.gnome.org/show_bug.cgi?id=324984
+                        */
+                       errvfsresult=gnome_vfs_tell(*acquire_cabinet->handlep,&offset_current);
+                       if (GNOME_VFS_OK==errvfsresult && (GnomeVFSFileOffset)offset_current!=offset)
+                               errvfsresult=gnome_vfs_seek(*acquire_cabinet->handlep,GNOME_VFS_SEEK_START,offset);
                        if (GNOME_VFS_OK==errvfsresult)
                                errvfsresult=gnome_vfs_read(*acquire_cabinet->handlep,buffer,bytes,bytes_read);
                        }
@@ -174,7 +182,8 @@ struct itimerval itimerval;
 
                /* Reopen '*acquire_cabinet->handlep' */
                g_assert(acquire_cabinet->handle_uri!=NULL);
-               if (GNOME_VFS_OK==(errvfsresult=gnome_vfs_open_uri(&handle_new,acquire_cabinet->handle_uri,GNOME_VFS_OPEN_READ))) {
+               if (GNOME_VFS_OK==(errvfsresult=gnome_vfs_open_uri(&handle_new,acquire_cabinet->handle_uri,
+                                       GNOME_VFS_OPEN_READ|GNOME_VFS_OPEN_RANDOM))) {
                        gnome_vfs_close(*acquire_cabinet->handlep);     /* errors ignored */
                        *acquire_cabinet->handlep=handle_new;
                        }
@@ -287,6 +296,7 @@ struct acquire_cabinet *r;
        acquire_cabinet_set_uri(r,uri);
        r->cabinet_done=0;
        r->cabinet_used=cabinet_used;
+       r->memory=acquire_cabinet_memory_object_new();
 
        return r;
 }
@@ -320,33 +330,8 @@ struct acquire_cabinet *r;
        r->cabinet_done=0;
        r->cabinet_used=cabinet_used;
 
-       /* Replace 'http://' by 'httpcaptive://' if system 'http' does not support seek(). */
-       gnome_vfs_uri_ref(uri);
-       if (GNOME_VFS_ERROR_NOT_SUPPORTED==gnome_vfs_seek(
-                       *handlep,       /* handle */
-                       GNOME_VFS_SEEK_START,   /* whence */
-                       0)) {   /* offset */
-gchar *href;
-const gchar *href2;
-GnomeVFSURI *uri2;
-
-               href=gnome_vfs_uri_to_string(uri,GNOME_VFS_URI_HIDE_NONE);
-               if (strncmp(href,"http://",strlen("http://"))) {
-                       g_warning(_("Destination file URL not valid: %s"),href);
-                       goto href_done;
-                       }
-               href2=captive_printf_alloca("httpcaptive://%s",href+strlen("http://"));
-               if (!(uri2=gnome_vfs_uri_new(href2))) {
-                       g_warning(_("'httpcaptive' GnomeVFS method not supported; install package 'gnomevfs-httpcaptive'; URL: %s"),href2);
-                       goto href_done;
-                       }
-               gnome_vfs_uri_unref(uri);
-               uri=uri2;
-href_done:;
-               }
-
        acquire_cabinet_set_uri(r,uri);
-       gnome_vfs_uri_unref(uri);
+       r->memory=acquire_cabinet_memory_object_new();
 
        return r;
 }
@@ -362,6 +347,7 @@ void acquire_cabinet_free(struct acquire_cabinet *acquire_cabinet)
        g_free((/* de-const */ gchar *)acquire_cabinet->filename);
        gnome_vfs_uri_unref(acquire_cabinet->uri);
        gnome_vfs_uri_unref(acquire_cabinet->handle_uri);
+       g_object_unref(acquire_cabinet->memory);
        g_free(acquire_cabinet);
 }
 
@@ -397,13 +383,15 @@ struct file *filelist,*fi;
        if ((*ui_progress)(acquire_cabinet->uri))
                return;
 
+       acquire_cabinet_memory_object_push(acquire_cabinet->memory);
+
        basecab=find_cabs_in_file(acquire_cabinet);
        if (!basecab)
-               return;
+               goto fail_memory_pop;
        if (basecab->next)
-               return;
+               goto fail_memory_pop;
        if (basecab->prevcab || basecab->nextcab)
-               return;
+               goto fail_memory_pop;
 
        filelist=process_files(basecab);
 
@@ -418,7 +406,7 @@ int errint;
                uri_fi=gnome_vfs_uri_append_file_name(acquire_cabinet->uri,fi->filename);
                if ((*ui_progress)(uri_fi)) {
                        gnome_vfs_uri_unref(uri_fi);
-                       return;
+                       goto fail_memory_pop;
                        }
 
                file_write_fi_assertion=fi;
@@ -433,7 +421,7 @@ int errint;
                                        TRUE);  /* free_segment */
                        gnome_vfs_uri_unref(uri_fi);
                        if (!errint)
-                               return;
+                               goto fail_memory_pop;
                        continue;
                        }
                file_buffer=g_byte_array_free(file_write_bytearray,
@@ -442,4 +430,9 @@ int errint;
                gnome_vfs_uri_unref(uri_fi);
                g_free(file_buffer);
     }
+
+       /* FALLTHRU */
+
+fail_memory_pop:
+       acquire_cabinet_memory_object_pop(acquire_cabinet->memory);
 }