Source: lib/net/data_uri_plugin.js

  1. /**
  2. * @license
  3. * Copyright 2016 Google Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. goog.provide('shaka.net.DataUriPlugin');
  18. goog.require('shaka.log');
  19. goog.require('shaka.net.NetworkingEngine');
  20. goog.require('shaka.util.AbortableOperation');
  21. goog.require('shaka.util.Error');
  22. goog.require('shaka.util.StringUtils');
  23. goog.require('shaka.util.Uint8ArrayUtils');
  24. /**
  25. * @namespace
  26. * @summary A networking plugin to handle data URIs.
  27. * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/data_URIs
  28. * @param {string} uri
  29. * @param {shakaExtern.Request} request
  30. * @param {shaka.net.NetworkingEngine.RequestType=} requestType
  31. * @return {!shakaExtern.IAbortableOperation.<shakaExtern.Response>}
  32. * @export
  33. */
  34. shaka.net.DataUriPlugin = function(uri, request, requestType) {
  35. try {
  36. let parsed = shaka.net.DataUriPlugin.parse(uri);
  37. /** @type {shakaExtern.Response} */
  38. let response = {
  39. uri: uri,
  40. data: parsed.data,
  41. headers: {
  42. 'content-type': parsed.contentType
  43. }
  44. };
  45. return shaka.util.AbortableOperation.completed(response);
  46. } catch (error) {
  47. return shaka.util.AbortableOperation.failed(error);
  48. }
  49. };
  50. /**
  51. * @param {string} uri
  52. * @return {{data: ArrayBuffer, contentType: string}}
  53. */
  54. shaka.net.DataUriPlugin.parse = function(uri) {
  55. // Extract the scheme.
  56. let parts = uri.split(':');
  57. if (parts.length < 2 || parts[0] != 'data') {
  58. shaka.log.error('Bad data URI, failed to parse scheme');
  59. throw new shaka.util.Error(
  60. shaka.util.Error.Severity.CRITICAL,
  61. shaka.util.Error.Category.NETWORK,
  62. shaka.util.Error.Code.MALFORMED_DATA_URI,
  63. uri);
  64. }
  65. let path = parts.slice(1).join(':');
  66. // Extract the encoding and MIME type (required but can be empty).
  67. let infoAndData = path.split(',');
  68. if (infoAndData.length < 2) {
  69. shaka.log.error('Bad data URI, failed to extract encoding and MIME type');
  70. throw new shaka.util.Error(
  71. shaka.util.Error.Severity.CRITICAL,
  72. shaka.util.Error.Category.NETWORK,
  73. shaka.util.Error.Code.MALFORMED_DATA_URI,
  74. uri);
  75. }
  76. let info = infoAndData[0];
  77. let dataStr = window.decodeURIComponent(infoAndData.slice(1).join(','));
  78. // Extract the encoding (optional).
  79. let typeAndEncoding = info.split(';');
  80. let encoding = null;
  81. if (typeAndEncoding.length > 1) {
  82. encoding = typeAndEncoding[1];
  83. }
  84. // Convert the data.
  85. /** @type {ArrayBuffer} */
  86. let data;
  87. if (encoding == 'base64') {
  88. data = shaka.util.Uint8ArrayUtils.fromBase64(dataStr).buffer;
  89. } else if (encoding) {
  90. shaka.log.error('Bad data URI, unknown encoding');
  91. throw new shaka.util.Error(
  92. shaka.util.Error.Severity.CRITICAL,
  93. shaka.util.Error.Category.NETWORK,
  94. shaka.util.Error.Code.UNKNOWN_DATA_URI_ENCODING,
  95. uri);
  96. } else {
  97. data = shaka.util.StringUtils.toUTF8(dataStr);
  98. }
  99. return {data: data, contentType: typeAndEncoding[0]};
  100. };
  101. shaka.net.NetworkingEngine.registerScheme('data', shaka.net.DataUriPlugin);