core,tests: Merge GstResponse into HTTPResponse
authorZeeshan Ali (Khattak) <zeeshanak@gnome.org>
Sat, 9 Apr 2011 00:27:27 +0000 (03:27 +0300)
committerZeeshan Ali (Khattak) <zeeshanak@gnome.org>
Sat, 9 Apr 2011 01:44:57 +0000 (04:44 +0300)
15 files changed:
po/POTFILES.in
po/POTFILES.skip
src/rygel/Makefile.am
src/rygel/rygel-http-gst-response.vala [deleted file]
src/rygel/rygel-http-gst-sink.vala
src/rygel/rygel-http-identity-handler.vala
src/rygel/rygel-http-response.vala
src/rygel/rygel-http-transcode-handler.vala
tests/Makefile.am
tests/rygel-http-gst-response-test.vala [deleted file]
tests/rygel-http-gst-response.vala [deleted symlink]
tests/rygel-http-response-test.vala
tests/rygel-http-response-test_gst-response.vala [deleted symlink]
tests/rygel-http-response.vala [moved from tests/rygel-http-response_gst-response.vala with 100% similarity]
tests/rygel-state-machine_http-response.vala [moved from tests/rygel-state-machine_gst-response.vala with 100% similarity]

index 34ab9e1..d7fec05 100644 (file)
@@ -100,7 +100,6 @@ src/rygel/rygel-item-creator.vala
 src/rygel/rygel-item-destroyer.vala
 src/rygel/rygel-l16-transcoder-bin.vala
 src/rygel/rygel-l16-transcoder.vala
-src/rygel/rygel-http-gst-response.vala
 src/rygel/rygel-log-handler.vala
 src/rygel/rygel-logical-expression.vala
 src/rygel/rygel-main.vala
index 4730ba2..1cac003 100644 (file)
@@ -59,7 +59,7 @@ src/rygel/rygel-import-resource.c
 src/rygel/rygel-item-creator.c
 src/rygel/rygel-item-destroyer.c
 src/rygel/rygel-l16-transcoder-bin.c
-src/rygel/rygel-http-gst-response.c
+src/rygel/rygel-http-response.c
 src/rygel/rygel-log-handler.c
 src/rygel/rygel-main.c
 src/rygel/rygel-media-container.c
@@ -100,7 +100,7 @@ tests/rygel-gst-utils.c
 tests/rygel-http-byte-seek.c
 tests/rygel-http-item-uri.c
 tests/rygel-http-time-seek.c
-tests/rygel-http-gst-response.c
+tests/rygel-http-response.c
 tests/rygel-http-byte-seek_http-get.c
 tests/rygel-http-get.c
 tests/rygel-http-item-uri_http-get.c
index 32d1b78..73c7c69 100644 (file)
@@ -52,7 +52,6 @@ VAPI_SOURCE_FILES = \
        rygel-http-byte-seek.vala \
        rygel-http-time-seek.vala \
        rygel-http-response.vala \
-       rygel-http-gst-response.vala \
        rygel-http-gst-sink.vala \
        rygel-resource-info.vala \
        rygel-icon-info.vala \
