Files
shaka-player/lib/net/data_uri_plugin.js
T
Jacob Trimble 596c80a949 Refactor handling of ArrayBuffer.
This changes the network API to use BufferSource instead of ArrayBuffer,
which allows plugins to return a "view" on a buffer instead of the
whole buffer.  This also adds some utilities for changing between
views and buffers.

Lastly this forbids the use of the "buffer" property of TypedArrays
since it doesn't work with partial "views".  This audits and fixes the
usages of the "buffer" property to ensure correct usage.

It should be noted that both MSE and EME accept a BufferSource as input,
so we don't need to convert a "view" into an ArrayBuffer before passing
to it.

Change-Id: Iaa417773f8ce5304424e43c7372ce10ebf540d2a
2019-08-20 20:17:33 +00:00

123 lines
3.8 KiB
JavaScript

/**
* @license
* Copyright 2016 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
goog.provide('shaka.net.DataUriPlugin');
goog.require('shaka.log');
goog.require('shaka.net.NetworkingEngine');
goog.require('shaka.util.AbortableOperation');
goog.require('shaka.util.Error');
goog.require('shaka.util.StringUtils');
goog.require('shaka.util.Uint8ArrayUtils');
/**
* @summary A networking plugin to handle data URIs.
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/data_URIs
* @export
*/
shaka.net.DataUriPlugin = class {
/**
* @param {string} uri
* @param {shaka.extern.Request} request
* @param {shaka.net.NetworkingEngine.RequestType} requestType
* @param {shaka.extern.ProgressUpdated} progressUpdated Called when a
* progress event happened.
* @return {!shaka.extern.IAbortableOperation.<shaka.extern.Response>}
* @export
*/
static parse(uri, request, requestType, progressUpdated) {
try {
const parsed = shaka.net.DataUriPlugin.parseRaw(uri);
/** @type {shaka.extern.Response} */
const response = {
uri: uri,
originalUri: uri,
data: parsed.data,
headers: {
'content-type': parsed.contentType,
},
};
return shaka.util.AbortableOperation.completed(response);
} catch (error) {
return shaka.util.AbortableOperation.failed(error);
}
}
/**
* @param {string} uri
* @return {{data: BufferSource, contentType: string}}
*/
static parseRaw(uri) {
// Extract the scheme.
const parts = uri.split(':');
if (parts.length < 2 || parts[0] != 'data') {
shaka.log.error('Bad data URI, failed to parse scheme');
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.NETWORK,
shaka.util.Error.Code.MALFORMED_DATA_URI,
uri);
}
const path = parts.slice(1).join(':');
// Extract the encoding and MIME type (required but can be empty).
const infoAndData = path.split(',');
if (infoAndData.length < 2) {
shaka.log.error('Bad data URI, failed to extract encoding and MIME type');
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.NETWORK,
shaka.util.Error.Code.MALFORMED_DATA_URI,
uri);
}
const info = infoAndData[0];
const dataStr = window.decodeURIComponent(infoAndData.slice(1).join(','));
// Extract the encoding (optional).
const typeAndEncoding = info.split(';');
let encoding = null;
if (typeAndEncoding.length > 1) {
encoding = typeAndEncoding[1];
}
// Convert the data.
/** @type {BufferSource} */
let data;
if (encoding == 'base64') {
data = shaka.util.Uint8ArrayUtils.fromBase64(dataStr);
} else if (encoding) {
shaka.log.error('Bad data URI, unknown encoding');
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.NETWORK,
shaka.util.Error.Code.UNKNOWN_DATA_URI_ENCODING,
uri);
} else {
data = shaka.util.StringUtils.toUTF8(dataStr);
}
return {data: data, contentType: typeAndEncoding[0]};
}
};
shaka.net.NetworkingEngine.registerScheme(
'data', shaka.net.DataUriPlugin.parse);