Source: lib/net/http_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.HttpPlugin');
  18. goog.require('goog.asserts');
  19. goog.require('shaka.log');
  20. goog.require('shaka.net.NetworkingEngine');
  21. goog.require('shaka.util.Error');
  22. goog.require('shaka.util.StringUtils');
  23. /**
  24. * @namespace
  25. * @summary A networking plugin to handle http and https URIs via XHR.
  26. * @param {string} uri
  27. * @param {shakaExtern.Request} request
  28. * @return {!Promise.<shakaExtern.Response>}
  29. * @export
  30. */
  31. shaka.net.HttpPlugin = function(uri, request) {
  32. return new Promise(function(resolve, reject) {
  33. var xhr = new XMLHttpRequest();
  34. xhr.open(request.method, uri, true);
  35. xhr.responseType = 'arraybuffer';
  36. xhr.timeout = request.retryParameters.timeout;
  37. xhr.withCredentials = request.allowCrossSiteCredentials;
  38. xhr.onload = function(event) {
  39. var target = event.target;
  40. goog.asserts.assert(target, 'XHR onload has no target!');
  41. var headers = target.getAllResponseHeaders().split('\r\n').reduce(
  42. function(all, part) {
  43. var header = part.split(': ');
  44. all[header[0].toLowerCase()] = header.slice(1).join(': ');
  45. return all;
  46. },
  47. {});
  48. if (target.status >= 200 && target.status <= 299 &&
  49. target.status != 202) {
  50. // Most 2xx HTTP codes are success cases.
  51. if (target.responseURL) {
  52. uri = target.responseURL;
  53. }
  54. /** @type {shakaExtern.Response} */
  55. var response = {
  56. uri: uri,
  57. data: target.response,
  58. headers: headers,
  59. fromCache: !!headers['x-shaka-from-cache']
  60. };
  61. resolve(response);
  62. } else {
  63. var responseText = null;
  64. try {
  65. responseText = shaka.util.StringUtils.fromBytesAutoDetect(
  66. target.response);
  67. } catch (exception) {}
  68. shaka.log.debug('HTTP error text:', responseText);
  69. var severity = target.status == 401 || target.status == 403 ?
  70. shaka.util.Error.Severity.CRITICAL :
  71. shaka.util.Error.Severity.RECOVERABLE;
  72. reject(new shaka.util.Error(
  73. severity,
  74. shaka.util.Error.Category.NETWORK,
  75. shaka.util.Error.Code.BAD_HTTP_STATUS,
  76. uri,
  77. target.status,
  78. responseText,
  79. headers));
  80. }
  81. };
  82. xhr.onerror = function(event) {
  83. reject(new shaka.util.Error(
  84. shaka.util.Error.Severity.RECOVERABLE,
  85. shaka.util.Error.Category.NETWORK,
  86. shaka.util.Error.Code.HTTP_ERROR,
  87. uri));
  88. };
  89. xhr.ontimeout = function(event) {
  90. reject(new shaka.util.Error(
  91. shaka.util.Error.Severity.RECOVERABLE,
  92. shaka.util.Error.Category.NETWORK,
  93. shaka.util.Error.Code.TIMEOUT,
  94. uri));
  95. };
  96. for (var k in request.headers) {
  97. xhr.setRequestHeader(k, request.headers[k]);
  98. }
  99. xhr.send(request.body);
  100. });
  101. };
  102. shaka.net.NetworkingEngine.registerScheme('http', shaka.net.HttpPlugin);
  103. shaka.net.NetworkingEngine.registerScheme('https', shaka.net.HttpPlugin);