Lightcord/modules/discord_desktop_core/core/app/discord_native/renderer/http.js

111 lines
2.7 KiB
JavaScript
Raw Normal View History

2020-12-12 11:56:28 +01:00
"use strict";
2020-06-27 21:02:48 +02:00
2020-12-12 11:56:28 +01:00
const electron = require('electron');
2020-06-27 21:02:48 +02:00
const http = require('http');
2020-12-12 11:56:28 +01:00
2020-06-27 21:02:48 +02:00
const https = require('https');
2020-12-12 11:56:28 +01:00
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) {
2020-06-27 21:02:48 +02:00
/**
* 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
*/
2020-12-12 11:56:28 +01:00
const {
method,
chunkInterval,
token,
contentType
} = options;
2020-06-27 21:02:48 +02:00
let httpModule = http;
2020-12-12 11:56:28 +01:00
2020-06-27 21:02:48 +02:00
if (route.startsWith('https')) {
httpModule = https;
2020-12-12 11:56:28 +01:00
} // we will force the URL to hit only API_ENDPOINT
const apiEndpoint = await getAPIEndpoint();
if (apiEndpoint == null) {
throw new Error('missing api endpoint setting');
2020-06-27 21:02:48 +02:00
}
2020-12-12 11:56:28 +01:00
const apiEndpointUrl = new URL(apiEndpoint);
const url = new URL(route, apiEndpoint);
url.protocol = apiEndpointUrl.protocol;
url.host = apiEndpointUrl.host;
2020-06-27 21:02:48 +02:00
2020-12-12 11:56:28 +01:00
if (!url.pathname.startsWith(apiEndpointUrl.pathname)) {
url.pathname = `${apiEndpointUrl.pathname}${url.pathname}`;
}
2020-06-27 21:02:48 +02:00
2020-12-12 11:56:28 +01:00
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;
2020-06-27 21:02:48 +02:00
});
2020-12-12 11:56:28 +01:00
res.on('end', () => {
resolve({
status: res.statusCode,
body: responseData
2020-06-27 21:02:48 +02:00
});
2020-12-12 11:56:28 +01:00
});
});
req.on('error', e => {
if (writeTimeout != null) {
clearTimeout(writeTimeout);
2020-06-27 21:02:48 +02:00
}
2020-12-12 11:56:28 +01:00
reject(e);
2020-06-27 21:02:48 +02:00
});
2020-12-12 11:56:28 +01:00
for (let i = 0; i < chunks.length; i++) {
await new Promise(resolve => {
req.write(chunks[i], () => {
writeTimeout = setTimeout(resolve, chunkInterval);
});
});
}
2020-06-27 21:02:48 +02:00
2020-12-12 11:56:28 +01:00
req.end();
});
2020-06-27 21:02:48 +02:00
}
module.exports = {
2020-12-12 11:56:28 +01:00
getAPIEndpoint,
makeChunkedRequest: function (route, chunks, options, callback) {
makeChunkedRequest(route, chunks, options).then(body => callback(null, body)).catch(err => callback(err));
}
2020-06-27 21:02:48 +02:00
};