mirror of
https://github.com/shaka-project/shaka-player.git
synced 2026-06-26 17:46:26 +03:00
2f55d2a3bd
This uses AbortableOperation in all networking, from the scheme plugins all the way to the request interface. This also updates all default scheme plugins, docs, and sample code. Backward compatibility is provided for scheme plugins and the request API in NetworkingEngine. This compatibility will be removed in v2.5. Two cancelation-related tests have been disabled in player_integration until the new abort interface has been adopted in the manifest parsers. Issue #829 Change-Id: I91c8e6efe97798d111e8ddca5655cddc1f6bcbf3
248 lines
8.3 KiB
JavaScript
248 lines
8.3 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.
|
|
*/
|
|
|
|
describe('HttpPlugin', function() {
|
|
/** @type {shakaExtern.RetryParameters} */
|
|
var retryParameters;
|
|
|
|
beforeAll(function() {
|
|
// Install the mock only briefly in the global namespace, to get a handle to
|
|
// the mocked XHR implementation.
|
|
jasmine.Ajax.install();
|
|
var MockXHR = window.XMLHttpRequest;
|
|
jasmine.Ajax.uninstall();
|
|
// Now plug this mock into HttpRequest directly, so it does not interfere
|
|
// with other requests, such as those made by karma frameworks like
|
|
// source-map-support.
|
|
shaka.net.HttpPlugin['xhr_'] = MockXHR;
|
|
|
|
jasmine.clock().install();
|
|
|
|
jasmine.Ajax.stubRequest('https://foo.bar/').andReturn({
|
|
'response': new ArrayBuffer(10),
|
|
'status': 200,
|
|
'responseHeaders': { 'FOO': 'BAR' }
|
|
});
|
|
jasmine.Ajax.stubRequest('https://foo.bar/202').andReturn({
|
|
'response': new ArrayBuffer(0),
|
|
'status': 202
|
|
});
|
|
jasmine.Ajax.stubRequest('https://foo.bar/204').andReturn({
|
|
'response': new ArrayBuffer(10),
|
|
'status': 204,
|
|
'responseHeaders': { 'FOO': 'BAR' }
|
|
});
|
|
jasmine.Ajax.stubRequest('https://foo.bar/withemptyline').andReturn({
|
|
'response': new ArrayBuffer(0),
|
|
'status': 200,
|
|
'responseHeaders': { '\nFOO': 'BAR' }
|
|
});
|
|
jasmine.Ajax.stubRequest('https://foo.bar/302').andReturn({
|
|
'response': new ArrayBuffer(10),
|
|
'status': 200,
|
|
'responseHeaders': { 'FOO': 'BAR' },
|
|
'responseURL': 'https://foo.bar/after/302'
|
|
});
|
|
jasmine.Ajax.stubRequest('https://foo.bar/401').andReturn({
|
|
'response': new ArrayBuffer(0),
|
|
'status': 401
|
|
});
|
|
jasmine.Ajax.stubRequest('https://foo.bar/403').andReturn({
|
|
'response': new ArrayBuffer(0),
|
|
'status': 403
|
|
});
|
|
jasmine.Ajax.stubRequest('https://foo.bar/404').andReturn({
|
|
'response': new ArrayBuffer(0),
|
|
'status': 404
|
|
});
|
|
jasmine.Ajax.stubRequest('https://foo.bar/cache').andReturn({
|
|
'response': new ArrayBuffer(0),
|
|
'status': 200,
|
|
'responseHeaders': { 'X-Shaka-From-Cache': 'true' }
|
|
});
|
|
|
|
jasmine.Ajax.stubRequest('https://foo.bar/timeout').andTimeout();
|
|
jasmine.Ajax.stubRequest('https://foo.bar/error').andError();
|
|
|
|
retryParameters = shaka.net.NetworkingEngine.defaultRetryParameters();
|
|
});
|
|
|
|
afterAll(function() {
|
|
shaka.net.HttpPlugin['xhr_'] = window.XMLHttpRequest;
|
|
jasmine.clock().uninstall();
|
|
});
|
|
|
|
it('sets the correct fields', function(done) {
|
|
var request = shaka.net.NetworkingEngine.makeRequest(
|
|
['https://foo.bar/'], retryParameters);
|
|
request.allowCrossSiteCredentials = true;
|
|
request.method = 'POST';
|
|
request.headers['BAZ'] = '123';
|
|
|
|
shaka.net.HttpPlugin(request.uris[0], request).promise
|
|
.then(function() {
|
|
/** @type {!jasmine.Ajax.RequestStub} */
|
|
var actual = jasmine.Ajax.requests.mostRecent();
|
|
expect(actual).toBeTruthy();
|
|
expect(actual.url).toBe(request.uris[0]);
|
|
expect(actual.method).toBe(request.method);
|
|
expect(actual.withCredentials).toBe(true);
|
|
expect(actual.requestHeaders['BAZ']).toBe('123');
|
|
})
|
|
.catch(fail)
|
|
.then(done);
|
|
});
|
|
|
|
it('fails with 202 status', function(done) {
|
|
testFails('https://foo.bar/202', done);
|
|
});
|
|
|
|
it('succeeds with 204 status', function(done) {
|
|
testSucceeds('https://foo.bar/204', done);
|
|
});
|
|
|
|
it('succeeds with empty line in response', function(done) {
|
|
testSucceedsWithEmptyLine('https://foo.bar/withemptyline', done);
|
|
});
|
|
|
|
it('gets redirect URLs with 302 status', function(done) {
|
|
testSucceeds('https://foo.bar/302', done,
|
|
'https://foo.bar/after/302');
|
|
});
|
|
|
|
it('fails with CRITICAL for 401 status', function(done) {
|
|
testFails('https://foo.bar/401', done, shaka.util.Error.Severity.CRITICAL);
|
|
});
|
|
|
|
it('fails with CRITICAL for 403 status', function(done) {
|
|
testFails('https://foo.bar/403', done, shaka.util.Error.Severity.CRITICAL);
|
|
});
|
|
|
|
it('fails if non-2xx status', function(done) {
|
|
testFails('https://foo.bar/404', done);
|
|
});
|
|
|
|
it('fails on timeout', function(done) {
|
|
testFails('https://foo.bar/timeout', done);
|
|
});
|
|
|
|
it('fails on error', function(done) {
|
|
testFails('https://foo.bar/error', done);
|
|
});
|
|
|
|
it('detects cache headers', function(done) {
|
|
var request = shaka.net.NetworkingEngine.makeRequest(
|
|
['https://foo.bar/cache'], retryParameters);
|
|
shaka.net.HttpPlugin(request.uris[0], request).promise
|
|
.catch(fail)
|
|
.then(function(response) {
|
|
expect(response).toBeTruthy();
|
|
expect(response.fromCache).toBe(true);
|
|
})
|
|
.then(done);
|
|
});
|
|
|
|
it('aborts the request when the operation is aborted', function(done) {
|
|
var request = shaka.net.NetworkingEngine.makeRequest(
|
|
['https://foo.bar/'], retryParameters);
|
|
var operation = shaka.net.HttpPlugin(request.uris[0], request);
|
|
|
|
/** @type {!jasmine.Ajax.RequestStub} */
|
|
var actual = jasmine.Ajax.requests.mostRecent();
|
|
actual.abort = shaka.test.Util.spyFunc(jasmine.createSpy('abort'));
|
|
|
|
var requestPromise = operation.promise.catch(() => {});
|
|
|
|
expect(actual.abort).not.toHaveBeenCalled();
|
|
var abortPromise = operation.abort();
|
|
expect(actual.abort).toHaveBeenCalled();
|
|
|
|
Promise.all([abortPromise, requestPromise]).catch(fail).then(done);
|
|
});
|
|
|
|
/**
|
|
* @param {string} uri
|
|
* @param {function()} done
|
|
* @param {string=} opt_overrideUri
|
|
*/
|
|
function testSucceeds(uri, done, opt_overrideUri) {
|
|
var request = shaka.net.NetworkingEngine.makeRequest(
|
|
[uri], retryParameters);
|
|
shaka.net.HttpPlugin(uri, request).promise
|
|
.catch(fail)
|
|
.then(function(response) {
|
|
expect(jasmine.Ajax.requests.mostRecent().url).toBe(uri);
|
|
expect(response).toBeTruthy();
|
|
expect(response.uri).toBe(opt_overrideUri || uri);
|
|
expect(response.data).toBeTruthy();
|
|
expect(response.data.byteLength).toBe(10);
|
|
expect(response.fromCache).toBe(false);
|
|
expect(response.headers).toBeTruthy();
|
|
// Returned header names are in lowercase.
|
|
expect(response.headers['foo']).toBe('BAR');
|
|
})
|
|
.then(done);
|
|
}
|
|
|
|
/**
|
|
* @param {string} uri
|
|
* @param {function()} done
|
|
* @param {shaka.util.Error.Severity=} opt_severity
|
|
*/
|
|
function testFails(uri, done, opt_severity) {
|
|
var request = shaka.net.NetworkingEngine.makeRequest(
|
|
[uri], retryParameters);
|
|
shaka.net.HttpPlugin(uri, request).promise
|
|
.then(fail)
|
|
.catch(function(error) {
|
|
expect(error).toBeTruthy();
|
|
expect(error.severity)
|
|
.toBe(opt_severity || shaka.util.Error.Severity.RECOVERABLE);
|
|
expect(error.category).toBe(shaka.util.Error.Category.NETWORK);
|
|
|
|
expect(jasmine.Ajax.requests.mostRecent().url).toBe(uri);
|
|
})
|
|
.then(done);
|
|
}
|
|
|
|
/**
|
|
* Since IE/Edge incorrectly return the header with a leading new line
|
|
* character ('\n'), we need to trim the response header.
|
|
* @param {string} uri
|
|
* @param {function()} done
|
|
* @param {string=} opt_overrideUri
|
|
*/
|
|
function testSucceedsWithEmptyLine(uri, done, opt_overrideUri) {
|
|
var request = shaka.net.NetworkingEngine.makeRequest(
|
|
[uri], retryParameters);
|
|
shaka.net.HttpPlugin(uri, request).promise
|
|
.catch(fail)
|
|
.then(function(response) {
|
|
expect(jasmine.Ajax.requests.mostRecent().url).toBe(uri);
|
|
expect(response).toBeTruthy();
|
|
expect(response.uri).toBe(opt_overrideUri || uri);
|
|
expect(response.data).toBeTruthy();
|
|
expect(response.fromCache).toBe(false);
|
|
expect(response.headers).toBeTruthy();
|
|
// Returned header names do not contain empty lines.
|
|
expect(response.headers['foo']).toBe('BAR');
|
|
})
|
|
.then(done);
|
|
}
|
|
});
|
|
|