OpenAsar/core/src/app/discord_native/renderer/http.js

96 lines
2.7 KiB
JavaScript

"use strict";
const electron = require('electron');
const http = require('http');
const https = require('https');
const {
CONSTANTS_GET
} = require('../common/constants').IPCEvents;
async function getAPIEndpoint() {
const apiEndpoint = await electron.ipcRenderer.invoke(CONSTANTS_GET, 'API_ENDPOINT');
if (apiEndpoint == null || apiEndpoint === '') {
return null;
}
return apiEndpoint;
}
async function makeChunkedRequest(route, chunks, options) {
/**
* Given an array of chunks, make a slow request, only writing chunks
* after a specified amount of time
*
* route: string
* options: object
* method: the method of the request
* contentType: the content type of the request
* chunkInterval: how long to wait to upload a chunk after the last chunk was flushed
* token: the token to make an authorized request from
* chunks: chunked body of the request to upload
*/
const {
method,
chunkInterval,
token,
contentType
} = options;
let httpModule = http;
if (route.startsWith('https')) {
httpModule = https;
}
// we will force the URL to hit only API_ENDPOINT
const apiEndpoint = await getAPIEndpoint();
if (apiEndpoint == null) {
throw new Error('missing api endpoint setting');
}
const apiEndpointUrl = new URL(apiEndpoint);
const url = new URL(route, apiEndpoint);
url.protocol = apiEndpointUrl.protocol;
url.host = apiEndpointUrl.host;
if (!url.pathname.startsWith(apiEndpointUrl.pathname)) {
url.pathname = `${apiEndpointUrl.pathname}${url.pathname}`;
}
return new Promise(async (resolve, reject) => {
let writeTimeout;
const req = httpModule.request(url.toString(), {
method,
headers: {
authorization: token,
'Content-Type': contentType,
'Content-Length': Buffer.byteLength(chunks.join(''))
}
}, res => {
let responseData = '';
res.setEncoding('utf8');
res.on('data', chunk => {
responseData += chunk;
});
res.on('end', () => {
resolve({
status: res.statusCode,
body: responseData
});
});
});
req.on('error', e => {
if (writeTimeout != null) {
clearTimeout(writeTimeout);
}
reject(e);
});
for (let i = 0; i < chunks.length; i++) {
await new Promise(resolve => {
req.write(chunks[i], () => {
writeTimeout = setTimeout(resolve, chunkInterval);
});
});
}
req.end();
});
}
module.exports = {
getAPIEndpoint,
makeChunkedRequest: function (route, chunks, options, callback) {
makeChunkedRequest(route, chunks, options).then(body => callback(null, body)).catch(err => callback(err));
}
};