UNPKG

2.41 kBJavaScriptView Raw
1var middleware = require('./middleware')
2var http = require('http')
3var https = require('https')
4var proxyForUrl = require('proxy-from-env').getProxyForUrl
5var urlUtils = require('url')
6var merge = require('../merge')
7var HttpsProxyAgent = require('https-proxy-agent')
8var obfuscateUrlPassword = require('../obfuscateUrlPassword')
9
10function 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
18function 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
40function 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
50module.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})