This repository has been archived by the owner on Apr 22, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 18
/
http.js
90 lines (77 loc) · 1.94 KB
/
http.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
const http = require('http')
const https = require('https')
/**
* @typedef HttpOptions
* @property url {string} An absolute or relative URL
* @property method {string} The request method
* @property headers {?map{string, string}} The request headers
* @property data {?any} The request body
*/
/**
* @typedef HttpResponse
* @property url {string} The request URL
* @property status {int} The response status code
* @property headers {map{string, string}} The response headers
* @property data {?string} The response data
* @property res {IncomingMessage} The original response
*/
class Http {
/**
* Creates a new instance of this http(s) client
* @param baseUrl {URL} The base URL
*/
constructor(baseUrl) {
this._baseUrl = baseUrl
}
_buildUrl(url) {
if (/^(?:[a-z]+:)?\/\//i.test(url)) {
return url
} else {
const _url = new URL(this._baseUrl.toString())
_url.pathname += url
return _url.toString()
}
}
/**
* Makes a request
* @param options {HttpOptions} The options for the request
* @returns {Promise<HttpResponse>} A promise resolving to the response
*/
async request(options) {
const url = this._buildUrl(options.url)
let client
if (url.indexOf('https://') === 0) {
client = https
} else if (url.indexOf('http://') === 0) {
client = http
} else {
throw new Error('Invalid URL scheme: ' + url)
}
return new Promise((resolve, reject) => {
const req = client.request(url, {
method: options.method,
headers: options.headers
}, (res) => {
res.setEncoding('utf8')
res.on('error', (err) => reject(err))
let data = ''
res.on('data', (chunk) => data += chunk)
res.on('end', () => {
resolve({
url: url,
status: res.statusCode,
headers: res.headers,
data: data,
res: res
})
})
})
req.on('error', (err) => reject(err))
if ('data' in options) {
req.write(options.data)
}
req.end()
})
}
}
module.exports = Http