2 * Copyright (C) 2010 Nokia Corporation.
4 * Author: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
5 * <zeeshan.ali@nokia.com>
7 * This file is part of Rygel.
9 * Rygel is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * Rygel is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27 public errordomain Rygel.TestError {
32 public class Rygel.HTTPGetTest : GLib.Object {
33 protected HTTPServer server;
34 protected HTTPClient client;
36 private bool server_done;
37 private bool client_done;
39 private MainLoop main_loop;
43 public static int main (string[] args) {
45 var test = new HTTPGetTest ();
48 } catch (TestError.SKIP error) {
50 } catch (Error error) {
51 critical ("%s", error.message);
59 public HTTPGetTest () throws Error {
60 this.server = new HTTPServer ();
61 this.client = new HTTPClient (this.server.context,
63 this.main_loop = new MainLoop (null, false);
66 public virtual void run () throws Error {
67 Timeout.add_seconds (3, this.on_timeout);
68 this.server.message_received.connect (this.on_message_received);
69 this.client.completed.connect (this.on_client_completed);
71 this.client.run.begin ();
73 this.main_loop.run ();
75 if (this.error != null) {
80 private HTTPRequest create_request (Soup.Message msg) throws Error {
81 return new HTTPGet (this.server,
82 this.server.context.server,
86 private void on_client_completed (StateMachine client) {
87 if (this.server_done) {
88 this.main_loop.quit ();
91 this.client_done = true;
94 private void on_message_received (HTTPServer server,
96 this.handle_client_message.begin (msg);
99 private async void handle_client_message (Soup.Message msg) {
101 var request = this.create_request (msg);
103 yield request.run ();
105 assert ((request as HTTPGet).item != null);
107 if (this.client_done) {
108 this.main_loop.quit ();
111 this.server_done = true;
112 } catch (Error error) {
114 this.main_loop.quit ();
120 private bool on_timeout () {
121 this.error = new TestError.TIMEOUT ("Timeout");
122 this.main_loop.quit ();
128 public class Rygel.HTTPServer : GLib.Object {
129 private const string SERVER_PATH = "/RygelHTTPServer/Rygel/Test";
130 public string path_root {
136 public MediaContainer root_container;
137 public GUPnP.Context context;
141 var item_uri = new HTTPItemURI (this.root_container.ITEM_ID,
144 return item_uri.to_string ();
148 public signal void message_received (Soup.Message message);
150 public HTTPServer () throws TestError {
152 this.context = new GUPnP.Context (null, "lo", 0);
153 } catch (Error error) {
154 throw new TestError.SKIP ("Network context not available");
157 assert (this.context != null);
158 assert (this.context.host_ip != null);
159 assert (this.context.port > 0);
161 this.context.server.add_handler (SERVER_PATH, this.server_cb);
163 this.root_container = new MediaContainer ();
166 private void server_cb (Server server,
170 ClientContext client) {
171 this.context.server.pause_message (msg);
172 this.message_received (msg);
175 public Transcoder get_transcoder (string target) throws Error {
176 return new Transcoder ();
180 public class Rygel.HTTPClient : GLib.Object, StateMachine {
181 public GUPnP.Context context;
182 public Soup.Message msg;
184 public Cancellable cancellable { get; set; }
186 public HTTPClient (GUPnP.Context context,
188 this.context = context;
190 this.msg = new Soup.Message ("GET", uri);
191 assert (this.msg != null);
194 public async void run () {
195 SourceFunc run_continue = run.callback;
197 this.context.session.queue_message (this.msg, (session, msg) => {
207 public class Rygel.MediaContainer : Rygel.MediaObject {
208 public const string ITEM_ID = "TestItem";
210 public async MediaObject? find_object (string item_id,
211 Cancellable? cancellable)
213 SourceFunc find_object_continue = find_object.callback;
215 find_object_continue ();
222 if (item_id == ITEM_ID) {
223 return new MediaItem ();
230 internal abstract class Rygel.HTTPGetHandler {
231 public HTTPResponse render_body (HTTPGet get_request) {
232 return new HTTPResponse (get_request);
235 public void add_response_headers (HTTPGet get_request) {}
238 internal class Rygel.HTTPTranscodeHandler : Rygel.HTTPGetHandler {
239 public HTTPTranscodeHandler (Transcoder transcoder,
240 Cancellable cancellable) {}
243 internal class Rygel.HTTPIdentityHandler : Rygel.HTTPGetHandler {
244 public HTTPIdentityHandler (Cancellable cancellable) {}
247 public class Rygel.MediaItem : Rygel.MediaObject {
248 public long size = 1024;
249 public long duration = 1024;
250 public ArrayList<Subtitle> subtitles = new ArrayList<Subtitle> ();
251 public ArrayList<Thumbnail> thumbnails = new ArrayList<Thumbnail> ();
253 public bool should_stream () {
258 public class Rygel.Thumbnail {
259 public long size = 1024;
262 public class Rygel.Subtitle {
263 public long size = 1024;
266 internal class Rygel.HTTPResponse : Rygel.StateMachine, GLib.Object {
267 public Cancellable cancellable { get; set; }
269 private Soup.Message msg;
270 private Soup.Server server;
272 public HTTPResponse (HTTPGet get_request) {
273 this.msg = get_request.msg;
274 this.server = get_request.server;
277 public async void run () {
278 SourceFunc run_continue = run.callback;
288 this.msg.set_status (Soup.KnownStatusCode.OK);
289 this.server.unpause_message (msg);
296 public class Rygel.Transcoder {}
297 public class Rygel.MediaObject {}