Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80537 views
1
var Stream = require('stream');
2
var util = require('util');
3
4
var Response = module.exports = function (res) {
5
this.offset = 0;
6
this.readable = true;
7
};
8
9
util.inherits(Response, Stream);
10
11
var capable = {
12
streaming : true,
13
status2 : true
14
};
15
16
function parseHeaders (res) {
17
var lines = res.getAllResponseHeaders().split(/\r?\n/);
18
var headers = {};
19
for (var i = 0; i < lines.length; i++) {
20
var line = lines[i];
21
if (line === '') continue;
22
23
var m = line.match(/^([^:]+):\s*(.*)/);
24
if (m) {
25
var key = m[1].toLowerCase(), value = m[2];
26
27
if (headers[key] !== undefined) {
28
29
if (isArray(headers[key])) {
30
headers[key].push(value);
31
}
32
else {
33
headers[key] = [ headers[key], value ];
34
}
35
}
36
else {
37
headers[key] = value;
38
}
39
}
40
else {
41
headers[line] = true;
42
}
43
}
44
return headers;
45
}
46
47
Response.prototype.getResponse = function (xhr) {
48
var respType = String(xhr.responseType).toLowerCase();
49
if (respType === 'blob') return xhr.responseBlob || xhr.response;
50
if (respType === 'arraybuffer') return xhr.response;
51
return xhr.responseText;
52
}
53
54
Response.prototype.getHeader = function (key) {
55
return this.headers[key.toLowerCase()];
56
};
57
58
Response.prototype.handle = function (res) {
59
if (res.readyState === 2 && capable.status2) {
60
try {
61
this.statusCode = res.status;
62
this.headers = parseHeaders(res);
63
}
64
catch (err) {
65
capable.status2 = false;
66
}
67
68
if (capable.status2) {
69
this.emit('ready');
70
}
71
}
72
else if (capable.streaming && res.readyState === 3) {
73
try {
74
if (!this.statusCode) {
75
this.statusCode = res.status;
76
this.headers = parseHeaders(res);
77
this.emit('ready');
78
}
79
}
80
catch (err) {}
81
82
try {
83
this._emitData(res);
84
}
85
catch (err) {
86
capable.streaming = false;
87
}
88
}
89
else if (res.readyState === 4) {
90
if (!this.statusCode) {
91
this.statusCode = res.status;
92
this.emit('ready');
93
}
94
this._emitData(res);
95
96
if (res.error) {
97
this.emit('error', this.getResponse(res));
98
}
99
else this.emit('end');
100
101
this.emit('close');
102
}
103
};
104
105
Response.prototype._emitData = function (res) {
106
var respBody = this.getResponse(res);
107
if (respBody.toString().match(/ArrayBuffer/)) {
108
this.emit('data', new Uint8Array(respBody, this.offset));
109
this.offset = respBody.byteLength;
110
return;
111
}
112
if (respBody.length > this.offset) {
113
this.emit('data', respBody.slice(this.offset));
114
this.offset = respBody.length;
115
}
116
};
117
118
var isArray = Array.isArray || function (xs) {
119
return Object.prototype.toString.call(xs) === '[object Array]';
120
};
121
122