videojs-vast-vpaid
Version:
VAST plugin to use with video.js
155 lines (120 loc) • 4.17 kB
JavaScript
const urlUtils = require('./urlUtils');
const utilities = require('./utilityFunctions');
function HttpRequestError (message) {
this.message = 'HttpRequest Error: ' + (message || '');
}
HttpRequestError.prototype = new Error();
HttpRequestError.prototype.name = 'HttpRequest Error';
function HttpRequest (createXhr) {
if (!utilities.isFunction(createXhr)) {
throw new HttpRequestError('Missing XMLHttpRequest factory method');
}
this.createXhr = createXhr;
}
HttpRequest.prototype.run = function (method, url, callback, options) {
sanityCheck(url, callback, options);
let timeout, timeoutId;
const xhr = this.createXhr();
options = options || {};
timeout = utilities.isNumber(options.timeout) ? options.timeout : 0;
xhr.open(method, urlUtils.urlParts(url).href, true);
if (options.headers) {
setHeaders(xhr, options.headers);
}
if (options.withCredentials) {
xhr.withCredentials = true;
}
xhr.onload = function () {
let statusText, response, status;
/**
* The only way to do a secure request on IE8 and IE9 is with the XDomainRequest object. Unfortunately, microsoft is
* so nice that decided that the status property and the 'getAllResponseHeaders' method where not needed so we have to
* fake them. If the request gets done with an XDomainRequest instance, we will assume that there are no headers and
* the status will always be 200. If you don't like it, DO NOT USE ANCIENT BROWSERS!!!
*
* For mor info go to: https://msdn.microsoft.com/en-us/library/cc288060(v=vs.85).aspx
*/
if (!xhr.getAllResponseHeaders) {
xhr.getAllResponseHeaders = function () {
return null;
};
}
if (!xhr.status) {
xhr.status = 200;
}
if (utilities.isDefined(timeoutId)) {
clearTimeout(timeoutId);
timeoutId = undefined;
}
statusText = xhr.statusText || '';
// responseText is the old-school way of retrieving response (supported by IE8 & 9)
// response/responseType properties were introduced in XHR Level2 spec (supported by IE10)
response = 'response' in xhr ? xhr.response : xhr.responseText;
// normalize IE9 bug (http://bugs.jquery.com/ticket/1450)
status = xhr.status === 1223 ? 204 : xhr.status;
callback(
status,
response,
xhr.getAllResponseHeaders(),
statusText);
};
xhr.onerror = requestError;
xhr.onabort = requestError;
xhr.send();
if (timeout > 0) {
timeoutId = setTimeout(() => {
if (xhr) {
xhr.abort();
}
}, timeout);
}
function sanityCheck (url, callback, options) {
if (!utilities.isString(url) || utilities.isEmptyString(url)) {
throw new HttpRequestError('Invalid url \'' + url + '\'');
}
if (!utilities.isFunction(callback)) {
throw new HttpRequestError('Invalid handler \'' + callback + '\' for the http request');
}
if (utilities.isDefined(options) && !utilities.isObject(options)) {
throw new HttpRequestError('Invalid options map \'' + options + '\'');
}
}
function setHeaders (xhr, headers) {
utilities.forEach(headers, (value, key) => {
if (utilities.isDefined(value)) {
xhr.setRequestHeader(key, value);
}
});
}
function requestError () {
callback(-1, null, null, '');
}
};
HttpRequest.prototype.get = function (url, callback, options) {
this.run('GET', url, processResponse, options);
function processResponse (status, response, headersString, statusText) {
if (isSuccess(status)) {
callback(null, response, status, headersString, statusText);
} else {
callback(new HttpRequestError(statusText), response, status, headersString, statusText);
}
}
function isSuccess (status) {
return 200 <= status && status < 300;
}
};
function createXhr () {
let xhr = new XMLHttpRequest();
if (!('withCredentials' in xhr)) {
// XDomainRequest for IE.
xhr = new XDomainRequest();
}
return xhr;
}
const http = new HttpRequest(createXhr);
module.exports = {
http: http,
HttpRequest: HttpRequest,
HttpRequestError: HttpRequestError,
createXhr: createXhr
};