Skip to content

Commit

Permalink
Merge pull request #133 from pulsar-edit/deedeeg/download/refactor
Browse files Browse the repository at this point in the history
DeeDeeG's February 2024 refactor of the Download microservice (complementary to PR 132)
  • Loading branch information
confused-Techie authored and DeeDeeG committed Feb 3, 2024
2 parents a12f06f + 2dea642 commit 5a86240
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 58 deletions.
44 changes: 37 additions & 7 deletions microservices/download/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@ const utils = require("./utils.js");
const port = parseInt(process.env.PORT) || 8080;

const server = http.createServer(async (req, res) => {
if (typeof req?.url !== "string"){
// Not sure if this error condition is even possible, but handling it anyway
await utils.displayError(req, res, {
code: 500,
msg: "Internal Server Error: Misformed URL"
});
console.log("Download Returned 500 due to the requested URL not being received as a string internally");
return;
}

// Since req.url is our URL plus query params, lets split them first.
const url = req.url.split("?");
const path = url[0];
Expand All @@ -11,21 +21,41 @@ const server = http.createServer(async (req, res) => {
// Set our Request Route
if (path === "/" && req.method === "GET") {

let params = {
if (typeof queryParams !== "string"){
await utils.displayError(req, res, {
code: 400,
msg: "Missing Query Parameters"
});
console.log("Download Returned 400 due to the requested URL having no query parameters");
return;
}

if (queryParams.length > 100){
// Longest valid combo is 36 characters ("os=silicon_mac&type=mac_zip_blockmap"),
// But leaving extra room to update the parameters in the future.
await utils.displayError(req, res, {
code: 414,
msg: "Requested Parameters are Too Long"
});
console.log("Download Returned 414 due to the provided parameters being too long");
return;
}

let validatedParams = {
os: utils.query_os(queryParams),
type: utils.query_type(queryParams)
};

if (!params.os || !params.type) {
if (!validatedParams.os || !validatedParams.type) {
await utils.displayError(req, res, {
code: 503,
msg: "Missing Required Download Parameters"
code: 400,
msg: "Required Download Parameters Missing or Invalid"
});
console.log("Download Returned 503 due to missing os or type");
console.log("Download Returned 400 due to missing or invalid os or type");
return;
}

let redirLink = await utils.findLink(params.os, params.type);
let redirLink = await utils.findLink(validatedParams.os, validatedParams.type);

if (!redirLink.ok) {
await utils.displayError(req, res, redirLink);
Expand All @@ -37,7 +67,7 @@ const server = http.createServer(async (req, res) => {
Location: redirLink.content
}).end();

console.log(`Download Returned: OS: ${params.os} - TYPE: ${params.type} - URL: ${redirLink.content}`);
console.log(`Download Returned: OS: ${validatedParams.os} - TYPE: ${validatedParams.type} - URL: ${redirLink.content}`);


} else {
Expand Down
97 changes: 46 additions & 51 deletions microservices/download/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,12 @@ const https = require("node:https");
const bins = require("./bins.js");
let TOKEN = process.env.GH_TOKEN_DOWNLOAD_MICROSERVICE;

const VALID_OS = [ "linux", "arm_linux", "silicon_mac", "intel_mac", "windows" ];
const VALID_TYPE = [
"linux_appimage",
"linux_tar",
"linux_rpm",
"linux_deb",
"windows_setup",
"windows_portable",
"windows_blockmap",
"mac_zip",
"mac_zip_blockmap",
"mac_dmg",
"mac_dmg_blockmap"
];

// Environment Variables Check

if (typeof TOKEN === "undefined") {
if (process.env.PULSAR_STATUS === "dev") {
// We are in dev mode, assign dev values
TOKEN = "123456";
} else {
// We are not in dev mode. Our secrets are gone and the application will fail to work
if (process.env.PULSAR_STATUS !== "dev") {
// We are not in dev mode. Our auth token is gone, and the application may fail to work
// due to rate limiting by GitHub for unauthenticated API requests.
console.log("Missing Required Environment Variable: 'GH_TOKEN_DOWNLOAD_MICROSERVICE'!");
process.exit(1);
}
Expand All @@ -43,6 +26,12 @@ function doRequest() {
}
};

if (process.env.PULSAR_STATUS === "dev") {
// We don't expect to be authed in dev mode.
// Fetching releases from GitHub without authentication is fine in dev mode.
delete options.headers['Authorization'];
}

return new Promise((resolve, reject) => {
let data = '';

Expand All @@ -65,52 +54,58 @@ function doRequest() {
});
};

function query_os(param) {
let raw = param; // The query string. From the URL string split by `?`
let prov = undefined;

if (typeof raw !== "string") {
function query_os(queryString) {
if (typeof queryString !== "string") {
return false;
}

let full = raw.split("&");
const allParams = queryString.split("&");
const valid = [ "linux", "arm_linux", "silicon_mac", "intel_mac", "windows" ];

for (const param of full) {
for (const param of allParams) {
if (param.startsWith("os=")) {
prov = param.split("=")[1];
break;
// Returning a result based on the first "os=" param we encounter.
// Users should not provide the same param twice, that would be invalid.
const prov = param.split("=")[1];
return valid.includes(prov) ? prov : false;
}
}

if (prov === undefined) {
return false;
}

return VALID_OS.includes(prov) ? prov : false;
// No "os" query param was provided, return false
return false;
}

function query_type(param) {
let raw = param;
let prov = undefined;

if (typeof raw !== "string") {
function query_type(queryString) {
if (typeof queryString !== "string") {
return false;
}

let full = raw.split("&");

for (const param of full) {
const allParams = queryString.split("&");
const valid = [
"linux_appimage",
"linux_tar",
"linux_rpm",
"linux_deb",
"windows_setup",
"windows_portable",
"windows_blockmap",
"mac_zip",
"mac_zip_blockmap",
"mac_dmg",
"mac_dmg_blockmap"
];

for (const param of allParams) {
if (param.startsWith("type=")) {
prov = param.split("=")[1];
break;
// Returning a result based on the first "type=" param we encounter.
// Users should not provide the same param twice, that would be invalid.
const prov = param.split("=")[1];
return valid.includes(prov) ? prov : false;
}
}

if (prov === undefined) {
return false;
}

return VALID_TYPE.includes(prov) ? prov : false;
// No "type" query param was provided, return false
return false;
}

async function displayError(req, res, errMsg) {
Expand Down Expand Up @@ -185,8 +180,8 @@ async function findLink(os, type) {
console.log(err);
return {
ok: false,
code: 505,
msg: "Server Error"
code: 500,
msg: "Server Error While Finding Link"
};
}
}
Expand Down

0 comments on commit 5a86240

Please sign in to comment.