From 3bc139e4e6de8cc707cc538527c3a1e1bd4eca0a Mon Sep 17 00:00:00 2001 From: Jens Georg Date: Tue, 31 May 2011 09:37:42 +0200 Subject: [PATCH] core: Use libsoup in ImportResource Using GIO has two problems: it needs the external http gvfs module which might not be available everywhere and even if it's available, the copy operation does a HEAD request first which makes the certification test fail. Partially fixes UPnP CTT testcases AV-CD:1-9.1, AV-CD:1-11.1 and AV-CD:1-12.1 --- src/rygel/rygel-import-resource.vala | 73 +++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 17 deletions(-) diff --git a/src/rygel/rygel-import-resource.vala b/src/rygel/rygel-import-resource.vala index 6e57e38..4ab7a20 100644 --- a/src/rygel/rygel-import-resource.vala +++ b/src/rygel/rygel-import-resource.vala @@ -22,6 +22,7 @@ */ using GUPnP; +using Soup; internal enum Rygel.TransferStatus { COMPLETED, @@ -48,6 +49,7 @@ internal class Rygel.ImportResource : GLib.Object, Rygel.StateMachine { public int64 bytes_total; private MediaItem item; + private Session session; public string status_as_string { get { @@ -70,6 +72,8 @@ internal class Rygel.ImportResource : GLib.Object, Rygel.StateMachine { private HTTPServer http_server; private MediaContainer root_container; private ServiceAction action; + private SourceFunc run_callback; + private FileOutputStream output_stream; public ImportResource (ContentDirectory content_dir, owned ServiceAction action) { @@ -85,6 +89,7 @@ internal class Rygel.ImportResource : GLib.Object, Rygel.StateMachine { this.bytes_total = 0; this.status = TransferStatus.IN_PROGRESS; + this.session = new SessionAsync (); content_dir.cancellable.cancelled.connect (() => { this.cancellable.cancel (); @@ -136,21 +141,25 @@ internal class Rygel.ImportResource : GLib.Object, Rygel.StateMachine { var queue = ItemRemovalQueue.get_default (); queue.dequeue (this.item); - try { - var destination_file = File.new_for_uri (this.item.uris[0]); - var source_file = File.new_for_uri (source_uri); - - yield source_file.copy_async (destination_file, - FileCopyFlags.OVERWRITE, - Priority.LOW, - this.cancellable, - this.copy_progress_cb); - this.status = TransferStatus.COMPLETED; - debug ("Import of '%s' to '%s' completed", - source_uri, - destination_file.get_uri ()); + try { + var source_file = File.new_for_uri (this.item.uris[0]); + this.output_stream = yield source_file.replace_async (null, + false, + FileCreateFlags.PRIVATE, + Priority.DEFAULT, + this.cancellable); + var message = new Message ("GET", source_uri); + message.got_chunk.connect (this.got_chunk_cb); + message.got_body.connect (this.got_body_cb); + message.got_headers.connect (this.got_headers_cb); + message.finished.connect (this.finished_cb); + + this.run_callback = run.callback; + this.session.queue_message (message, null); + + yield; } catch (Error err) { warning ("%s", err.message); this.status = TransferStatus.ERROR; @@ -184,10 +193,40 @@ internal class Rygel.ImportResource : GLib.Object, Rygel.StateMachine { return media_object as MediaItem; } - private void copy_progress_cb (int64 current_num_bytes, - int64 total_num_bytes) { - this.bytes_copied = current_num_bytes; - this.bytes_total = total_num_bytes; + private void got_headers_cb (Message message) { + this.bytes_total = message.response_headers.get_content_length (); + } + + private void got_chunk_cb (Message message, Buffer buffer) { + this.bytes_copied += buffer.length; + try { + size_t bytes_written; + + this.output_stream.write_all (buffer.data, + out bytes_written, + this.cancellable); + } catch (Error error) { + warning ("%s", error.message); + this.status = TransferStatus.ERROR; + this.session.cancel_message (message, + KnownStatusCode.CANCELLED); + } + } + + private void got_body_cb (Message message) { + try { + this.output_stream.close (this.cancellable); + if (this.status == TransferStatus.IN_PROGRESS) { + this.status = TransferStatus.COMPLETED; + } + } catch (Error error) { + warning ("%s", error.message); + this.status = TransferStatus.ERROR; + } + } + + private void finished_cb (Message message) { + this.run_callback (); } } -- 2.7.4