mirror of
https://github.com/usebruno/bruno.git
synced 2026-07-09 06:55:03 +00:00
fix(mount): survive large and corrupt files when mounting collections (#8514)
This commit is contained in:
committed by
GitHub
parent
7af6150f42
commit
da707ea0d5
@@ -189,7 +189,7 @@ class MountManager {
|
||||
const result = parsed.get(e.relativePath);
|
||||
if (!result) continue;
|
||||
if (result.error) {
|
||||
entry.state.set(e.relativePath, { error: result.error });
|
||||
entry.state.set(e.relativePath, { data: result.data, error: result.error });
|
||||
continue;
|
||||
}
|
||||
entry.state.set(e.relativePath, { data: result.data });
|
||||
|
||||
@@ -182,6 +182,9 @@ const buildTree = (collectionPath, parserResults, options = {}) => {
|
||||
hydrateRequestUuids(data, null, collectionPath);
|
||||
tree.root = data;
|
||||
}
|
||||
if (tree.root && typeof tree.root === 'object') {
|
||||
tree.root.pathname = path.join(collectionPath, relativePath);
|
||||
}
|
||||
}
|
||||
} else if (cls.type === 'folder') {
|
||||
folderRoots.set(path.dirname(relativePath), entry);
|
||||
|
||||
@@ -15,7 +15,8 @@ class Pool {
|
||||
const workers = Math.max(1, size ?? os.availableParallelism());
|
||||
this.#pool = workerpool.pool(WORKER_FILE, {
|
||||
maxWorkers: workers,
|
||||
workerType: 'thread'
|
||||
workerType: 'thread',
|
||||
workerThreadOpts: { resourceLimits: { maxOldGenerationSizeMb: 512 } }
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -5,11 +5,49 @@ const filestore = require('@usebruno/filestore');
|
||||
|
||||
const sha256 = (buf) => crypto.createHash('sha256').update(buf).digest('hex');
|
||||
|
||||
const parseContent = (content, format, type) => {
|
||||
const REDACT_BODY_THRESHOLD = 512 * 1024;
|
||||
|
||||
const parseLargeBruRequest = (content, format) => {
|
||||
const { bruFileStringWithRedactedBody, extractedBodyContent } = filestore.parseRequestAndRedactBody(content, { format });
|
||||
const data = filestore.parseRequest(bruFileStringWithRedactedBody, { format });
|
||||
data.request = data.request || {};
|
||||
data.request.body = data.request.body || {};
|
||||
const body = extractedBodyContent || {};
|
||||
if (body.json) data.request.body.json = body.json;
|
||||
if (body.text) data.request.body.text = body.text;
|
||||
if (body.xml) data.request.body.xml = body.xml;
|
||||
if (body.sparql) data.request.body.sparql = body.sparql;
|
||||
if (body.graphql) {
|
||||
data.request.body.graphql = data.request.body.graphql || {};
|
||||
data.request.body.graphql.query = body.graphql;
|
||||
}
|
||||
return data;
|
||||
};
|
||||
|
||||
const extractBruMeta = (content) => {
|
||||
const data = {};
|
||||
const match = content.match(/meta\s*\{\s*([\s\S]*?)\s*\}/);
|
||||
if (match) {
|
||||
for (const line of match[1].replace(/\r\n/g, '\n').split('\n')) {
|
||||
const idx = line.indexOf(':');
|
||||
if (idx === -1) continue;
|
||||
const key = line.slice(0, idx).trim();
|
||||
const value = line.slice(idx + 1).trim();
|
||||
if (!key || !value) continue;
|
||||
data[key] = Number.isNaN(Number(value)) ? value : Number(value);
|
||||
}
|
||||
}
|
||||
if (data.type === 'http') data.type = 'http-request';
|
||||
else if (data.type === 'graphql') data.type = 'graphql-request';
|
||||
return data;
|
||||
};
|
||||
|
||||
const parseContent = (content, format, type, byteSize) => {
|
||||
if (type === 'config' || format === 'json') return JSON.parse(content);
|
||||
const options = { format };
|
||||
switch (type) {
|
||||
case 'request':
|
||||
if (format === 'bru' && byteSize >= REDACT_BODY_THRESHOLD) return parseLargeBruRequest(content, format);
|
||||
return filestore.parseRequest(content, options);
|
||||
case 'collection':
|
||||
return filestore.parseCollection(content, options);
|
||||
@@ -26,9 +64,16 @@ const parseFile = ({ collectionPath, relativePath, format, type }) => {
|
||||
const absolutePath = path.join(collectionPath, relativePath);
|
||||
const buf = fs.readFileSync(absolutePath);
|
||||
const stat = fs.statSync(absolutePath, { bigint: true });
|
||||
const mtime = stat.mtimeNs;
|
||||
const hash = sha256(buf);
|
||||
const content = buf.toString('utf8');
|
||||
const data = parseContent(content, format, type);
|
||||
return { relativePath, mtime: stat.mtimeNs, hash: sha256(buf), data, format, type };
|
||||
try {
|
||||
const data = parseContent(content, format, type, buf.length);
|
||||
return { relativePath, mtime, hash, data, format, type };
|
||||
} catch (err) {
|
||||
const data = format === 'bru' && type === 'request' ? extractBruMeta(content) : {};
|
||||
return { relativePath, mtime, hash, data, format, type, partial: true, error: { message: err.message, stack: err.stack } };
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = parseFile;
|
||||
|
||||
Reference in New Issue
Block a user