diff options
author | Zeeshan Ali (Khattak) <zeeshanak@gnome.org> | 2011-04-09 03:27:27 +0300 |
---|---|---|
committer | Zeeshan Ali (Khattak) <zeeshanak@gnome.org> | 2011-04-09 04:44:57 +0300 |
commit | f3ce150d16d03f865792bf849b2c5c1cfc695484 (patch) | |
tree | 4467d40ecf5f3359c8da11965057d48e2eeb0d5b | |
parent | cfeed62ff2028eb892382f8833fa89cc8817eb39 (diff) | |
download | rygel-f3ce150d16d03f865792bf849b2c5c1cfc695484.tar.gz |
core,tests: Merge GstResponse into HTTPResponse
-rw-r--r-- | po/POTFILES.in | 1 | ||||
-rw-r--r-- | po/POTFILES.skip | 4 | ||||
-rw-r--r-- | src/rygel/Makefile.am | 1 | ||||
-rw-r--r-- | src/rygel/rygel-http-gst-response.vala | 230 | ||||
-rw-r--r-- | src/rygel/rygel-http-gst-sink.vala | 4 | ||||
-rw-r--r-- | src/rygel/rygel-http-identity-handler.vala | 2 | ||||
-rw-r--r-- | src/rygel/rygel-http-response.vala | 203 | ||||
-rw-r--r-- | src/rygel/rygel-http-transcode-handler.vala | 2 | ||||
-rw-r--r-- | tests/Makefile.am | 10 | ||||
-rw-r--r-- | tests/rygel-http-gst-response-test.vala | 164 | ||||
l--------- | tests/rygel-http-gst-response.vala | 1 | ||||
-rw-r--r-- | tests/rygel-http-response-test.vala | 132 | ||||
l--------- | tests/rygel-http-response-test_gst-response.vala | 1 | ||||
l--------- | tests/rygel-http-response.vala (renamed from tests/rygel-http-response_gst-response.vala) | 0 | ||||
l--------- | tests/rygel-state-machine_http-response.vala (renamed from tests/rygel-state-machine_gst-response.vala) | 0 |
15 files changed, 332 insertions, 423 deletions
diff --git a/po/POTFILES.in b/po/POTFILES.in index 34ab9e1e..d7fec05e 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -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 diff --git a/po/POTFILES.skip b/po/POTFILES.skip index 4730ba26..1cac0034 100644 --- a/po/POTFILES.skip +++ b/po/POTFILES.skip @@ -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 diff --git a/src/rygel/Makefile.am b/src/rygel/Makefile.am index 32d1b781..73c7c697 100644 --- a/src/rygel/Makefile.am +++ b/src/rygel/Makefile.am @@ -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 index c204842b..00000000 --- a/src/rygel/rygel-http-gst-response.vala +++ /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; - } -} - diff --git a/src/rygel/rygel-http-gst-sink.vala b/src/rygel/rygel-http-gst-sink.vala index f70fc98f..330f88f2 100644 --- a/src/rygel/rygel-http-gst-sink.vala +++ b/src/rygel/rygel-http-gst-sink.vala @@ -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; diff --git a/src/rygel/rygel-http-identity-handler.vala b/src/rygel/rygel-http-identity-handler.vala index cd28b735..00dc4654 100644 --- a/src/rygel/rygel-http-identity-handler.vala +++ b/src/rygel/rygel-http-identity-handler.vala @@ -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); } } diff --git a/src/rygel/rygel-http-response.vala b/src/rygel/rygel-http-response.vala index 28bf86c2..98a4026e 100644 --- a/src/rygel/rygel-http-response.vala +++ b/src/rygel/rygel-http-response.vala @@ -22,14 +22,17 @@ */ 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; + } } diff --git a/src/rygel/rygel-http-transcode-handler.vala b/src/rygel/rygel-http-transcode-handler.vala index 14788791..b1122fc0 100644 --- a/src/rygel/rygel-http-transcode-handler.vala +++ b/src/rygel/rygel-http-transcode-handler.vala @@ -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); } diff --git a/tests/Makefile.am b/tests/Makefile.am index 6fa71e7d..e01705eb 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -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 index 16137ebb..00000000 --- a/tests/rygel-http-gst-response-test.vala +++ /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 index 77ea6688..00000000 --- a/tests/rygel-http-gst-response.vala +++ /dev/null @@ -1 +0,0 @@ -../src/rygel/rygel-http-gst-response.vala
\ No newline at end of file diff --git a/tests/rygel-http-response-test.vala b/tests/rygel-http-response-test.vala index c3e6d8b4..0a8e50a4 100644 --- a/tests/rygel-http-response-test.vala +++ b/tests/rygel-http-response-test.vala @@ -21,16 +21,19 @@ * 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 index 0cb230fa..00000000 --- a/tests/rygel-http-response-test_gst-response.vala +++ /dev/null @@ -1 +0,0 @@ -rygel-http-response-test.vala
\ No newline at end of file diff --git a/tests/rygel-http-response_gst-response.vala b/tests/rygel-http-response.vala index e23cfdf1..e23cfdf1 120000 --- a/tests/rygel-http-response_gst-response.vala +++ b/tests/rygel-http-response.vala diff --git a/tests/rygel-state-machine_gst-response.vala b/tests/rygel-state-machine_http-response.vala index 5063d685..5063d685 120000 --- a/tests/rygel-state-machine_gst-response.vala +++ b/tests/rygel-state-machine_http-response.vala |