|
@@ -24,13 +24,13 @@ export default class XMLHttpRequest extends XMLHttpRequestEventTarget{
|
24
|
24
|
_readyState : number = UNSENT;
|
25
|
25
|
_response : any = '';
|
26
|
26
|
_responseText : any = '';
|
27
|
|
- _responseHeaders : any = '';
|
|
27
|
+ _responseHeaders : any = {};
|
28
|
28
|
_responseType : '' | 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' = '';
|
29
|
29
|
// TODO : not suppoted for now
|
30
|
30
|
_responseURL : null = '';
|
31
|
31
|
_responseXML : null = '';
|
32
|
|
- _status : number;
|
33
|
|
- _statusText : string;
|
|
32
|
+ _status : number = 0;
|
|
33
|
+ _statusText : string = '';
|
34
|
34
|
_timeout : number = 0;
|
35
|
35
|
_upload : XMLHttpRequestEventTarget;
|
36
|
36
|
_sendFlag : boolean = false;
|
|
@@ -74,11 +74,21 @@ export default class XMLHttpRequest extends XMLHttpRequestEventTarget{
|
74
|
74
|
this._headers = {}
|
75
|
75
|
}
|
76
|
76
|
|
77
|
|
- // XMLHttpRequest.open, always async, user and password not supported.
|
|
77
|
+
|
|
78
|
+ /**
|
|
79
|
+ * XMLHttpRequest.open, always async, user and password not supported. When
|
|
80
|
+ * this method invoked, headers should becomes empty again.
|
|
81
|
+ * @param {string} method Request method
|
|
82
|
+ * @param {string} url Request URL
|
|
83
|
+ * @param {true} async Always async
|
|
84
|
+ * @param {any} user NOT SUPPORTED
|
|
85
|
+ * @param {any} password NOT SUPPORTED
|
|
86
|
+ */
|
78
|
87
|
open(method:string, url:string, async:true, user:any, password:any) {
|
79
|
88
|
log.verbose('XMLHttpRequest open ', method, url, async, user, password)
|
80
|
89
|
this._method = method
|
81
|
90
|
this._url = url
|
|
91
|
+ this._headers = {}
|
82
|
92
|
this.readyState = XMLHttpRequest.OPENED
|
83
|
93
|
}
|
84
|
94
|
|
|
@@ -87,6 +97,10 @@ export default class XMLHttpRequest extends XMLHttpRequestEventTarget{
|
87
|
97
|
* @param {any} body Body in RNfetchblob flavor
|
88
|
98
|
*/
|
89
|
99
|
send(body) {
|
|
100
|
+
|
|
101
|
+ if(this._readyState !== XMLHttpRequest.OPENED)
|
|
102
|
+ throw 'InvalidStateError : XMLHttpRequest is not opened yet.'
|
|
103
|
+
|
90
|
104
|
this._sendFlag = true
|
91
|
105
|
log.verbose('XMLHttpRequest send ', body)
|
92
|
106
|
let {_method, _url, _headers } = this
|
|
@@ -123,8 +137,19 @@ export default class XMLHttpRequest extends XMLHttpRequestEventTarget{
|
123
|
137
|
if(this._readyState !== OPENED && this._sendFlag) {
|
124
|
138
|
throw `InvalidStateError : Calling setRequestHeader in wrong state ${this._readyState}`
|
125
|
139
|
}
|
126
|
|
- if(/[^\u0000-\u00ff]/.test(name) || typeof name !== 'string') {
|
127
|
|
- throw `TypeError : Invalid header field name ${name}`
|
|
140
|
+ // UNICODE SHOULD NOT PASS
|
|
141
|
+ if(typeof name !== 'string' || /[^\u0000-\u00ff]/.test(name)) {
|
|
142
|
+ throw 'TypeError : header field name should be a string'
|
|
143
|
+ }
|
|
144
|
+ //
|
|
145
|
+ let invalidPatterns = [
|
|
146
|
+ /[\(\)\>\<\@\,\:\\\/\[\]\?\=\}\{\s\ \u007f\;\t\0\v\r]/,
|
|
147
|
+ /tt/
|
|
148
|
+ ]
|
|
149
|
+ for(let i in invalidPatterns) {
|
|
150
|
+ if(invalidPatterns[i].test(name) || typeof name !== 'string') {
|
|
151
|
+ throw `SyntaxError : Invalid header field name ${name}`
|
|
152
|
+ }
|
128
|
153
|
}
|
129
|
154
|
this._headers[name] = value
|
130
|
155
|
}
|
|
@@ -160,9 +185,9 @@ export default class XMLHttpRequest extends XMLHttpRequestEventTarget{
|
160
|
185
|
}
|
161
|
186
|
|
162
|
187
|
getAllResponseHeaders():string | null {
|
163
|
|
- log.verbose('XMLHttpRequest get all headers',this._task.taskId, this._responseHeaders)
|
|
188
|
+ log.verbose('XMLHttpRequest get all headers', this._responseHeaders)
|
164
|
189
|
if(!this._responseHeaders)
|
165
|
|
- return null
|
|
190
|
+ return ''
|
166
|
191
|
let result = ''
|
167
|
192
|
let respHeaders = this.responseHeaders
|
168
|
193
|
for(let i in respHeaders) {
|
|
@@ -202,10 +227,10 @@ export default class XMLHttpRequest extends XMLHttpRequestEventTarget{
|
202
|
227
|
|
203
|
228
|
_onError(err) {
|
204
|
229
|
log.verbose('XMLHttpRequest error', err)
|
205
|
|
- this.statusText = err
|
206
|
|
- this.status = String(err).match(/\d+/)
|
207
|
|
- this.status = this.status ? Math.floor(this.status) : 404
|
208
|
|
- this.readyState = XMLHttpRequest.DONE
|
|
230
|
+ this._statusText = err
|
|
231
|
+ this._status = String(err).match(/\d+/)
|
|
232
|
+ this._status = this._status ? Math.floor(this.status) : 404
|
|
233
|
+ this._readyState = XMLHttpRequest.DONE
|
209
|
234
|
if(String(err).match('timeout') !== null) {
|
210
|
235
|
this.dispatchEvent('timeout')
|
211
|
236
|
if(this.ontimeout)
|
|
@@ -223,7 +248,6 @@ export default class XMLHttpRequest extends XMLHttpRequestEventTarget{
|
223
|
248
|
_onDone(resp) {
|
224
|
249
|
log.verbose('XMLHttpRequest done', this._task.taskId, this)
|
225
|
250
|
this.statusText = '200 OK'
|
226
|
|
- this._status = 200
|
227
|
251
|
switch(resp.type) {
|
228
|
252
|
case 'base64' :
|
229
|
253
|
if(this.responseType === 'json') {
|
|
@@ -306,7 +330,7 @@ export default class XMLHttpRequest extends XMLHttpRequestEventTarget{
|
306
|
330
|
}
|
307
|
331
|
|
308
|
332
|
get responseHeaders() {
|
309
|
|
- log.verbose('get responseHeaders', this._task.taskId, this._responseHeaders)
|
|
333
|
+ log.verbose('get responseHeaders', this._responseHeaders)
|
310
|
334
|
return this._responseHeaders
|
311
|
335
|
}
|
312
|
336
|
|