blob: ef2efe36d6f0fcc8701b8bb984caf1b8f35500a4 [file] [log] [blame]
Adrià Vilanova Martínez4e0cb182022-06-26 00:21:50 +02001import {correctArrayKeys} from '../common/protojs';
Adrià Vilanova Martínez102d54b2022-12-18 11:12:11 +01002import * as utils from '../xhrInterceptor/utils.js';
Adrià Vilanova Martínez43ec2b92021-07-16 18:44:54 +02003
Adrià Vilanova Martínez4e0cb182022-06-26 00:21:50 +02004const originalOpen = window.XMLHttpRequest.prototype.open;
5const originalSetRequestHeader =
6 window.XMLHttpRequest.prototype.setRequestHeader;
7const originalSend = window.XMLHttpRequest.prototype.send;
Adrià Vilanova Martínez43ec2b92021-07-16 18:44:54 +02008
avm999631f50f6f2021-08-12 23:04:41 +02009let messageID = 0;
10
Adrià Vilanova Martínez102d54b2022-12-18 11:12:11 +010011class XHRProxy {
12 constructor() {
13 this.originalXMLHttpRequest = window.XMLHttpRequest;
14 const originalXMLHttpRequest = this.originalXMLHttpRequest;
Adrià Vilanova Martínez43ec2b92021-07-16 18:44:54 +020015
Adrià Vilanova Martínez102d54b2022-12-18 11:12:11 +010016 this.messageID = 0;
17
18 window.XMLHttpRequest = function() {
19 this.xhr = new originalXMLHttpRequest();
20 this.$TWPTID = messageID++;
21 };
22
23 const methods = [
24 'open', 'abort', 'setRequestHeader', 'send', 'addEventListener',
25 'removeEventListener', 'getResponseHeader', 'getAllResponseHeaders',
26 'dispatchEvent', 'overrideMimeType'
27 ];
28 methods.forEach(method => {
29 window.XMLHttpRequest.prototype[method] = function() {
30 const proxyThis = this;
31
32 switch (method) {
33 case 'open':
34 this.$TWPTRequestURL = arguments[1] || location.href;
35
36 var interceptors =
37 utils.matchInterceptors('response', this.$TWPTRequestURL);
38 if (interceptors.length > 0) {
39 this.xhr.addEventListener('load', function() {
40 var body = utils.getResponseJSON(this);
41 if (body !== undefined)
42 interceptors.forEach(i => {
43 utils.triggerEvent(i.eventName, body, proxyThis.$TWPTID);
44 });
45 });
46 }
47 break;
48
49 case 'setRequestHeader':
50 let header = arguments[0];
51 let value = arguments[1];
52 if ('Content-Type'.localeCompare(
53 header, undefined, {sensitivity: 'accent'}) == 0)
54 this.$isArrayProto = (value == 'application/json+protobuf');
55 break;
56
57 case 'send':
58 var interceptors = utils.matchInterceptors(
59 'request', this.$TWPTRequestURL || location.href);
60 if (interceptors.length > 0) {
61 let rawBody = arguments[0];
62 let body;
63 if (typeof (rawBody) === 'object' &&
64 (rawBody instanceof Object.getPrototypeOf(Uint8Array))) {
65 let dec = new TextDecoder('utf-8');
66 body = dec.decode(rawBody);
67 } else if (typeof (rawBody) === 'string') {
68 body = rawBody;
69 } else {
70 console.error(
71 'Unexpected type of request body (' + typeof (rawBody) +
72 ').',
73 this.$TWPTRequestURL);
74 return;
75 }
76
77 let JSONBody = JSON.parse(body);
78 if (this.$isArrayProto) JSONBody = correctArrayKeys(JSONBody);
79
80 interceptors.forEach(i => {
81 utils.triggerEvent(i.eventName, JSONBody, this.$TWPTID);
82 });
83 }
84 break;
85 }
86 return this.xhr[method].apply(this.xhr, arguments);
87 };
Adrià Vilanova Martínez43ec2b92021-07-16 18:44:54 +020088 });
Adrià Vilanova Martínez43ec2b92021-07-16 18:44:54 +020089
Adrià Vilanova Martínez102d54b2022-12-18 11:12:11 +010090 const scalars = [
91 'onabort',
92 'onerror',
93 'onload',
94 'onloadstart',
95 'onloadend',
96 'onprogress',
97 'onreadystatechange',
98 'readyState',
99 'response',
100 'responseText',
101 'responseType',
102 'responseXML',
103 'status',
104 'statusText',
105 'upload',
106 'withCredentials',
107 'DONE',
108 'UNSENT',
109 'HEADERS_RECEIVED',
110 'LOADING',
111 'OPENED'
112 ];
113 scalars.forEach(scalar => {
114 Object.defineProperty(window.XMLHttpRequest.prototype, scalar, {
115 get: function() {
116 return this.xhr[scalar];
117 },
118 set: function(val) {
119 this.xhr[scalar] = val;
120 },
121 });
Adrià Vilanova Martínez43ec2b92021-07-16 18:44:54 +0200122 });
Adrià Vilanova Martínez102d54b2022-12-18 11:12:11 +0100123
124 return this;
Adrià Vilanova Martínez43ec2b92021-07-16 18:44:54 +0200125 }
Adrià Vilanova Martínez102d54b2022-12-18 11:12:11 +0100126}
127
128new XHRProxy();