Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DeeDeeG's February 2024 refactor of the Download microservice (complementary to PR 132) #133

Merged
merged 4 commits into from
Feb 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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