1var http = require('http');
2var https = require('https');
3var url = require('url');
4
5var isHttpResource = require('../utils/is-http-resource');
6var isHttpsResource = require('../utils/is-https-resource');
7var override = require('../utils/override');
8
9var HTTP_PROTOCOL = 'http:';
10
11function loadRemoteResource(uri, inlineRequest, inlineTimeout, callback) {
12  var proxyProtocol = inlineRequest.protocol || inlineRequest.hostname;
13  var errorHandled = false;
14  var requestOptions;
15  var fetch;
16
17  requestOptions = override(
18    url.parse(uri),
19    inlineRequest || {}
20  );
21
22  if (inlineRequest.hostname !== undefined) {
23    // overwrite as we always expect a http proxy currently
24    requestOptions.protocol = inlineRequest.protocol || HTTP_PROTOCOL;
25    requestOptions.path = requestOptions.href;
26  }
27
28  fetch = (proxyProtocol && !isHttpsResource(proxyProtocol)) || isHttpResource(uri) ?
29    http.get :
30    https.get;
31
32  fetch(requestOptions, function (res) {
33    var chunks = [];
34    var movedUri;
35
36    if (errorHandled) {
37      return;
38    }
39
40    if (res.statusCode < 200 || res.statusCode > 399) {
41      return callback(res.statusCode, null);
42    } else if (res.statusCode > 299) {
43      movedUri = url.resolve(uri, res.headers.location);
44      return loadRemoteResource(movedUri, inlineRequest, inlineTimeout, callback);
45    }
46
47    res.on('data', function (chunk) {
48      chunks.push(chunk.toString());
49    });
50    res.on('end', function () {
51      var body = chunks.join('');
52      callback(null, body);
53    });
54  })
55  .on('error', function (res) {
56    if (errorHandled) {
57      return;
58    }
59
60    errorHandled = true;
61    callback(res.message, null);
62  })
63  .on('timeout', function () {
64    if (errorHandled) {
65      return;
66    }
67
68    errorHandled = true;
69    callback('timeout', null);
70  })
71  .setTimeout(inlineTimeout);
72}
73
74module.exports = loadRemoteResource;
75