diff --git a/docs/tutorials/license-wrapping.md b/docs/tutorials/license-wrapping.md index 2b6db05bc..2dd419bb0 100644 --- a/docs/tutorials/license-wrapping.md +++ b/docs/tutorials/license-wrapping.md @@ -60,11 +60,12 @@ license request, we must register a request filter: ```js player.getNetworkingEngine().registerRequestFilter(function(type, request) { + // Alias some utilities provided by the library. + var StringUtils = shaka.util.StringUtils; + var Uint8ArrayUtils = shaka.util.Uint8ArrayUtils; + // Only manipulate license requests: if (type == shaka.net.NetworkingEngine.RequestType.LICENSE) { - // This is the raw license request generated by the Widevine CDM. - var rawLicenseRequest = new Uint8Array(request.body); - // Create the wrapped request structure. var wrapped = {}; @@ -72,7 +73,7 @@ license request, we must register a request filter: // The server we are using in this tutorial expects this field and this // encoding for the raw request. wrapped.rawLicenseRequestBase64 = - btoa(String.fromCharCode.apply(null, rawLicenseRequest)); + Uint8ArrayUtils.toBase64(new Uint8Array(request.body)); // Add whatever else we want to communicate to the server. // None of these values are read by the server we are using in this @@ -86,12 +87,9 @@ license request, we must register a request filter: // Encode the wrapped request as JSON. var wrappedJson = JSON.stringify(wrapped); - // Convert the JSON string back into a Uint8Array to replace the request + // Convert the JSON string back into an ArrayBuffer to replace the request // body. - request.body = new Uint8Array(wrappedJson.length); - for (var i = 0; i < wrappedJson.length; ++i) { - request.body[i] = wrappedJson.charCodeAt(i); - } + request.body = StringUtils.toUTF8(wrappedJson); } }); ``` @@ -133,25 +131,22 @@ using a request filter: ```js player.getNetworkingEngine().registerResponseFilter(function(type, response) { + // Alias some utilities provided by the library. + var StringUtils = shaka.util.StringUtils; + var Uint8ArrayUtils = shaka.util.Uint8ArrayUtils; + // Only manipulate license responses: if (type == shaka.net.NetworkingEngine.RequestType.LICENSE) { - // This is the wrapped license. - var wrappedArray = new Uint8Array(response.data); - // Convert it to a string. - var wrappedString = String.fromCharCode.apply(null, wrappedArray); + // This is the wrapped license, which is a JSON string. + var wrappedString = StringUtils.fromUTF8(response.data); // Parse the JSON string into an object. var wrapped = JSON.parse(wrappedString); // This is a base64-encoded version of the raw license. var rawLicenseBase64 = wrapped.rawLicenseBase64; - // Decode it to a string. - var rawLicenseString = atob(rawLicenseBase64); - // Convert that string into a Uint8Array and replace the response data - // to feed it to the Widevine CDM. - response.data = new Uint8Array(rawLicenseString.length); - for (var i = 0; i < rawLicenseString.length; ++i) { - response.data[i] = rawLicenseString.charCodeAt(i); - } + // Decode that base64 string into a Uint8Array and replace the response + // data. The raw license will be fed to the Widevine CDM. + response.data = Uint8ArrayUtils.fromBase64(rawLicenseBase64); // Read additional fields from the server. // The server we are using in this tutorial does not send anything useful. diff --git a/lib/net/networking_engine.js b/lib/net/networking_engine.js index 1b3dd665f..741d054a7 100644 --- a/lib/net/networking_engine.js +++ b/lib/net/networking_engine.js @@ -252,12 +252,19 @@ shaka.net.NetworkingEngine.prototype.request = function(type, request) { goog.asserts.assert(request.uris && request.uris.length, 'Request without URIs!'); + // If a request comes from outside the library, some parameters may be left + // undefined. To make it easier for application developers, we will fill them + // in with defaults if necessary. + request.method = request.method || 'GET'; + request.headers = request.headers || {}; + request.retryParameters = request.retryParameters || + shaka.net.NetworkingEngine.defaultRetryParameters(); + var filterStartMs = Date.now(); // Send to the filter first, in-case they change the URI. - var requestFilters = this.requestFilters_; var p = Promise.resolve(); - requestFilters.forEach(function(requestFilter) { + this.requestFilters_.forEach(function(requestFilter) { // Request filters are resolved sequentially. p = p.then(function() { return Promise.resolve(requestFilter(type, request)); @@ -359,9 +366,8 @@ shaka.net.NetworkingEngine.prototype.send_ = function( response.timeMs = Date.now() - startTimeMs; var filterStartMs = Date.now(); - var responseFilters = this.responseFilters_; var p = Promise.resolve(); - responseFilters.forEach(function(responseFilter) { + this.responseFilters_.forEach(function(responseFilter) { // Response filters are resolved sequentially. p = p.then(function() { return Promise.resolve(responseFilter(type, response)); diff --git a/lib/util/string_utils.js b/lib/util/string_utils.js index 35c060415..f219ddb31 100644 --- a/lib/util/string_utils.js +++ b/lib/util/string_utils.js @@ -24,6 +24,7 @@ goog.require('shaka.util.Error'); /** * @namespace shaka.util.StringUtils * @summary A set of string utility functions. + * @exportDoc */ @@ -33,6 +34,7 @@ goog.require('shaka.util.Error'); * @param {?BufferSource} data * @return {string} * @throws {shaka.util.Error} + * @export */ shaka.util.StringUtils.fromUTF8 = function(data) { if (!data) return ''; @@ -69,6 +71,7 @@ shaka.util.StringUtils.fromUTF8 = function(data) { * @param {boolean} littleEndian true to read little endian, false to read big. * @return {string} * @throws {shaka.util.Error} + * @export */ shaka.util.StringUtils.fromUTF16 = function(data, littleEndian) { if (!data) return ''; @@ -110,6 +113,7 @@ shaka.util.StringUtils.fromUTF16 = function(data, littleEndian) { * @param {?BufferSource} data * @return {string} * @throws {shaka.util.Error} + * @export */ shaka.util.StringUtils.fromBytesAutoDetect = function(data) { var StringUtils = shaka.util.StringUtils; @@ -146,6 +150,7 @@ shaka.util.StringUtils.fromBytesAutoDetect = function(data) { * * @param {string} str * @return {!ArrayBuffer} + * @export */ shaka.util.StringUtils.toUTF8 = function(str) { // http://stackoverflow.com/a/13691499 diff --git a/lib/util/uint8array_utils.js b/lib/util/uint8array_utils.js index 38350840f..1e2aa353e 100644 --- a/lib/util/uint8array_utils.js +++ b/lib/util/uint8array_utils.js @@ -21,6 +21,7 @@ goog.provide('shaka.util.Uint8ArrayUtils'); /** * @namespace shaka.util.Uint8ArrayUtils * @summary A set of Uint8Array utility functions. + * @exportDoc */ @@ -31,6 +32,7 @@ goog.provide('shaka.util.Uint8ArrayUtils'); * @param {boolean=} opt_padding If true, pad the output with equals signs. * Defaults to true. * @return {string} + * @export */ shaka.util.Uint8ArrayUtils.toBase64 = function(arr, opt_padding) { // btoa expects a "raw string" where each character is interpreted as a byte. @@ -46,6 +48,7 @@ shaka.util.Uint8ArrayUtils.toBase64 = function(arr, opt_padding) { * alphabet or the alternate "base64url" alphabet. * @param {string} str * @return {!Uint8Array} + * @export */ shaka.util.Uint8ArrayUtils.fromBase64 = function(str) { // atob creates a "raw string" where each character is interpreted as a byte. @@ -62,6 +65,7 @@ shaka.util.Uint8ArrayUtils.fromBase64 = function(str) { * Convert a hex string to a Uint8Array. * @param {string} str * @return {!Uint8Array} + * @export */ shaka.util.Uint8ArrayUtils.fromHex = function(str) { var arr = new Uint8Array(str.length / 2); @@ -76,6 +80,7 @@ shaka.util.Uint8ArrayUtils.fromHex = function(str) { * Convert a Uint8Array to a hex string. * @param {!Uint8Array} arr * @return {string} + * @export */ shaka.util.Uint8ArrayUtils.toHex = function(arr) { var hex = ''; @@ -93,6 +98,7 @@ shaka.util.Uint8ArrayUtils.toHex = function(arr) { * @param {Uint8Array} arr1 * @param {Uint8Array} arr2 * @return {boolean} + * @export */ shaka.util.Uint8ArrayUtils.equal = function(arr1, arr2) { if (!arr1 && !arr2) return true;