fix: resolve workspace integration blockers (#5)
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
export const MAX_CAD_BYTES = 50 * 1024 * 1024;
|
||||
export const CAD_FETCH_TIMEOUT_MS = 15_000;
|
||||
|
||||
export function assertCadByteLength(byteLength: number): void {
|
||||
if (!Number.isFinite(byteLength) || byteLength < 0) {
|
||||
throw new Error('CAD 파일 크기를 확인할 수 없습니다.');
|
||||
}
|
||||
if (byteLength > MAX_CAD_BYTES) {
|
||||
throw new Error('CAD 파일은 50 MiB 이하여야 합니다.');
|
||||
}
|
||||
}
|
||||
|
||||
export function resolveCadUrl(input: string, base: URL): URL {
|
||||
const url = new URL(input, base);
|
||||
if (!['http:', 'https:'].includes(url.protocol)) {
|
||||
throw new Error('CAD URL은 HTTP(S)만 허용합니다.');
|
||||
}
|
||||
if (url.origin !== base.origin) {
|
||||
throw new Error('CAD URL은 viewer와 같은 origin만 허용합니다.');
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
export async function fetchCadBuffer(url: URL): Promise<ArrayBuffer> {
|
||||
const controller = new AbortController();
|
||||
const timeout = window.setTimeout(() => controller.abort(), CAD_FETCH_TIMEOUT_MS);
|
||||
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
credentials: 'same-origin',
|
||||
signal: controller.signal,
|
||||
});
|
||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
||||
|
||||
const declaredLength = Number(response.headers.get('content-length'));
|
||||
if (Number.isFinite(declaredLength) && declaredLength > 0) {
|
||||
assertCadByteLength(declaredLength);
|
||||
}
|
||||
|
||||
if (!response.body) {
|
||||
const buffer = await response.arrayBuffer();
|
||||
assertCadByteLength(buffer.byteLength);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
const reader = response.body.getReader();
|
||||
const chunks: Uint8Array[] = [];
|
||||
let total = 0;
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done) break;
|
||||
total += value.byteLength;
|
||||
assertCadByteLength(total);
|
||||
chunks.push(value);
|
||||
}
|
||||
|
||||
const data = new Uint8Array(total);
|
||||
let offset = 0;
|
||||
for (const chunk of chunks) {
|
||||
data.set(chunk, offset);
|
||||
offset += chunk.byteLength;
|
||||
}
|
||||
return data.buffer;
|
||||
} catch (error) {
|
||||
if (controller.signal.aborted) {
|
||||
throw new Error('CAD 파일 요청 시간이 초과되었습니다.');
|
||||
}
|
||||
throw error;
|
||||
} finally {
|
||||
window.clearTimeout(timeout);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user