Example #1
0
export function listener(request, response): void {
  const urlParts = url.parse(request.url, true);
  if (request.method === "GET") {
    const filename = querystring.unescape(urlParts.pathname.substring(1));
    db.filesCollection.findOne({ _id: filename }, (err, file) => {
      if (err) {
        response.writeHead(500, { Connection: "close" });
        response.end(`${err.name}: ${err.message}`);
        throw err;
      }

      if (!file) {
        response.writeHead(404);
        response.end();
        return;
      }

      response.writeHead(200, {
        "Content-Type": file.contentType || "application/octet-stream",
        "Content-Length": file.length
      });

      const bucket = new GridFSBucket(db.client.db());
      const downloadStream = bucket.openDownloadStreamByName(filename);
      downloadStream.pipe(response);
    });
  } else {
    response.writeHead(405, { Allow: "GET" });
    response.end("405 Method Not Allowed");
  }
}
Example #2
0
        this.renderer.link = function(href, title, text) {
            if (!href) {
                return marked.Renderer.prototype.link.call(this, href, title, text);
            }

            if (this.options.sanitize) {
                try {
                    const prot = decodeURIComponent(unescape(href))
                        .replace(/[^\w:]/g, '')
                        .toLowerCase();
                    if (prot.startsWith('javascript:') || prot.startsWith('vbscript:')) {
                        return '';
                    }
                } catch (e) {
                    return '';
                }
            }

            let onclick = 'cancelClick(event)';
            if (href.startsWith('http://') || href.startsWith('https://')) {
                onclick = 'openLinkWithExternalBrowser(event)';
            } else if (re_ext.test(href)) {
                onclick = 'openMarkdownLink(event)';
            } else if (href.indexOf('#') !== -1) {
                onclick = 'openHashLink(event)';
            }

            self.link_id += 1;
            const id = `md-link-${self.link_id}`;
            self.tooltips += `<paper-tooltip for="${id}" offset="0">${he.encode(href)}</paper-tooltip>`;

            return title !== null ?
                `<a id="${id}" href="${href}" onclick="${onclick}" title=${title}>${text}</a>` :
                `<a id="${id}" href="${href}" onclick="${onclick}">${text}</a>`;
        };
Example #3
0
/* tslint:disable:no-unused-variable */
function openMarkdownLink(event: MouseEvent) {
/* tslint:enable:no-unused-variable */
    event.preventDefault();

    let target = event.target as HTMLAnchorElement;
    while (target !== null) {
        if (target.href) {
            break;
        }
        target = target.parentElement as HTMLAnchorElement;
    }
    if (target === null) {
        console.log('openMarkdownLink(): No target <a> was found', event);
        return;
    }

    let path = unescape(target.href);
    if (path.startsWith('file://')) {
        path = path.slice(7); // Omit 'file://'
    }

    const hash_idx = path.indexOf('#');
    if (hash_idx !== -1) {
        path = path.slice(0, hash_idx);
    }

    if (element_env.openMarkdownDoc) {
        element_env.openMarkdownDoc(path, event.ctrlKey || event.metaKey);
    } else {
        console.log('openMarkdownDoc() is not defined!! Link ignored: ' + path);
    }
}
/**
 * Build url string to request access token, optionally with given query parameters.
 *
 * @param accessTokenEndpoint
 * @param queryParams - key-value pairs which will be added as query parameters
 * @returns {string}
 */
function buildRequestAccessTokenUrl(accessTokenEndpoint: string, queryParams?: Object): string {

  if (queryParams !== undefined) {
    const queryString = qs.stringify(queryParams);

    // we are unescaping again since we did not escape before using querystring and we do not want to break anything
    const unescapedQueryString = qs.unescape(queryString);

    return `${accessTokenEndpoint}?${unescapedQueryString}`;
  } else {
    return accessTokenEndpoint;
  }
}
/**
 * Returns URI to request authorization code with the given parameters.
 *
 * @param authorizationEndpoint - OAuth authorization endpoint
 * @param redirectUri - absolute URI specifying the endpoint the authorization code is responded
 * @param clientId - client id of requesting application
 * @param queryParams - optional set of key-value pairs which will be added as query parameters to the request
 * @returns {string}
 */
