1 | var middleware = require('./middleware')
|
2 | var http = require('http')
|
3 | var https = require('https')
|
4 | var proxyForUrl = require('proxy-from-env').getProxyForUrl
|
5 | var urlUtils = require('url')
|
6 | var merge = require('../merge')
|
7 | var HttpsProxyAgent = require('https-proxy-agent')
|
8 | var obfuscateUrlPassword = require('../obfuscateUrlPassword')
|
9 |
|
10 | function nodeRequest (request, options, protocol, withResponse) {
|
11 | if (protocol === 'https:') {
|
12 | return https.request(merge(request, options.https), withResponse)
|
13 | } else {
|
14 | return http.request(merge(request, options.http), withResponse)
|
15 | }
|
16 | }
|
17 |
|
18 | function proxyUrl (request, proxy) {
|
19 | var url = urlUtils.parse(request.url)
|
20 | var proxyUrl = urlUtils.parse(proxy)
|
21 |
|
22 | request.headers.host = url.hostname
|
23 |
|
24 | if (url.protocol === 'https:') {
|
25 | url.agent = new HttpsProxyAgent(proxy)
|
26 | return url
|
27 | } else {
|
28 | if (proxyUrl.auth) {
|
29 | request.headers['proxy-authorization'] = 'Basic ' + Buffer.from(proxyUrl.auth).toString('base64')
|
30 | }
|
31 |
|
32 | return {
|
33 | hostname: proxyUrl.hostname,
|
34 | port: proxyUrl.port,
|
35 | path: request.url
|
36 | }
|
37 | }
|
38 | }
|
39 |
|
40 | function parseUrl (request) {
|
41 | var proxy = proxyForUrl(request.url) || request.options.proxy
|
42 |
|
43 | if (proxy) {
|
44 | return proxyUrl(request, proxy)
|
45 | } else {
|
46 | return urlUtils.parse(request.url)
|
47 | }
|
48 | }
|
49 |
|
50 | module.exports = middleware('http', function (request) {
|
51 | return new Promise(function (resolve, reject) {
|
52 | var url = parseUrl(request)
|
53 |
|
54 | var req = nodeRequest(
|
55 | {
|
56 | hostname: url.hostname,
|
57 | port: url.port,
|
58 | method: request.method,
|
59 | path: url.path,
|
60 | headers: request.headers,
|
61 | agent: url.agent
|
62 | },
|
63 | request.options,
|
64 | url.protocol,
|
65 | function (res) {
|
66 | return resolve({
|
67 | statusCode: res.statusCode,
|
68 | statusText: http.STATUS_CODES[res.statusCode],
|
69 | url: request.url,
|
70 | headers: res.headers,
|
71 | body: res
|
72 | })
|
73 | }
|
74 | )
|
75 |
|
76 | if (request.options.timeout) {
|
77 | req.setTimeout(request.options.timeout)
|
78 |
|
79 | req.on('timeout', function () {
|
80 | var msg = request.method.toUpperCase() + ' ' + obfuscateUrlPassword(request.url) + ' => timeout (' + request.options.timeout + 'ms)'
|
81 | reject(new Error(msg))
|
82 | })
|
83 | }
|
84 |
|
85 | req.on('error', function (e) {
|
86 | reject(e)
|
87 | })
|
88 |
|
89 | if (request.body) {
|
90 | request.body.pipe(req)
|
91 | } else {
|
92 | req.end()
|
93 | }
|
94 | })
|
95 | })
|