Skip to content

Commit e1ccff0

Browse files
committed
feat: downloading shows md5 hash
1 parent b73d12b commit e1ccff0

3 files changed

Lines changed: 21 additions & 4 deletions

File tree

src/commands/test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ export default defineCommand({
188188
console.log(
189189
renderMultiTable(
190190
"Download Comparison",
191-
["Mode", "Conns", "Time", "Bytes", "Speed"],
191+
["Mode", "Conns", "Time", "Bytes", "Speed", "MD5"],
192192
downloadRows([
193193
{ label: "Single", result: singleResult },
194194
...(canMulti

src/functions/downloadFunctions.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as dns from "node:dns/promises";
22
import * as net from "node:net";
33
import * as tls from "node:tls";
4+
import { createHash } from "node:crypto";
45
import { headers } from "../library/http";
56
import { LinkInformation } from "./linkValidation";
67

@@ -154,6 +155,7 @@ export interface DownloadResult {
154155
avgBytesPerSecond: number;
155156
statusCode: number | null;
156157
connections: number;
158+
md5: string | null;
157159
}
158160

159161
export interface DownloadProgress {
@@ -166,6 +168,7 @@ async function downloadOnce(
166168
link: string,
167169
range: { start: number; end: number } | undefined,
168170
onBytes: (delta: number) => void,
171+
onChunk?: (chunk: Buffer) => void,
169172
): Promise<{ statusCode: number | null; bytes: number }> {
170173
const url = new URL(link);
171174
const isHttps = url.protocol === "https:";
@@ -225,12 +228,14 @@ async function downloadOnce(
225228
const bodyChunk = headerBuf.subarray(bodyStart);
226229
bytes += bodyChunk.length;
227230
onBytes(bodyChunk.length);
231+
onChunk?.(bodyChunk);
228232
}
229233
headerBuf = Buffer.alloc(0);
230234
}
231235
} else {
232236
bytes += chunk.length;
233237
onBytes(chunk.length);
238+
onChunk?.(chunk);
234239
}
235240
});
236241

@@ -269,6 +274,7 @@ export async function downloadFull(
269274
};
270275

271276
let statusCode: number | null = null;
277+
let md5: string | null = null;
272278

273279
try {
274280
if (useMulti) {
@@ -279,13 +285,22 @@ export async function downloadFull(
279285
const e = Math.floor((size * (i + 1)) / connections) - 1;
280286
ranges.push({ start: s, end: e });
281287
}
288+
const hashers = ranges.map(() => createHash("md5"));
282289
const results = await Promise.all(
283-
ranges.map((r) => downloadOnce(link, r, onBytes)),
290+
ranges.map((r, i) =>
291+
downloadOnce(link, r, onBytes, (chunk) => hashers[i]!.update(chunk)),
292+
),
284293
);
285294
statusCode = results[0]?.statusCode ?? null;
295+
const joined = hashers.map((h) => h.digest("hex")).join("");
296+
md5 = createHash("md5").update(joined).digest("hex");
286297
} else {
287-
const result = await downloadOnce(link, undefined, onBytes);
298+
const hasher = createHash("md5");
299+
const result = await downloadOnce(link, undefined, onBytes, (chunk) =>
300+
hasher.update(chunk),
301+
);
288302
statusCode = result.statusCode;
303+
md5 = hasher.digest("hex");
289304
}
290305
} catch (err) {
291306
const message = err instanceof Error ? err.message : String(err);
@@ -300,5 +315,6 @@ export async function downloadFull(
300315
avgBytesPerSecond: durationMs > 0 ? bytes / (durationMs / 1000) : 0,
301316
statusCode,
302317
connections: useMulti ? connections : 1,
318+
md5,
303319
};
304320
}

src/library/tables.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,14 @@ export function downloadRows(
9292
): string[][] {
9393
return results.map(({ label, result }) =>
9494
result === null
95-
? [label, "—", "—", "—", "—"]
95+
? [label, "—", "—", "—", "—", "—"]
9696
: [
9797
label,
9898
String(result.connections),
9999
formatDuration(result.durationMs),
100100
formatBytes(result.bytes),
101101
formatSpeed(result.avgBytesPerSecond),
102+
result.md5 ?? "—",
102103
],
103104
);
104105
}

0 commit comments

Comments
 (0)