function createAuthCodeRequestUri(authorizationEndpoint: string,
                                  redirectUri: string,
                                  clientId: string,
                                  queryParams?: { [index: string]: string }): string {

  const _queryParams = {
    'client_id': clientId,
    'redirect_uri': redirectUri,
    'response_type': 'code',
    ...queryParams
  };

  const queryString = qs.stringify(_queryParams);
  // we are unescaping again since we did not escape before using querystring and we do not want to break anything
  const unescapedQueryString = qs.unescape(queryString);

  return `${authorizationEndpoint}?${unescapedQueryString}`;
}
Example #6
0
  function(req, res) {
    var fqn = querystring.unescape(req.path.substring('/pageDetailsByFQN/'.length));
    log.debug("Getting page details with name: " + fqn);
    queryPermissionWrapper(
      Page.findOne({fullyQualifiedName:fqn}), req.user)
      .exec(function(err, page) {
        log.debug("Got page: " + JSON.stringify(page));
        if (page) {
          fetchPageDetailsForPage(
            page,
            function(pageDetails) {
              res.status(200).type("application/json").send(JSON.stringify(pageDetails));
            },
            function(error) {
              log.error(error);
              res.status(500).end();
            });
        } else {
          Page.findOne({fullyQualifiedName:fqn}, function(err, permissionPage) {
            if (err) {
              log.error(err);
            }

            if (permissionPage) {
              fetchPageDetailsForPage(
                permissionPage,
                function(permissionPageDetails) {
                  permissionPageDetails.page.content = null;
                  permissionPageDetails.editable = false;
                  permissionPageDetails.viewable = false;
                  res.status(200).type("application/json").send(JSON.stringify(permissionPageDetails));
                },
                function(error) {
                  log.error(error);
                  res.status(500).end();
                });
            } else {
              log.error("User tried to access page with permission");
              res.status(404).end();
            }
          });
        }
      });
  }
Example #7
0
/* tslint:disable:no-unused-variable */
function openMarkdownLink(event: MouseEvent) {
    /* tslint:enable:no-unused-variable */
    event.preventDefault();

    let target = event.target as HTMLAnchorElement;
    while (target !== null) {
        if (target.href) {
            break;
        }
        target = target.parentElement as HTMLAnchorElement;
    }

    if (target === null) {
        console.log('openMarkdownLink(): No target <a> was found', event);
        return;
    }

    let path = unescape(target.href);
    if (path.startsWith('file://')) {
        path = path.slice(7); // Omit 'file://'
    }

    const hash_idx = path.indexOf('#');
    if (hash_idx !== -1) {
        path = path.slice(0, hash_idx);
    }

    if (process.platform === 'win32' && path[0] === '/') {
        // Chromium convert relative path of 'href' into absolute path.
        // But on Windows 'foo/bar' is converted into 'file:///C:/foo/bar'.
        // C:/foo/bar is correct. So strip first '/' here (#37).
        path = path.slice(1);
    }

    if (element_env.openMarkdownDoc) {
        element_env.openMarkdownDoc(path, event.ctrlKey || event.metaKey);
    } else {
        console.log('openMarkdownDoc() is not defined!! Link ignored: ' + path);
    }
}
Example #8
0
        let eq: string;
        let options: querystring.ParseOptions;
        let result: SampleObject;

        result = querystring.parse<SampleObject>(str);
        result = querystring.parse<SampleObject>(str, sep);
        result = querystring.parse<SampleObject>(str, sep, eq);
        result = querystring.parse<SampleObject>(str, sep, eq, options);
    }

    {
        let str: string;
        let result: string;

        result = querystring.escape(str);
        result = querystring.unescape(str);
    }
}

////////////////////////////////////////////////////
/// path tests : http://nodejs.org/api/path.html
////////////////////////////////////////////////////

namespace path_tests {

    path.normalize('/foo/bar//baz/asdf/quux/..');

    path.join('/foo', 'bar', 'baz/asdf', 'quux', '..');
    // returns
    //'/foo/bar/baz/asdf'
Example #9
0
var ds: dgram.Socket = dgram.createSocket("udp4", (msg: Buffer, rinfo: dgram.RemoteInfo): void => {
});
var ai: dgram.AddressInfo = ds.address();
ds.send(new Buffer("hello"), 0, 5, 5000, "127.0.0.1", (error: Error, bytes: number): void => {
});

////////////////////////////////////////////////////
///Querystring tests : https://gist.github.com/musubu/2202583
////////////////////////////////////////////////////

var original: string = 'http://example.com/product/abcde.html';
var escaped: string = querystring.escape(original);
console.log(escaped);
// http%3A%2F%2Fexample.com%2Fproduct%2Fabcde.html
var unescaped: string = querystring.unescape(escaped);
console.log(unescaped);
// http://example.com/product/abcde.html

////////////////////////////////////////////////////
/// path tests : http://nodejs.org/api/path.html
////////////////////////////////////////////////////

namespace path_tests {

