[rygel] server: Refactor transferMode handling
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rygel] server: Refactor transferMode handling
- Date: Sun, 8 Feb 2015 13:25:48 +0000 (UTC)
commit 2970c0f22938167a4e6d516205edf19900474158
Author: Jens Georg <mail jensge org>
Date: Mon Jan 19 08:45:41 2015 +0100
server: Refactor transferMode handling
Based on Cablelabs's CVP-2 implementation.
src/librygel-server/rygel-audio-item.vala | 1 +
src/librygel-server/rygel-http-get-handler.vala | 36 +++++++++++++---
src/librygel-server/rygel-http-get.vala | 44 +++++--------------
.../rygel-http-identity-handler.vala | 4 ++
.../rygel-http-resource-handler.vala | 10 ++++
.../rygel-http-transcode-handler.vala | 9 ++++
src/librygel-server/rygel-video-item.vala | 14 ------
7 files changed, 65 insertions(+), 53 deletions(-)
---
diff --git a/src/librygel-server/rygel-audio-item.vala b/src/librygel-server/rygel-audio-item.vala
index ec9b4c7..0495ecc 100644
--- a/src/librygel-server/rygel-audio-item.vala
+++ b/src/librygel-server/rygel-audio-item.vala
@@ -120,6 +120,7 @@ public class Rygel.AudioItem : MediaFileItem {
res.sample_freq = this.sample_freq;
res.bits_per_sample = this.bits_per_sample;
res.audio_channels = this.channels;
+ res.dlna_flags |= DLNAFlags.STREAMING_TRANSFER_MODE;
return res;
}
diff --git a/src/librygel-server/rygel-http-get-handler.vala b/src/librygel-server/rygel-http-get-handler.vala
index 2d88881..c61b346 100644
--- a/src/librygel-server/rygel-http-get-handler.vala
+++ b/src/librygel-server/rygel-http-get-handler.vala
@@ -28,20 +28,21 @@ using GUPnP;
* HTTP GET request handler interface.
*/
internal abstract class Rygel.HTTPGetHandler: GLib.Object {
- private const string TRANSFER_MODE_HEADER = "transferMode.dlna.org";
+ protected const string TRANSFER_MODE_HEADER = "transferMode.dlna.org";
+
+ protected const string TRANSFER_MODE_STREAMING = "Streaming";
+ protected const string TRANSFER_MODE_INTERACTIVE = "Interactive";
+ protected const string TRANSFER_MODE_BACKGROUND = "Background";
public Cancellable cancellable { get; set; }
// Add response headers.
+ /**
+ * Invokes the handler to add response headers to/for the given HTTP request
+ */
public virtual void add_response_headers (HTTPGet request)
throws HTTPRequestError {
var mode = request.msg.request_headers.get_one (TRANSFER_MODE_HEADER);
- if (mode != null) {
- // FIXME: Is it OK to just copy the value of this header from
- // request to response? All we do to entertain this header is to
- // set the priority of IO operations.
- request.msg.response_headers.append (TRANSFER_MODE_HEADER, mode);
- }
// Yes, I know this is not the ideal code to just get a specific
// string for an HTTP header but if you think you can come-up with
@@ -61,6 +62,14 @@ internal abstract class Rygel.HTTPGetHandler: GLib.Object {
warning ("Received request for 'contentFeatures.dlna.org' but " +
"failed to provide the value in response headers");
}
+ // Per DLNA 7.5.4.3.2.33.2, if the transferMode header is empty it
+ // must be treated as Streaming mode or Interactive, depending upon the content
+ if (mode == null) {
+ request.msg.response_headers.append (TRANSFER_MODE_HEADER,
+ this.get_default_transfer_mode ());
+ } else {
+ request.msg.response_headers.append (TRANSFER_MODE_HEADER, mode);
+ }
// Handle device-specific hacks that need to change the response
// headers such as Samsung's subtitle stuff.
@@ -72,6 +81,19 @@ internal abstract class Rygel.HTTPGetHandler: GLib.Object {
}
/**
+ * Returns the default transfer mode for the handler.
+ * The default is "Interactive"
+ */
+ public virtual string get_default_transfer_mode () {
+ return TRANSFER_MODE_INTERACTIVE; // Considering this the default
+ }
+
+ /**
+ * Returns true if the handler supports the given transfer mode, false otherwise.
+ */
+ public abstract bool supports_transfer_mode (string mode);
+
+ /**
* Returns the resource size or -1 if not known.
*/
public abstract int64 get_resource_size ();
diff --git a/src/librygel-server/rygel-http-get.vala b/src/librygel-server/rygel-http-get.vala
index b3fd5b9..0e7f602 100644
--- a/src/librygel-server/rygel-http-get.vala
+++ b/src/librygel-server/rygel-http-get.vala
@@ -82,7 +82,18 @@ internal class Rygel.HTTPGet : HTTPRequest {
this.handler = new HTTPIdentityHandler (this.cancellable);
}
- this.ensure_correct_mode ();
+ { // Check the transfer mode
+ var transfer_mode = this.msg.request_headers.get_one (TRANSFER_MODE_HEADER);
+
+ if (transfer_mode == null) {
+ transfer_mode = this.handler.get_default_transfer_mode ();
+ }
+
+ if (! this.handler.supports_transfer_mode (transfer_mode)) {
+ throw new HTTPRequestError.UNACCEPTABLE ("%s transfer mode not supported for '%s'",
+ transfer_mode, uri.to_string ());
+ }
+ }
yield this.handle_item_request ();
}
@@ -234,35 +245,4 @@ internal class Rygel.HTTPGet : HTTPRequest {
this.end (Soup.Status.NONE);
}
-
- private void ensure_correct_mode () throws HTTPRequestError {
- var mode = this.msg.request_headers.get_one (TRANSFER_MODE_HEADER);
- var correct = true;
-
- switch (mode) {
- case "Streaming":
- correct = (
- (this.handler is HTTPTranscodeHandler ||
- ((this.object as MediaFileItem).streamable () &&
- this.subtitle == null &&
- this.thumbnail == null)));
-
- break;
- case "Interactive":
- correct = (this.handler is HTTPIdentityHandler &&
- ((!(this.object as MediaFileItem).is_live_stream () &&
- !(this.object as MediaFileItem).streamable ()) ||
- (this.subtitle != null ||
- this.thumbnail != null)));
-
- break;
- }
-
- if (!correct) {
- throw new HTTPRequestError.UNACCEPTABLE
- ("%s mode not supported for '%s'",
- mode,
- this.object.id);
- }
- }
}
diff --git a/src/librygel-server/rygel-http-identity-handler.vala
b/src/librygel-server/rygel-http-identity-handler.vala
index 6c8b126..383f057 100644
--- a/src/librygel-server/rygel-http-identity-handler.vala
+++ b/src/librygel-server/rygel-http-identity-handler.vala
@@ -65,6 +65,10 @@ internal class Rygel.HTTPIdentityHandler : Rygel.HTTPGetHandler {
}
}
+ public override bool supports_transfer_mode (string mode) {
+ return true;
+ }
+
public override int64 get_resource_size () {
return -1;
}
diff --git a/src/librygel-server/rygel-http-resource-handler.vala
b/src/librygel-server/rygel-http-resource-handler.vala
index b1ed7ab..eae7246 100644
--- a/src/librygel-server/rygel-http-resource-handler.vala
+++ b/src/librygel-server/rygel-http-resource-handler.vala
@@ -63,6 +63,16 @@ internal class Rygel.HTTPMediaResourceHandler : HTTPGetHandler {
base.add_response_headers (request);
}
+ public override string get_default_transfer_mode () {
+ // Per DLNA 7.5.4.3.2.33.2, the assumed transfer mode is based on the content type
+ // "Streaming" for AV content and "Interactive" for all others
+ return media_resource.get_default_transfer_mode ();
+ }
+
+ public override bool supports_transfer_mode (string mode) {
+ return media_resource.supports_transfer_mode (mode);
+ }
+
public override HTTPResponse render_body (HTTPGet request)
throws HTTPRequestError {
try {
diff --git a/src/librygel-server/rygel-http-transcode-handler.vala
b/src/librygel-server/rygel-http-transcode-handler.vala
index 94492da..bf318cd 100644
--- a/src/librygel-server/rygel-http-transcode-handler.vala
+++ b/src/librygel-server/rygel-http-transcode-handler.vala
@@ -71,6 +71,15 @@ internal class Rygel.HTTPTranscodeHandler : HTTPGetHandler {
return -1;
}
+ public override string get_default_transfer_mode () {
+ return TRANSFER_MODE_STREAMING;
+ }
+
+ public override bool supports_transfer_mode (string mode) {
+ return (mode == TRANSFER_MODE_STREAMING ||
+ mode == TRANSFER_MODE_BACKGROUND);
+ }
+
protected override DIDLLiteResource add_resource
(DIDLLiteObject didl_object,
HTTPGet request)
diff --git a/src/librygel-server/rygel-video-item.vala b/src/librygel-server/rygel-video-item.vala
index d0ca515..e59eb85 100644
--- a/src/librygel-server/rygel-video-item.vala
+++ b/src/librygel-server/rygel-video-item.vala
@@ -101,20 +101,6 @@ public class Rygel.VideoItem : AudioItem, VisualItem {
}
}
- internal override void add_resources (DIDLLiteItem didl_item,
- bool allow_internal)
- throws Error {
- foreach (var subtitle in this.subtitles) {
- var protocol = this.get_protocol_for_uri (subtitle.uri);
-
- if (allow_internal || protocol != "internal") {
- subtitle.add_didl_node (didl_item);
- }
- }
-
- base.add_resources (didl_item, allow_internal);
- }
-
internal override MediaResource get_primary_resource () {
var res = base.get_primary_resource ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]