diff --git a/src/rygel/rygel-http-gst-response.vala b/src/rygel/rygel-http-gst-response.vala
deleted file mode 100644 (file)
index c204842..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (C) 2008 Zeeshan Ali (Khattak) <zeeshanak@gnome.org>.
- * Copyright (C) 2008,2011 Nokia Corporation.
- *
- * Author: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
- *                               <zeeshan.ali@nokia.com>
- *
- * This file is part of Rygel.
- *
- * Rygel is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Rygel is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-using Gst;
-using Soup;
-
-internal class Rygel.HTTPGstResponse : Rygel.HTTPResponse {
-    private Pipeline pipeline;
-    private uint bus_watch_id;
-
-    public HTTPSeek seek;
-
-    public HTTPGstResponse (HTTPGet        request,
-                            HTTPGetHandler request_handler,
-                            Element        src) throws Error {
-        var partial = (request.seek != null &&
-                       request.seek.length < request.seek.total_length);
-
-        base (request, request_handler, partial);
-
-        this.seek = request.seek;
-        this.prepare_pipeline ("RygelHTTPGstResponse", src);
-
-        if (this.seek != null && this.seek is HTTPByteSeek) {
-            this.msg.response_headers.set_encoding (Encoding.CONTENT_LENGTH);
-        } else {
-            this.msg.response_headers.set_encoding (Encoding.EOF);
-        }
-    }
-
-    public override async void run () {
-        // Only bother attempting to seek if the offset is greater than zero.
-        if (this.seek != null && this.seek.start > 0) {
-            this.pipeline.set_state (State.PAUSED);
-        } else {
-            this.pipeline.set_state (State.PLAYING);
-        }
-
-        this.run_continue = run.callback;
-
-        yield;
-    }
-
-    public override void end (bool aborted, uint status) {
-        var sink = this.pipeline.get_by_name (HTTPGstSink.NAME) as HTTPGstSink;
-        sink.cancellable.cancel ();
-
-        this.pipeline.set_state (State.NULL);
-        Source.remove (this.bus_watch_id);
-
-        var encoding = this.msg.response_headers.get_encoding ();
-
-        if (!aborted && encoding != Encoding.CONTENT_LENGTH) {
-            this.msg.response_body.complete ();
-            this.server.unpause_message (this.msg);
-        }
-
-        base.end (aborted, status);
-    }
-
-    private void prepare_pipeline (string name,
-                                   Element src) throws Error {
-        var sink = new HTTPGstSink (this);
-
-        this.pipeline = new Pipeline (name);
-        assert (this.pipeline != null);
-
-        this.pipeline.add_many (src, sink);
-
-        if (src.numpads == 0) {
-            // Seems source uses dynamic pads, link when pad available
-            src.pad_added.connect (this.src_pad_added);
-        } else {
-            // static pads? easy!
-            if (!src.link (sink)) {
-                throw new GstError.LINK (_("Failed to link %s to %s"),
-                                         src.name,
-                                         sink.name);
-            }
-        }
-
-        // Bus handler
-        var bus = this.pipeline.get_bus ();
-        this.bus_watch_id = bus.add_watch (this.bus_handler);
-    }
-
-    private void src_pad_added (Element src,
-                                Pad     src_pad) {
-        var caps = src_pad.get_caps ();
-
-        var sink = this.pipeline.get_by_name (HTTPGstSink.NAME);
-        Pad sink_pad;
-
-        dynamic Element depay = GstUtils.get_rtp_depayloader (caps);
-        if (depay != null) {
-            this.pipeline.add (depay);
-            if (!depay.link (sink)) {
-                critical (_("Failed to link %s to %s"),
-                          depay.name,
-                          sink.name);
-                this.end (false, KnownStatusCode.NONE);
-                return;
-            }
-
-            sink_pad = depay.get_compatible_pad (src_pad, caps);
-        } else {
-            sink_pad = sink.get_compatible_pad (src_pad, caps);
-        }
-
-        if (src_pad.link (sink_pad) != PadLinkReturn.OK) {
-            critical (_("Failed to link pad %s to %s"),
-                      src_pad.name,
-                      sink_pad.name);
-            this.end (false, KnownStatusCode.NONE);
-            return;
-        }
-
-        if (depay != null) {
-            depay.sync_state_with_parent ();
-        }
-    }
-
-    private bool bus_handler (Gst.Bus     bus,
-                              Gst.Message message) {
-        bool ret = true;
-
-        if (message.type == MessageType.EOS) {
-            ret = false;
-        } else if (message.type == MessageType.STATE_CHANGED) {
-            if (message.src != this.pipeline) {
-                return true;
-            }
-
-            if (this.seek != null && this.seek.start > 0) {
-                State old_state;
-                State new_state;
-
-                message.parse_state_changed (out old_state,
-                                             out new_state,
-                                             null);
-
-                if (old_state == State.READY && new_state == State.PAUSED) {
-                    if (this.perform_seek ()) {
-                        this.pipeline.set_state (State.PLAYING);
-                    }
-                }
-            }
-        } else {
-            GLib.Error err;
-            string err_msg;
-
-            if (message.type == MessageType.ERROR) {
-                message.parse_error (out err, out err_msg);
-                critical (_("Error from pipeline %s: %s"),
-                          this.pipeline.name,
-                          err_msg);
-
-                ret = false;
-            } else if (message.type == MessageType.WARNING) {
-                message.parse_warning (out err, out err_msg);
-                warning (_("Warning from pipeline %s: %s"),
-                         this.pipeline.name,
-                         err_msg);
-            }
-        }
-
-        if (!ret) {
-                Idle.add_full (this.priority, () => {
-                    this.end (false, KnownStatusCode.NONE);
-
-                    return false;
-                });
-        }
-
-        return ret;
-    }
-
-    private bool perform_seek () {
-        var stop_type = Gst.SeekType.NONE;
-        Format format;
-
-        if (this.seek is HTTPTimeSeek) {
-            format = Format.TIME;
-
-            if (this.seek.stop > 0) {
-                stop_type = Gst.SeekType.SET;
-            }
-        } else {
-            format = Format.BYTES;
-        }
-
-        if (!this.pipeline.seek (1.0,
-                                 format,
-                                 SeekFlags.FLUSH | SeekFlags.ACCURATE,
-                                 Gst.SeekType.SET,
-                                 this.seek.start,
-                                 stop_type,
-                                 this.seek.stop)) {
-            warning (_("Failed to seek to offset %lld"), this.seek.start);
-
-            this.end (false, KnownStatusCode.REQUESTED_RANGE_NOT_SATISFIABLE);
-
-            return false;
-        }
-
-        return true;
-    }
-}
-
index f70fc98..330f88f 100644 (file)
@@ -32,7 +32,7 @@ internal class Rygel.HTTPGstSink : BaseSink {
 
     public Cancellable cancellable;
 
-    private unowned HTTPGstResponse response;
+    private unowned HTTPResponse response;
     private int priority;
 
     private int64 chunks_buffered;
@@ -51,7 +51,7 @@ internal class Rygel.HTTPGstSink : BaseSink {
         add_pad_template (template);
     }
 
-    public HTTPGstSink (HTTPGstResponse response) {
+    public HTTPGstSink (HTTPResponse response) {
         this.chunks_buffered = 0;
         this.bytes_sent = 0;
         this.max_bytes = int64.MAX;
index cd28b73..00dc465 100644 (file)
@@ -88,6 +88,6 @@ internal class Rygel.HTTPIdentityHandler : Rygel.HTTPGetHandler {
             throw new HTTPRequestError.NOT_FOUND (_("Not found"));
         }
 
-        return new HTTPGstResponse (request, this, src);
+        return new HTTPResponse (request, this, src);
     }
 }
index 28bf86c..98a4026 100644 (file)
  */
 
 using Gst;
+using Soup;
 
-internal abstract class Rygel.HTTPResponse : GLib.Object, Rygel.StateMachine {
+internal class Rygel.HTTPResponse : GLib.Object, Rygel.StateMachine {
     public Soup.Server server { get; private set; }
     public Soup.Message msg;
 
     public Cancellable cancellable { get; set; }
 
-    protected SourceFunc run_continue;
+    public HTTPSeek seek;
+
+    private SourceFunc run_continue;
     private int _priority = -1;
     public int priority {
         get {
@@ -54,30 +57,49 @@ internal abstract class Rygel.HTTPResponse : GLib.Object, Rygel.StateMachine {
         }
     }
 
+    private Pipeline pipeline;
+    private uint bus_watch_id;
+
     public HTTPResponse (HTTPGet        request,
                          HTTPGetHandler request_handler,
-                         bool           partial) throws Error {
+                         Element        src) throws Error {
         this.server = request.server;
         this.msg = request.msg;
         this.cancellable = request_handler.cancellable;
+        this.seek = request.seek;
 
-        if (partial) {
+        if (this.seek != null && this.seek.length < this.seek.total_length) {
             this.msg.set_status (Soup.KnownStatusCode.PARTIAL_CONTENT);
         } else {
             this.msg.set_status (Soup.KnownStatusCode.OK);
         }
 
-        this.msg.response_body.set_accumulate (false);
+        if (this.seek != null && this.seek is HTTPByteSeek) {
+            this.msg.response_headers.set_encoding (Encoding.CONTENT_LENGTH);
+        } else {
+            this.msg.response_headers.set_encoding (Encoding.EOF);
+        }
 
         if (this.cancellable != null) {
             this.cancellable.cancelled.connect (this.on_cancelled);
         }
+
+        this.msg.response_body.set_accumulate (false);
+
+        this.prepare_pipeline ("RygelHTTPGstResponse", src);
     }
 
-    public abstract async void run ();
+    public async void run () {
+        // Only bother attempting to seek if the offset is greater than zero.
+        if (this.seek != null && this.seek.start > 0) {
+            this.pipeline.set_state (State.PAUSED);
+        } else {
+            this.pipeline.set_state (State.PLAYING);
+        }
+
+        this.run_continue = run.callback;
 
-    private void on_cancelled (Cancellable cancellable) {
-        this.end (true, Soup.KnownStatusCode.CANCELLED);
+        yield;
     }
 
     public void push_data (uint8[] data) {
@@ -87,6 +109,19 @@ internal abstract class Rygel.HTTPResponse : GLib.Object, Rygel.StateMachine {
     }
 
     public virtual void end (bool aborted, uint status) {
+        var sink = this.pipeline.get_by_name (HTTPGstSink.NAME) as HTTPGstSink;
+        sink.cancellable.cancel ();
+
+        this.pipeline.set_state (State.NULL);
+        Source.remove (this.bus_watch_id);
+
+        var encoding = this.msg.response_headers.get_encoding ();
+
+        if (!aborted && encoding != Encoding.CONTENT_LENGTH) {
+            this.msg.response_body.complete ();
+            this.server.unpause_message (this.msg);
+        }
+
         if (this.run_continue != null) {
             this.run_continue ();
         }
@@ -97,4 +132,156 @@ internal abstract class Rygel.HTTPResponse : GLib.Object, Rygel.StateMachine {
 
         this.completed ();
     }
+
+    private void on_cancelled (Cancellable cancellable) {
+        this.end (true, Soup.KnownStatusCode.CANCELLED);
+    }
+
+    private void prepare_pipeline (string name,
+                                   Element src) throws Error {
+        var sink = new HTTPGstSink (this);
+
+        this.pipeline = new Pipeline (name);
+        assert (this.pipeline != null);
+
+        this.pipeline.add_many (src, sink);
+
+        if (src.numpads == 0) {
+            // Seems source uses dynamic pads, link when pad available
+            src.pad_added.connect (this.src_pad_added);
+        } else {
+            // static pads? easy!
+            if (!src.link (sink)) {
+                throw new GstError.LINK (_("Failed to link %s to %s"),
+                                         src.name,
+                                         sink.name);
+            }
+        }
+
+        // Bus handler
+        var bus = this.pipeline.get_bus ();
+        this.bus_watch_id = bus.add_watch (this.bus_handler);
+    }
+
+    private void src_pad_added (Element src,
+                                Pad     src_pad) {
+        var caps = src_pad.get_caps ();
+
+        var sink = this.pipeline.get_by_name (HTTPGstSink.NAME);
+        Pad sink_pad;
+
+        dynamic Element depay = GstUtils.get_rtp_depayloader (caps);
+        if (depay != null) {
+            this.pipeline.add (depay);
+            if (!depay.link (sink)) {
+                critical (_("Failed to link %s to %s"),
+                          depay.name,
+                          sink.name);
+                this.end (false, KnownStatusCode.NONE);
+                return;
+            }
+
+            sink_pad = depay.get_compatible_pad (src_pad, caps);
+        } else {
+            sink_pad = sink.get_compatible_pad (src_pad, caps);
+        }
+
+        if (src_pad.link (sink_pad) != PadLinkReturn.OK) {
+            critical (_("Failed to link pad %s to %s"),
+                      src_pad.name,
+                      sink_pad.name);
+            this.end (false, KnownStatusCode.NONE);
+            return;
+        }
+
+        if (depay != null) {
+            depay.sync_state_with_parent ();
+        }
+    }
+
+    private bool bus_handler (Gst.Bus     bus,
+                              Gst.Message message) {
+        bool ret = true;
+
+        if (message.type == MessageType.EOS) {
+            ret = false;
+        } else if (message.type == MessageType.STATE_CHANGED) {
+            if (message.src != this.pipeline) {
+                return true;
+            }
+
+            if (this.seek != null && this.seek.start > 0) {
+                State old_state;
+                State new_state;
+
+                message.parse_state_changed (out old_state,
+                                             out new_state,
+                                             null);
+
+                if (old_state == State.READY && new_state == State.PAUSED) {
+                    if (this.perform_seek ()) {
+                        this.pipeline.set_state (State.PLAYING);
+                    }
+                }
+            }
+        } else {
+            GLib.Error err;
+            string err_msg;
+
+            if (message.type == MessageType.ERROR) {
+                message.parse_error (out err, out err_msg);
+                critical (_("Error from pipeline %s: %s"),
+                          this.pipeline.name,
+                          err_msg);
+
+                ret = false;
+            } else if (message.type == MessageType.WARNING) {
+                message.parse_warning (out err, out err_msg);
+                warning (_("Warning from pipeline %s: %s"),
+                         this.pipeline.name,
+                         err_msg);
+            }
+        }
+
+        if (!ret) {
+                Idle.add_full (this.priority, () => {
+                    this.end (false, KnownStatusCode.NONE);
+
+                    return false;
+                });
+        }
+
+        return ret;
+    }
+
+    private bool perform_seek () {
+        var stop_type = Gst.SeekType.NONE;
+        Format format;
+
+        if (this.seek is HTTPTimeSeek) {
+            format = Format.TIME;
+
+            if (this.seek.stop > 0) {
+                stop_type = Gst.SeekType.SET;
+            }
+        } else {
+            format = Format.BYTES;
+        }
+
+        if (!this.pipeline.seek (1.0,
+                                 format,
+                                 SeekFlags.FLUSH | SeekFlags.ACCURATE,
+                                 Gst.SeekType.SET,
+                                 this.seek.start,
+                                 stop_type,
+                                 this.seek.stop)) {
+            warning (_("Failed to seek to offset %lld"), this.seek.start);
+
+            this.end (false, KnownStatusCode.REQUESTED_RANGE_NOT_SATISFIABLE);
+
+            return false;
+        }
+
+        return true;
+    }
 }
index 1478879..b1122fc 100644 (file)
@@ -59,7 +59,7 @@ internal class Rygel.HTTPTranscodeHandler : HTTPGetHandler {
         try {
             src = this.transcoder.create_source (item, src);
 
-            return new HTTPGstResponse (request, this, src);
+            return new HTTPResponse (request, this, src);
         } catch (GLib.Error err) {
             throw new HTTPRequestError.NOT_FOUND (err.message);
         }
index 6fa71e7..e01705e 100644 (file)
@@ -26,7 +26,7 @@ AM_VALAFLAGS = --disable-warnings --thread \
                --pkg gio-2.0 --pkg gee-1.0 -g
 
 check_PROGRAMS = rygel-http-item-uri-test \
-                rygel-http-gst-response-test \
+                rygel-http-response-test \
                 rygel-http-byte-seek-test \
                 rygel-http-time-seek-test \
                 rygel-http-get-test \
@@ -38,11 +38,9 @@ TESTS = $(check_PROGRAMS)
 rygel_http_item_uri_test_SOURCES = rygel-http-item-uri-test.vala \
                                    rygel-http-item-uri.vala
 
-rygel_http_gst_response_test_SOURCES = rygel-http-gst-response-test.vala \
-                                  rygel-http-gst-response.vala \
-                                   rygel-http-response_gst-response.vala \
-                                   rygel-http-response-test_gst-response.vala \
-                                  rygel-state-machine_gst-response.vala \
+rygel_http_response_test_SOURCES = rygel-http-response-test.vala \
+                                  rygel-http-response.vala \
+                                  rygel-state-machine_http-response.vala \
                                   rygel-http-gst-sink.vala \
                                   rygel-gst-utils.vala
 
diff --git a/tests/rygel-http-gst-response-test.vala b/tests/rygel-http-gst-response-test.vala
deleted file mode 100644 (file)
index 16137eb..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2010 Nokia Corporation.
- *
- * Author: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
- *                               <zeeshan.ali@nokia.com>
- *
- * This file is part of Rygel.
- *
- * Rygel is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Rygel is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-using Soup;
-using Gst;
-
-public class Rygel.HTTPGstResponseTest : Rygel.HTTPResponseTest {
-    private MediaItem item;
-
-    public static int main (string[] args) {
-        Gst.init (ref args);
-
-        try {
-            var test = new HTTPGstResponseTest.complete ();
-            test.run ();
-
-            test = new HTTPGstResponseTest.abort ();
-            test.run ();
-        } catch (TestError.SKIP error) {
-            return error.code;
-        } catch (Error error) {
-            critical ("%s", error.message);
-
-            return -1;
-        }
-
-        return 0;
-    }
-
-    private HTTPGstResponseTest.complete () throws Error {
-        base.complete ();
-
-        this.item = new MediaItem.fixed_size ();
-    }
-
-    private HTTPGstResponseTest.abort () throws Error {
-        base.abort ();
-
-        this.item = new MediaItem ();
-    }
-
-    internal override HTTPResponse create_response (Soup.Message msg)
-                                                     throws Error {
-        var seek = null as HTTPSeek;
-
-        if (!this.item.is_live_stream ()) {
-            seek = new HTTPByteSeek (0,
-                                     HTTPResponseTest.MAX_BYTES - 1,
-                                     this.item.size);
-            msg.response_headers.set_content_length (seek.length);
-        }
-
-        var request = new HTTPGet (this.server.context.server,
-                                   msg,
-                                   this.item,
-                                   seek,
-                                   this.cancellable);
-        var handler = new HTTPGetHandler (this.cancellable);
-        var src = this.item.create_stream_source ();
-
-        return new HTTPGstResponse (request, handler, src);
-    }
-}
-
-public class Rygel.HTTPGet : GLib.Object {
-    public Soup.Server server;
-    public Soup.Message msg;
-
-    public Cancellable cancellable;
-
-    public MediaItem item;
-
-    internal HTTPSeek seek;
-
-    public HTTPGet (Soup.Server  server,
-                    Soup.Message msg,
-                    MediaItem    item,
-                    HTTPSeek?    seek,
-                    Cancellable? cancellable) {
-        this.server = server;
-        this.msg = msg;
-        this.item = item;
-        this.seek = seek;
-        this.cancellable = cancellable;
-    }
-}
-
-public class Rygel.HTTPGetHandler : GLib.Object {
-    public Cancellable cancellable;
-
-    public HTTPGetHandler (Cancellable? cancellable) {
-        this.cancellable = cancellable;
-    }
-}
-
-public class Rygel.MediaItem {
-    private static const long BLOCK_SIZE = HTTPResponseTest.MAX_BYTES / 16 + 1;
-    private static const long MAX_BUFFERS = 25;
-
-    public int64 size {
-        get {
-            return MAX_BUFFERS * BLOCK_SIZE;
-        }
-    }
-
-    private dynamic Element src;
-
-    public MediaItem () {
-        this.src = GstUtils.create_element ("fakesrc", null);
-        this.src.sizetype = 2; // fixed
-    }
-
-    public MediaItem.fixed_size () {
-        this ();
-
-        this.src.blocksize = BLOCK_SIZE;
-        this.src.num_buffers = MAX_BUFFERS;
-        this.src.sizemax = MAX_BUFFERS * BLOCK_SIZE;
-    }
-
-    public Element? create_stream_source () {
-        return this.src;
-    }
-
-    public bool is_live_stream () {
-        return ((int) this.src.num_buffers) < 0;
-    }
-}
-
-internal class Rygel.HTTPByteSeek : Rygel.HTTPSeek {
-    public HTTPByteSeek (int64 start, int64 stop, int64 total_length) {
-        base (start, stop, total_length);
-    }
-}
-
-internal class Rygel.HTTPTimeSeek : Rygel.HTTPSeek {
-    public HTTPTimeSeek (int64 start, int64 stop, int64 total_length) {
-        base (start, stop, total_length);
-    }
-}
-
-public errordomain Rygel.HTTPRequestError {
-    NOT_FOUND = Soup.KnownStatusCode.NOT_FOUND
-}
diff --git a/tests/rygel-http-gst-response.vala b/tests/rygel-http-gst-response.vala
deleted file mode 120000 (symlink)
index 77ea668..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../src/rygel/rygel-http-gst-response.vala
\ No newline at end of file
index c3e6d8b..0a8e50a 100644 (file)
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
-// This module contains the common code between the test cases for
-// HTTPResponse subclasses.
 using Soup;
+using Gst;
 
 public errordomain Rygel.TestError {
     SKIP = 77,
     TIMEOUT
 }
 
-public abstract class Rygel.HTTPResponseTest : GLib.Object {
+public errordomain Rygel.HTTPRequestError {
+    NOT_FOUND = Soup.KnownStatusCode.NOT_FOUND
+}
+
+public class Rygel.HTTPResponseTest : GLib.Object {
     public const long MAX_BYTES = 102400;
 
     protected HTTPServer server;
@@ -39,11 +42,33 @@ public abstract class Rygel.HTTPResponseTest : GLib.Object {
     private bool server_done;
     private bool client_done;
 
+    private MediaItem item;
+
     private MainLoop main_loop;
 
     protected Cancellable cancellable;
     private Error error;
 
+    public static int main (string[] args) {
+        Gst.init (ref args);
+
+        try {
+            var test = new HTTPResponseTest.complete ();
+            test.run ();
+
+            test = new HTTPResponseTest.abort ();
+            test.run ();
+        } catch (TestError.SKIP error) {
+            return error.code;
+        } catch (Error error) {
+            critical ("%s", error.message);
+
+            return -1;
+        }
+
+        return 0;
+    }
+
     public HTTPResponseTest (Cancellable? cancellable = null) throws Error {
         this.cancellable = cancellable;
 
@@ -57,10 +82,14 @@ public abstract class Rygel.HTTPResponseTest : GLib.Object {
 
     public HTTPResponseTest.complete () throws Error {
         this ();
+
+        this.item = new MediaItem.fixed_size ();
     }
 
     public HTTPResponseTest.abort () throws Error {
         this (new Cancellable ());
+
+        this.item = new MediaItem ();
     }
 
     public virtual void run () throws Error {
@@ -82,8 +111,24 @@ public abstract class Rygel.HTTPResponseTest : GLib.Object {
         }
     }
 
-    internal abstract HTTPResponse create_response (Soup.Message msg)
-                                                    throws Error;
+    private HTTPResponse create_response (Soup.Message msg) throws Error {
+        var seek = null as HTTPSeek;
+
+        if (!this.item.is_live_stream ()) {
+            seek = new HTTPByteSeek (0, MAX_BYTES - 1, this.item.size);
+            msg.response_headers.set_content_length (seek.length);
+        }
+
+        var request = new HTTPGet (this.server.context.server,
+                                   msg,
+                                   this.item,
+                                   seek,
+                                   this.cancellable);
+        var handler = new HTTPGetHandler (this.cancellable);
+        var src = this.item.create_stream_source ();
+
+        return new HTTPResponse (request, handler, src);
+    }
 
     private void on_client_completed (StateMachine client) {
         if (this.server_done) {
@@ -247,3 +292,80 @@ public class Rygel.HTTPSeek : GLib.Object {
         this.length = stop - start + 1;
     }
 }
+
+public class Rygel.HTTPByteSeek : Rygel.HTTPSeek {
+    public HTTPByteSeek (int64 start, int64 stop, int64 total_length) {
+        base (start, stop, total_length);
+    }
+}
+
+public class Rygel.HTTPTimeSeek : Rygel.HTTPSeek {
+    public HTTPTimeSeek (int64 start, int64 stop, int64 total_length) {
+        base (start, stop, total_length);
+    }
+}
+
+public class Rygel.HTTPGet : GLib.Object {
+    public Soup.Server server;
+    public Soup.Message msg;
+
+    public Cancellable cancellable;
+
+    public MediaItem item;
+
+    internal HTTPSeek seek;
+
+    public HTTPGet (Soup.Server  server,
+                    Soup.Message msg,
+                    MediaItem    item,
+                    HTTPSeek?    seek,
+                    Cancellable? cancellable) {
+        this.server = server;
+        this.msg = msg;
+        this.item = item;
+        this.seek = seek;
+        this.cancellable = cancellable;
+    }
+}
+
+public class Rygel.HTTPGetHandler : GLib.Object {
+    public Cancellable cancellable;
+
+    public HTTPGetHandler (Cancellable? cancellable) {
+        this.cancellable = cancellable;
+    }
+}
+
+public class Rygel.MediaItem {
+    private static const long BLOCK_SIZE = HTTPResponseTest.MAX_BYTES / 16 + 1;
+    private static const long MAX_BUFFERS = 25;
+
+    public int64 size {
+        get {
+            return MAX_BUFFERS * BLOCK_SIZE;
+        }
+    }
+
+    private dynamic Element src;
+
+    public MediaItem () {
+        this.src = GstUtils.create_element ("fakesrc", null);
+        this.src.sizetype = 2; // fixed
+    }
+
+    public MediaItem.fixed_size () {
+        this ();
+
+        this.src.blocksize = BLOCK_SIZE;
+        this.src.num_buffers = MAX_BUFFERS;
+        this.src.sizemax = MAX_BUFFERS * BLOCK_SIZE;
+    }
+
+    public Element? create_stream_source () {
+        return this.src;
+    }
+
+    public bool is_live_stream () {
+        return ((int) this.src.num_buffers) < 0;
+    }
+}
diff --git a/tests/rygel-http-response-test_gst-response.vala b/tests/rygel-http-response-test_gst-response.vala
deleted file mode 120000 (symlink)
index 0cb230f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-rygel-http-response-test.vala
\ No newline at end of file