Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
titaniumnetwork-dev
GitHub Repository: titaniumnetwork-dev/Ultraviolet
Path: blob/main/src/client/requests/xhr.js
305 views
1
import EventEmitter from "events";
2
import HookEvent from "../hook.js";
3
4
/**
5
* @typedef {import('../index').default} UVClient
6
*/
7
8
class Xhr extends EventEmitter {
9
/**
10
*
11
* @param {UVClient} ctx
12
*/
13
constructor(ctx) {
14
super();
15
this.ctx = ctx;
16
this.window = ctx.window;
17
this.XMLHttpRequest = this.window.XMLHttpRequest;
18
this.xhrProto = this.window.XMLHttpRequest
19
? this.window.XMLHttpRequest.prototype
20
: {};
21
this.open = this.xhrProto.open;
22
this.abort = this.xhrProto.abort;
23
this.send = this.xhrProto.send;
24
this.overrideMimeType = this.xhrProto.overrideMimeType;
25
this.getAllResponseHeaders = this.xhrProto.getAllResponseHeaders;
26
this.getResponseHeader = this.xhrProto.getResponseHeader;
27
this.setRequestHeader = this.xhrProto.setRequestHeader;
28
this.responseURL = ctx.nativeMethods.getOwnPropertyDescriptor(
29
this.xhrProto,
30
"responseURL"
31
);
32
this.responseText = ctx.nativeMethods.getOwnPropertyDescriptor(
33
this.xhrProto,
34
"responseText"
35
);
36
}
37
override() {
38
this.overrideOpen();
39
this.overrideSend();
40
this.overrideMimeType();
41
this.overrideGetResHeader();
42
this.overrideGetResHeaders();
43
this.overrideSetReqHeader();
44
}
45
overrideOpen() {
46
this.ctx.override(this.xhrProto, "open", (target, that, args) => {
47
if (2 > args.length) return target.apply(that, args);
48
49
let [method, input, async = true, user = null, password = null] = args;
50
const event = new HookEvent(
51
{ method, input, async, user, password },
52
target,
53
that
54
);
55
56
this.emit("open", event);
57
if (event.intercepted) return event.returnValue;
58
59
return event.target.call(
60
event.that,
61
event.data.method,
62
event.data.input,
63
event.data.async,
64
event.data.user,
65
event.data.password
66
);
67
});
68
}
69
overrideResponseUrl() {
70
this.ctx.overrideDescriptor(this.xhrProto, "responseURL", {
71
get: (target, that) => {
72
const event = new HookEvent({ value: target.call(that) }, target, that);
73
this.emit("responseUrl", event);
74
75
if (event.intercepted) return event.returnValue;
76
return event.data.value;
77
},
78
});
79
}
80
overrideSend() {
81
this.ctx.override(this.xhrProto, "send", (target, that, [body = null]) => {
82
const event = new HookEvent({ body }, target, that);
83
84
this.emit("send", event);
85
if (event.intercepted) return event.returnValue;
86
87
return event.target.call(event.that, event.data.body);
88
});
89
}
90
overrideSetReqHeader() {
91
this.ctx.override(
92
this.xhrProto,
93
"setRequestHeader",
94
(target, that, args) => {
95
if (2 > args.length) return target.apply(that, args);
96
97
let [name, value] = args;
98
const event = new HookEvent({ name, value }, target, that);
99
100
this.emit("setReqHeader", event);
101
if (event.intercepted) return event.returnValue;
102
103
return event.target.call(event.that, event.data.name, event.data.value);
104
}
105
);
106
}
107
overrideGetResHeaders() {
108
this.ctx.override(
109
this.xhrProto,
110
"getAllResponseHeaders",
111
(target, that) => {
112
const event = new HookEvent({ value: target.call(that) }, target, that);
113
114
this.emit("getAllResponseHeaders", event);
115
if (event.intercepted) return event.returnValue;
116
117
return event.data.value;
118
}
119
);
120
}
121
overrideGetResHeader() {
122
this.ctx.override(
123
this.xhrProto,
124
"getResponseHeader",
125
(target, that, args) => {
126
if (!args.length) return target.apply(that, args);
127
let [name] = args;
128
129
const event = new HookEvent(
130
{ name, value: target.call(that, name) },
131
target,
132
that
133
);
134
if (event.intercepted) return event.returnValue;
135
136
return event.data.value;
137
}
138
);
139
}
140
}
141
142
export default Xhr;
143
144