/* * Copyright (C) 2010 Nokia Corporation. * * Author: Zeeshan Ali (Khattak) * * * 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.1 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ private errordomain Rygel.TestError { SKIP } private class Rygel.HTTPIdentityHandler : GLib.Object {} private class Rygel.HTTPSubtitleHandler : GLib.Object {} private class Rygel.HTTPThumbnailHandler : GLib.Object {} public class Rygel.MediaObject : GLib.Object { public int64 size = 2048; } private class Rygel.MediaFileItem : MediaObject { } private class Rygel.Thumbnail : GLib.Object { public int64 size = 1024; } private class Rygel.Subtitle : GLib.Object { public int64 size = 512; } public class Rygel.MediaContainer : MediaObject { } public class Rygel.ClientHacks : GLib.Object { public static ClientHacks create (Soup.Message msg) throws Error { return new ClientHacks (); } public bool force_seek () { return false; } } private class Rygel.HTTPGet : GLib.Object { public const string ITEM_URI = "http://DoesntMatterWhatThisIs"; public Soup.Message msg; public MediaObject object; public Thumbnail thumbnail; public Subtitle subtitle; public HTTPIdentityHandler handler; public HTTPGet (Thumbnail? thumbnail, Subtitle? subtitle) { this.msg = new Soup.Message ("HTTP", ITEM_URI); this.object = new MediaFileItem (); this.handler = new HTTPIdentityHandler (); this.thumbnail = thumbnail; this.subtitle = subtitle; } public HTTPGet.seek_start (int64 start, Thumbnail? thumbnail, Subtitle? subtitle) { this (thumbnail, subtitle); this.add_headers (start, -1); } public HTTPGet.seek_stop (int64 stop, Thumbnail? thumbnail, Subtitle? subtitle) { this (thumbnail, subtitle); this.add_headers (0, stop); } public HTTPGet.seek_start_stop (int64 start, int64 stop, Thumbnail? thumbnail, Subtitle? subtitle) { this (thumbnail, subtitle); this.add_headers (start, stop); } public HTTPGet.inverted_range () { this (null, null); this.msg.request_headers.append ("Range", "bytes=34-0"); } public HTTPGet.invalid_range () { this (null, null); this.msg.request_headers.append ("Range", "bytes=a-b"); } private void add_headers (int64 start, int64 stop) { this.msg.request_headers.set_range (start, stop); } } private class Rygel.HTTPByteSeekTest : GLib.Object { private Regex range_regex; public static int main (string[] args) { try { var test = new HTTPByteSeekTest (); test.run (); /* TODO: Nothing throws this exception. Should it? } catch (TestError.SKIP error) { return 77; */ } catch (Error error) { critical ("%s", error.message); return -1; } return 0; } public void run () throws HTTPSeekError { var thumbnails = new Thumbnail[] { null, new Thumbnail () }; var subtitles = new Subtitle[] { null, new Subtitle () }; foreach (var thumbnail in thumbnails) { foreach (var subtitle in subtitles) { this.test_no_seek (thumbnail, subtitle); this.test_start_only_seek (thumbnail, subtitle); this.test_stop_only_seek (thumbnail, subtitle); this.test_start_stop_seek (thumbnail, subtitle); } } try { new HTTPByteSeek (new HTTPGet.inverted_range ()); assert_not_reached (); } catch (HTTPSeekError error) {} try { new HTTPByteSeek (new HTTPGet.invalid_range ()); assert_not_reached (); } catch (HTTPSeekError error) {} } private HTTPByteSeekTest () { try { this.range_regex = new Regex ("bytes +[0-9]+-[0-9]+/[0-9]+", RegexCompileFlags.CASELESS); } catch (RegexError error) { // This means that it is not a regular expression assert_not_reached (); } } private void test_no_seek (Thumbnail? thumbnail, Subtitle? subtitle) throws HTTPSeekError { var request = new HTTPGet (thumbnail, subtitle); int64 size; if (request.thumbnail != null) { size = request.thumbnail.size; } else if (request.subtitle != null) { size = request.subtitle.size; } else { size = request.object.size; } this.test_seek (request, 0, size - 1); } private void test_start_only_seek (Thumbnail? thumbnail, Subtitle? subtitle) throws HTTPSeekError { var request = new HTTPGet.seek_start (128, thumbnail, subtitle); int64 size; if (request.thumbnail != null) { size = request.thumbnail.size; } else if (request.subtitle != null) { size = request.subtitle.size; } else { size = request.object.size; } this.test_seek (request, 128, size - 1); } private void test_stop_only_seek (Thumbnail? thumbnail, Subtitle? subtitle) throws HTTPSeekError { var request = new HTTPGet.seek_stop (128, thumbnail, subtitle); this.test_seek (request, 0, 128); } private void test_start_stop_seek (Thumbnail? thumbnail, Subtitle? subtitle) throws HTTPSeekError { var request = new HTTPGet.seek_start_stop (128, 256, thumbnail, subtitle); this.test_seek (request, 128, 256); } private void test_seek (HTTPGet request, int64 start, int64 stop) throws HTTPSeekError { assert (HTTPByteSeek.needed (request)); var seek = new HTTPByteSeek (request); seek.add_response_headers (); assert (seek != null); assert (seek.start == start); assert (seek.stop == stop); if (request.thumbnail != null) { assert (seek.total_length == request.thumbnail.size); } else if (request.subtitle != null) { assert (seek.total_length == request.subtitle.size); } else { assert (seek.total_length == request.object.size); } if (request.msg.request_headers.get_one ("Range") != null) { var header = request.msg.response_headers.get_one ("Accept-Ranges"); assert (header == "bytes"); header = request.msg.response_headers.get_one ("Content-Range"); assert (header != null); assert (this.range_regex.match (header)); } assert (request.msg.response_headers.get_content_length () == seek.length); /* TODO: This is just here to avoid a warning about * requested() not being used. * How should this really be tested? * Sometimes the result here is true, and sometimes it is false. */ /* bool result = */ HTTPByteSeek.requested(request); } }