blob: ef2efe36d6f0fcc8701b8bb984caf1b8f35500a4 [file] [log] [blame]
import {correctArrayKeys} from '../common/protojs';
import * as utils from '../xhrInterceptor/utils.js';
const originalOpen = window.XMLHttpRequest.prototype.open;
const originalSetRequestHeader =
window.XMLHttpRequest.prototype.setRequestHeader;
const originalSend = window.XMLHttpRequest.prototype.send;
let messageID = 0;
class XHRProxy {
constructor() {
this.originalXMLHttpRequest = window.XMLHttpRequest;
const originalXMLHttpRequest = this.originalXMLHttpRequest;
this.messageID = 0;
window.XMLHttpRequest = function() {
this.xhr = new originalXMLHttpRequest();
this.$TWPTID = messageID++;
};
const methods = [
'open', 'abort', 'setRequestHeader', 'send', 'addEventListener',
'removeEventListener', 'getResponseHeader', 'getAllResponseHeaders',
'dispatchEvent', 'overrideMimeType'
];
methods.forEach(method => {
window.XMLHttpRequest.prototype[method] = function() {
const proxyThis = this;
switch (method) {
case 'open':
this.$TWPTRequestURL = arguments[1] || location.href;
var interceptors =
utils.matchInterceptors('response', this.$TWPTRequestURL);
if (interceptors.length > 0) {
this.xhr.addEventListener('load', function() {
var body = utils.getResponseJSON(this);
if (body !== undefined)
interceptors.forEach(i => {
utils.triggerEvent(i.eventName, body, proxyThis.$TWPTID);
});
});
}
break;
case 'setRequestHeader':
let header = arguments[0];
let value = arguments[1];
if ('Content-Type'.localeCompare(
header, undefined, {sensitivity: 'accent'}) == 0)
this.$isArrayProto = (value == 'application/json+protobuf');
break;
case 'send':
var interceptors = utils.matchInterceptors(
'request', this.$TWPTRequestURL || location.href);
if (interceptors.length > 0) {
let rawBody = arguments[0];
let body;
if (typeof (rawBody) === 'object' &&
(rawBody instanceof Object.getPrototypeOf(Uint8Array))) {
let dec = new TextDecoder('utf-8');
body = dec.decode(rawBody);
} else if (typeof (rawBody) === 'string') {
body = rawBody;
} else {
console.error(
'Unexpected type of request body (' + typeof (rawBody) +
').',
this.$TWPTRequestURL);
return;
}
let JSONBody = JSON.parse(body);
if (this.$isArrayProto) JSONBody = correctArrayKeys(JSONBody);
interceptors.forEach(i => {
utils.triggerEvent(i.eventName, JSONBody, this.$TWPTID);
});
}
break;
}
return this.xhr[method].apply(this.xhr, arguments);
};
});
const scalars = [
'onabort',
'onerror',
'onload',
'onloadstart',
'onloadend',
'onprogress',
'onreadystatechange',
'readyState',
'response',
'responseText',
'responseType',
'responseXML',
'status',
'statusText',
'upload',
'withCredentials',
'DONE',
'UNSENT',
'HEADERS_RECEIVED',
'LOADING',
'OPENED'
];
scalars.forEach(scalar => {
Object.defineProperty(window.XMLHttpRequest.prototype, scalar, {
get: function() {
return this.xhr[scalar];
},
set: function(val) {
this.xhr[scalar] = val;
},
});
});
return this;
}
}
new XHRProxy();