-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrequest-stream.js
62 lines (59 loc) · 1.68 KB
/
request-stream.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
const https = require('https');
const { URL } = require('url');
// thanks stefanmaric:
// https://gist.github.com/stefanmaric/895f51652060a820e2ee7f164af87948
const defer = () => {
const bag = {}
return Object.assign(
new Promise((resolve, reject) => Object.assign(bag, { resolve, reject })),
bag
)
}
module.exports = (req_options) => {
// returns Promise<response:ReadableStream> | Promise<{req:WritableStream,res:Promise<Object>}
// the second form if the method is 'PUT'
// res is an unresolved promise, while req is ready to use WritableStream.
// ratio: when putting a huge file, typically you get back a small response.
// also the api want to deal with short error message
return new Promise((resolve, reject) => {
let url = new URL(req_options.url);
let options = {
method:req_options.method,
port:443,
hostname:url.hostname,
path:url.pathname + url.search,
headers:req_options.headers || {}
};
let resP = defer();
let req = https.request(options, (res) => {
if (req_options.method != 'PUT') {
resolve(res);
} else {
let chunks = [];
let body = '';
res.on('data', (chunk) => {
body += chunk;
chunks.push(chunk);
});
res.on('end', () => {
resP.resolve({
body:body,
chunks:chunks,
statusCode:res.statusCode,
headers:res.headers
});
});
}
req.end();
});
if (req_options.method == 'PUT') {
resolve({req, res: resP});
}
req.on('error', (e) => {
reject(e);
});
if (req_options.method != 'PUT') {
req.end();
}
});
};