Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gulpfile.common.https.mjs « gulp - github.com/thsmi/sieve.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 07aa04ff4fea7d95512dee2032c2c5034ab6395d (plain)
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/*
 * The content of this file is licensed. You may obtain a copy of
 * the license at https://github.com/thsmi/sieve/ or request it via
 * email from the author.
 *
 * Do not remove or change this comment.
 *
 * The initial author of the code is:
 *   Thomas Schmid <schmid-thomas@gmx.net>
 */

import logger from 'gulplog';

import https from 'https';
import fs from 'fs';

const HTTP_SUCCESS_MIN = 200;
const HTTP_SUCCESS_MAX = 299;

const HTTP_REDIRECT_MIN = 300;
const HTTP_REDIRECT_MAX = 399;

/**
 * Checks if the http status code indicates a redirection.
 *
 * @param {int} status
 *   the status to be checked,
 *
 * @returns {boolean}
 *   the true in case the server requested a redirection otherwise false.
 */
function isRedirection(status) {
  return (status >= HTTP_REDIRECT_MIN) && (status <= HTTP_REDIRECT_MAX);
}

/**
 * Checks if the http status code indicates a success.
 *
 * @param {int} status
 *   the status to be checked,
 *
 * @returns {boolean}
 *   the true in case the server signaled a success otherwise false.
 */
function isSuccess(status) {
  return (status >= HTTP_SUCCESS_MIN) && (status <= HTTP_SUCCESS_MAX);
}

/**
 * Fetches a json file from a https url.
 * E.g. used to download github releases via the api.
 *
 * @param {string} url
 *   the json file to be loaded.
 * @returns {string}
 *   the bytes received.
 */
async function fetch(url) {

  logger.debug(`Fetching ${url}`);


  return await new Promise((resolve, reject) => {

    // Github requires to have a user agents set.
    // It should be the username plus the application name.
    //
    // https://developer.github.com/v3/#user-agent-required

    const options = {headers: { 'User-Agent': 'thsmi-sieve' }};
    https.get(url, options, async function (response) {

      try {

        if (isRedirection(response.statusCode)) {
          logger.debug(`Following redirect to ${response.headers.location}`);
          resolve(await fetch(response.headers.location));
          return;
        }

        if (!isSuccess(response.statusCode))
          throw new Error(`Fetching ${url} failed with status code ${response.statusCode}.`);

        let data = "";

        response.on("data", (bytes) => {
          data += bytes;
        });

        response.on('end', () => {
          resolve(JSON.parse(data));
        });

      } catch (ex) {
        reject(new Error(ex));
      }
    });
  });
}

/**
 * Downloads a file from an https url and stores the data into the given file.
 * It follows redirects. Upon a non 200 status code an error is thrown.
 *
 * @param {string} url
 *   the download url.
 * @param {string} destination
 *   the file into which the downloaded data should be stored.
 *   In case the file exists it will be silently overwritten.
 * @returns {undefined}
 */
async function download(url, destination) {

  logger.debug(`Downloading ${url} to ${destination}`);

  return await new Promise((resolve, reject) => {
    // Github requires to have a user agents set.
    // It should be the username plus the application name.
    //
    // https://developer.github.com/v3/#user-agent-required

    const options = {headers: { 'User-Agent': 'thsmi-sieve' }};

    https.get(url, options, async function (response) {

      try {
        if (isRedirection(response.statusCode)) {
          logger.debug(`Following redirect to ${response.headers.location}`);
          await download(response.headers.location, destination);

          resolve();
          return;
        }

        if (!isSuccess(response.statusCode))
          throw new Error(`Downloading ${url} failed with status code ${response.statusCode}.`);

        const file = fs.createWriteStream(destination);

        response.pipe(file);

        file.on('finish', function () {
          file.close(function () {
            resolve();
          });
        });
      } catch (ex) {
        reject(new Error(ex));
      }
    });
  });
}

export default {
  download,
  fetch
};