-
Notifications
You must be signed in to change notification settings - Fork 108
/
Copy pathresponse.js
107 lines (94 loc) · 2.77 KB
/
response.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
var EventEmitter = require('events').EventEmitter;
var Response = module.exports = function (xhr) {
this.xhr = xhr;
this.offset = 0;
};
Response.prototype = new EventEmitter;
var capable = {
streaming : true,
status2 : true
};
function parseHeaders (xhr) {
var lines = xhr.getAllResponseHeaders().split(/\r?\n/);
var headers = {};
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
if (line === '') continue;
var m = line.match(/^([^:]+):\s*(.*)/);
if (m) {
var key = m[1].toLowerCase(), value = m[2];
if (headers[key] !== undefined) {
if ((Array.isArray && Array.isArray(headers[key]))
|| headers[key] instanceof Array) {
headers[key].push(value);
}
else {
headers[key] = [ headers[key], value ];
}
}
else {
headers[key] = value;
}
}
else {
headers[line] = true;
}
}
return headers;
}
Response.prototype.getHeader = function (key) {
var header = this.headers[key.toLowerCase()];
// Work around Mozilla bug #608735 [https://bugzil.la/608735], which causes
// getAllResponseHeaders() to return {} if the response is a CORS request.
// xhr.getHeader still works correctly.
return header || this.xhr.getResponseHeader(key);
};
Response.prototype.handle = function () {
var xhr = this.xhr;
if (xhr.readyState === 2 && capable.status2) {
try {
this.statusCode = xhr.status;
this.headers = parseHeaders(xhr);
}
catch (err) {
capable.status2 = false;
}
if (capable.status2) {
this.emit('ready');
}
}
else if (capable.streaming && xhr.readyState === 3) {
try {
if (!this.statusCode) {
this.statusCode = xhr.status;
this.headers = parseHeaders(xhr);
this.emit('ready');
}
}
catch (err) {}
try {
this.write();
}
catch (err) {
capable.streaming = false;
}
}
else if (xhr.readyState === 4) {
if (!this.statusCode) {
this.statusCode = xhr.status;
this.emit('ready');
}
this.write();
if (xhr.error) {
this.emit('error', xhr.responseText);
}
else this.emit('end');
}
};
Response.prototype.write = function () {
var xhr = this.xhr;
if (xhr.responseText.length > this.offset) {
this.emit('data', xhr.responseText.slice(this.offset));
this.offset = xhr.responseText.length;
}
};