    path.normalize('/foo/bar//baz/asdf/quux/..');

    path.join('/foo', 'bar', 'baz/asdf', 'quux', '..');
    // returns
    //'/foo/bar/baz/asdf'
Example #10
0
  request.addListener("end", () => {
    const body = getBody();
    const urlParts = url.parse(request.url, true);
    if (PRESETS_REGEX.test(urlParts.pathname)) {
      const presetName = querystring.unescape(
        PRESETS_REGEX.exec(urlParts.pathname)[1]
      );
      if (request.method === "PUT") {
        const preset = JSON.parse(body.toString());
        preset._id = presetName;
        db.presetsCollection.replaceOne(
          { _id: presetName },
          preset,
          { upsert: true },
          err => {
            if (err) return void throwError(err, response);

            cache.del("presets_hash", err => {
              if (err) return void throwError(err, response);

              response.writeHead(200);
              response.end();
            });
          }
        );
      } else if (request.method === "DELETE") {
        db.presetsCollection.deleteOne({ _id: presetName }, err => {
          if (err) return void throwError(err, response);

          cache.del("presets_hash", err => {
            if (err) return void throwError(err, response);

            response.writeHead(200);
            response.end();
          });
        });
      } else {
        response.writeHead(405, { Allow: "PUT, DELETE" });
        response.end("405 Method Not Allowed");
      }
    } else if (OBJECTS_REGEX.test(urlParts.pathname)) {
      const objectName = querystring.unescape(
        OBJECTS_REGEX.exec(urlParts.pathname)[1]
      );
      if (request.method === "PUT") {
        const object = JSON.parse(body.toString());
        object._id = objectName;
        db.objectsCollection.replaceOne(
          { _id: objectName },
          object,
          { upsert: true },
          err => {
            if (err) return void throwError(err, response);

            cache.del("presets_hash", err => {
              if (err) return void throwError(err, response);

              response.writeHead(200);
              response.end();
            });
          }
        );
      } else if (request.method === "DELETE") {
        db.objectsCollection.deleteOne({ _id: objectName }, err => {
          if (err) return void throwError(err, response);

          cache.del("presets_hash", err => {
            if (err) return void throwError(err, response);

            response.writeHead(200);
            response.end();
          });
        });
      } else {
        response.writeHead(405, { Allow: "PUT, DELETE" });
        response.end("405 Method Not Allowed");
      }
    } else if (PROVISIONS_REGEX.test(urlParts.pathname)) {
      const provisionName = querystring.unescape(
        PROVISIONS_REGEX.exec(urlParts.pathname)[1]
      );
      if (request.method === "PUT") {
        const object = {
          _id: provisionName,
          script: body.toString()
        };

        try {
          new vm.Script(`"use strict";(function(){\n${object.script}\n})();`);
        } catch (err) {
          response.writeHead(400);
          response.end(`${err.name}: ${err.message}`);
          return;
        }

        db.provisionsCollection.replaceOne(
          { _id: provisionName },
          object,
          { upsert: true },
          err => {
            if (err) return void throwError(err, response);

            cache.del("presets_hash", err => {
              if (err) return void throwError(err, response);

              response.writeHead(200);
              response.end();
            });
          }
        );
      } else if (request.method === "DELETE") {
        db.provisionsCollection.deleteOne({ _id: provisionName }, err => {
          if (err) return void throwError(err, response);

          cache.del("presets_hash", err => {
            if (err) return void throwError(err, response);

            response.writeHead(200);
            response.end();
          });
        });
      } else {
        response.writeHead(405, { Allow: "PUT, DELETE" });
        response.end("405 Method Not Allowed");
      }
    } else if (VIRTUAL_PARAMETERS_REGEX.test(urlParts.pathname)) {
      const virtualParameterName = querystring.unescape(
        VIRTUAL_PARAMETERS_REGEX.exec(urlParts.pathname)[1]
      );
      if (request.method === "PUT") {
        const object = {
          _id: virtualParameterName,
          script: body.toString()
        };

        try {
          new vm.Script(`"use strict";(function(){\n${object.script}\n})();`);
        } catch (err) {
          response.writeHead(400);
          response.end(`${err.name}: ${err.message}`);
          return;
        }

        db.virtualParametersCollection.replaceOne(
          { _id: virtualParameterName },
          object,
          { upsert: true },
          err => {
            if (err) return void throwError(err, response);

            cache.del("presets_hash", err => {
              if (err) return void throwError(err, response);

              response.writeHead(200);
              response.end();
            });
          }
        );
      } else if (request.method === "DELETE") {
        db.virtualParametersCollection.deleteOne(
          { _id: virtualParameterName },
          err => {
            if (err) return void throwError(err, response);

            cache.del("presets_hash", err => {
              if (err) return void throwError(err, response);

              response.writeHead(200);
              response.end();
            });
          }
        );
      } else {
        response.writeHead(405, { Allow: "PUT, DELETE" });
        response.end("405 Method Not Allowed");
      }
    } else if (TAGS_REGEX.test(urlParts.pathname)) {
      const r = TAGS_REGEX.exec(urlParts.pathname);
      const deviceId = querystring.unescape(r[1]);
      const tag = querystring.unescape(r[2]);
      if (request.method === "POST") {
        db.devicesCollection.updateOne(
          { _id: deviceId },
          { $addToSet: { _tags: tag } },
          { safe: true },
          err => {
            if (err) return void throwError(err, response);
            response.writeHead(200);
            response.end();
          }
        );
      } else if (request.method === "DELETE") {
        db.devicesCollection.updateOne(
          { _id: deviceId },
          { $pull: { _tags: tag } },
          { safe: true },
          err => {
            if (err) return void throwError(err, response);

            response.writeHead(200);
            response.end();
          }
        );
      } else {
        response.writeHead(405, { Allow: "POST, DELETE" });
        response.end("405 Method Not Allowed");
      }
    } else if (FAULTS_REGEX.test(urlParts.pathname)) {
      if (request.method === "DELETE") {
        const faultId = querystring.unescape(
          FAULTS_REGEX.exec(urlParts.pathname)[1]
        );
        const deviceId = faultId.split(":", 1)[0];
        const channel = faultId.slice(deviceId.length + 1);
        db.faultsCollection.deleteOne({ _id: faultId }, err => {
          if (err) return void throwError(err, response);

          if (channel.startsWith("task_")) {
            const objId = new mongodb.ObjectID(channel.slice(5));
            return void db.tasksCollection.deleteOne({ _id: objId }, err => {
              if (err) return void throwError(err, response);

              cache.del(`${deviceId}_tasks_faults_operations`, err => {
                if (err) return void throwError(err, response);

                response.writeHead(200);
                response.end();
              });
            });
          }

          cache.del(`${deviceId}_tasks_faults_operations`, err => {
            if (err) return void throwError(err, response);

            response.writeHead(200);
            response.end();
          });
        });
      } else {
        response.writeHead(405, { Allow: "DELETE" });
        response.end("405 Method Not Allowed");
      }
    } else if (DEVICE_TASKS_REGEX.test(urlParts.pathname)) {
      if (request.method === "POST") {
        const deviceId = querystring.unescape(
          DEVICE_TASKS_REGEX.exec(urlParts.pathname)[1]
        );
        if (body.length) {
          const task = JSON.parse(body.toString());
          task.device = deviceId;
          apiFunctions.insertTasks(task, err => {
            if (err) return void throwError(err, response);

            cache.del(`${deviceId}_tasks_faults_operations`, err => {
              if (err) return void throwError(err, response);

              if (urlParts.query.connection_request != null) {
                apiFunctions.connectionRequest(deviceId, err => {
                  if (err) {
                    response.writeHead(202, err.message, {
                      "Content-Type": "application/json"
                    });
                    response.end(JSON.stringify(task));
                    return;
                  }

                  const taskTimeout =
                    (urlParts.query.timeout &&
                      parseInt(urlParts.query.timeout as string)) ||
                    config.get("DEVICE_ONLINE_THRESHOLD", deviceId);

                  apiFunctions.watchTask(
                    deviceId,
                    task._id,
                    taskTimeout,
                    (err, status) => {
                      if (err) return void throwError(err, response);

                      if (status === "timeout") {
                        response.writeHead(
                          202,
                          "Task queued but not processed",
                          {
                            "Content-Type": "application/json"
                          }
                        );
                        response.end(JSON.stringify(task));
                      } else if (status === "fault") {
                        db.tasksCollection.findOne(
                          { _id: task._id },
                          (err, task2) => {
                            if (err) return void throwError(err, response);

                            response.writeHead(202, "Task faulted", {
                              "Content-Type": "application/json"
                            });
                            response.end(JSON.stringify(task2));
                          }
                        );
                      } else {
                        response.writeHead(200, {
                          "Content-Type": "application/json"
                        });
                        response.end(JSON.stringify(task));
                      }
                    }
                  );
                });
              } else {
                response.writeHead(202, {
                  "Content-Type": "application/json"
                });
                response.end(JSON.stringify(task));
              }
            });
          });
        } else if (urlParts.query.connection_request != null) {
          // No task, send connection request only
          apiFunctions.connectionRequest(deviceId, err => {
            if (err) {
              response.writeHead(504);
              response.end(`${err.name}: ${err.message}`);
              return;
            }
            response.writeHead(200);
            response.end();
          });
        } else {
          response.writeHead(400);
          response.end();
        }
      } else {
        response.writeHead(405, { Allow: "POST" });
        response.end("405 Method Not Allowed");
      }
    } else if (TASKS_REGEX.test(urlParts.pathname)) {
      const r = TASKS_REGEX.exec(urlParts.pathname);
      const taskId = querystring.unescape(r[1]);
      const action = r[2];
      if (!action || action === "/") {
        if (request.method === "DELETE") {
          db.tasksCollection.findOne(
            { _id: new mongodb.ObjectID(taskId) },
            { projection: { device: 1 } },
            (err, task) => {
              if (err) return void throwError(err, response);

              if (!task) {
                response.writeHead(404);
                response.end("Task not found");
                return;
              }

              const deviceId = task.device;
              db.tasksCollection.deleteOne(
                { _id: new mongodb.ObjectID(taskId) },
                err => {
                  if (err) return void throwError(err, response);

                  db.faultsCollection.deleteOne(
                    { _id: `${deviceId}:task_${taskId}` },
                    err => {
                      if (err) return void throwError(err, response);

                      cache.del(`${deviceId}_tasks_faults_operations`, err => {
                        if (err) return void throwError(err, response);

                        response.writeHead(200);
                        response.end();
                      });
                    }
                  );
                }
              );
            }
          );
        } else {
          response.writeHead(405, { Allow: "PUT DELETE" });
          response.end("405 Method Not Allowed");
        }
      } else if (action === "/retry") {
        if (request.method === "POST") {
          db.tasksCollection.findOne(
            { _id: new mongodb.ObjectID(taskId) },
            { projection: { device: 1 } },
            (err, task) => {
              if (err) return void throwError(err, response);

              const deviceId = task.device;
              db.faultsCollection.deleteOne(
                { _id: `${deviceId}:task_${taskId}` },
                err => {
                  if (err) return void throwError(err, response);

                  cache.del(`${deviceId}_tasks_faults_operations`, err => {
                    if (err) return void throwError(err, response);

                    response.writeHead(200);
                    response.end();
                  });
                }
              );
            }
          );
        } else {
          response.writeHead(405, { Allow: "POST" });
          response.end("405 Method Not Allowed");
        }
      } else {
        response.writeHead(404);
        response.end();
      }
    } else if (FILES_REGEX.test(urlParts.pathname)) {
      const filename = querystring.unescape(
        FILES_REGEX.exec(urlParts.pathname)[1]
      );
      if (request.method === "PUT") {
        const metadata = {
          fileType: request.headers.filetype,
          oui: request.headers.oui,
          productClass: request.headers.productclass,
          version: request.headers.version
        };
        const bucket = new mongodb.GridFSBucket(db.client.db());
        const uploadStream = bucket.openUploadStreamWithId(filename, filename, {
          metadata: metadata
        });

        uploadStream.on("error", err => {
          throwError(err, response);
        });

        uploadStream.end(body, () => {
          response.writeHead(201);
          response.end();
        });
      } else if (request.method === "DELETE") {
        const bucket = new mongodb.GridFSBucket(db.client.db());
        bucket.delete((filename as unknown) as mongodb.ObjectId, err => {
          if (err) return void throwError(err, response);

          response.writeHead(200);
          response.end();
        });
      } else {
        response.writeHead(405, { Allow: "PUT, DELETE" });
        response.end("405 Method Not Allowed");
      }
    } else if (PING_REGEX.test(urlParts.pathname)) {
      const host = querystring.unescape(PING_REGEX.exec(urlParts.pathname)[1]);
      exec(`ping -w 1 -i 0.2 -c 3 ${host}`, (err, stdout) => {
        if (err) {
          response.writeHead(404, { "Cache-Control": "no-cache" });
          response.end(`${err.name}: ${err.message}`);
          return;
        }

        response.writeHead(200, {
          "Content-Type": "text/plain",
          "Cache-Control": "no-cache"
        });
        response.end(stdout);
      });
    } else if (DELETE_DEVICE_REGEX.test(urlParts.pathname)) {
      if (request.method !== "DELETE") {
        response.writeHead(405, { Allow: "DELETE" });
        response.end("405 Method Not Allowed");
        return;
      }

      const deviceId = querystring.unescape(
        DELETE_DEVICE_REGEX.exec(urlParts.pathname)[1]
      );
      apiFunctions.deleteDevice(deviceId, err => {
        if (err) return void throwError(err, response);

        response.writeHead(200);
        response.end();
      });
    } else if (QUERY_REGEX.test(urlParts.pathname)) {
      let collectionName = QUERY_REGEX.exec(urlParts.pathname)[1];

      // Convert to camel case
      let i = collectionName.indexOf("_");
      while (i++ >= 0) {
        const up =
          i < collectionName.length ? collectionName[i].toUpperCase() : "";
        collectionName =
          collectionName.slice(0, i - 1) + up + collectionName.slice(i + 1);
        i = collectionName.indexOf("_", i);
      }

      if (request.method !== "GET" && request.method !== "HEAD") {
        response.writeHead(405, { Allow: "GET, HEAD" });
        response.end("405 Method Not Allowed");
        return;
      }

      const collection = db[`${collectionName}Collection`];
      if (!collection) {
        response.writeHead(404);
        response.end("404 Not Found");
        return;
      }

      let q = {};
      if (urlParts.query.query) {
        try {
          q = JSON.parse(urlParts.query.query as string);
        } catch (err) {
          response.writeHead(400);
          response.end(`${err.name}: ${err.message}`);
          return;
        }
      }

      switch (collectionName) {
        case "devices":
          q = query.expand(q);
          break;
        case "tasks":
          q = query.sanitizeQueryTypes(q, {
            _id: v => new mongodb.ObjectID(v),
            timestamp: v => new Date(v),
            retries: Number
          });
          break;
        case "faults":
          q = query.sanitizeQueryTypes(q, {
            timestamp: v => new Date(v),
            retries: Number
          });
      }

      let projection = null;
      if (urlParts.query.projection) {
        projection = {};
        for (const p of (urlParts.query.projection as string).split(","))
          projection[p.trim()] = 1;
      }

      const cur = collection.find(q, { projection: projection });

      if (urlParts.query.sort) {
        const s = JSON.parse(urlParts.query.sort as string);
        const sort = {};
        for (const [k, v] of Object.entries(s)) {
          if (k[k.lastIndexOf(".") + 1] !== "_" && collectionName === "devices")
            sort[`${k}._value`] = v;
          else sort[k] = v;
        }

        cur.sort(sort);
      }

      if (urlParts.query.skip)
        cur.skip(parseInt(urlParts.query.skip as string));

      if (urlParts.query.limit)
        cur.limit(parseInt(urlParts.query.limit as string));

      cur.count(false, (err, total) => {
        if (err) return void throwError(err);

        response.writeHead(200, {
          "Content-Type": "application/json",
          total: total
        });

        if (request.method === "HEAD") {
          response.end();
          return;
        }

        response.write("[\n");
        i = 0;
        cur.forEach(
          item => {
            if (i++) response.write(",\n");
            response.write(JSON.stringify(item));
          },
          err => {
            if (err) return void throwError(err);
            response.end("\n]");
          }
        );
      });
    } else {
      response.writeHead(404);
      response.end("404 Not Found");
    }
  });