Skip to content
File

Blob: src/worker/git/operations/fetch/protocol.ts

typescript57 lines
1import type { CacheContext } from "@/worker/cache";
2 
3import { asBodyInit } from "@/worker/common";
4import { responseCacheControl } from "@/worker/cache/policy";
5import { pktLine, delimPkt, flushPkt, concatChunks } from "@/worker/git/core";
6 
7/**
8 * Builds acknowledgment section for git protocol v2.
9 */
10export function buildAckSection(ackOids: string[], done: boolean): Uint8Array[] {
11 const chunks: Uint8Array[] = [];
12 
13 if (!done) {
14 chunks.push(pktLine("acknowledgments\n"));
15 if (ackOids && ackOids.length > 0) {
16 for (let i = 0; i < ackOids.length; i++) {
17 const oid = ackOids[i];
18 const suffix = i === ackOids.length - 1 ? "ready" : "common";
19 chunks.push(pktLine(`ACK ${oid} ${suffix}\n`));
20 }
21 } else {
22 chunks.push(pktLine("NAK\n"));
23 }
24 chunks.push(delimPkt());
25 }
26 chunks.push(pktLine("packfile\n"));
27 
28 return chunks;
29}
30 
31/**
32 * Builds an ACK/NAK-only response when no packfile is needed.
33 */
34export function buildAckOnlyResponse(ackOids: string[], cacheCtx?: CacheContext): Response {
35 const chunks: Uint8Array[] = [pktLine("acknowledgments\n")];
36 
37 if (ackOids && ackOids.length > 0) {
38 for (let i = 0; i < ackOids.length; i++) {
39 const oid = ackOids[i];
40 const suffix = i === ackOids.length - 1 ? "ready" : "common";
41 chunks.push(pktLine(`ACK ${oid} ${suffix}\n`));
42 }
43 } else {
44 chunks.push(pktLine("NAK\n"));
45 }
46 
47 chunks.push(flushPkt());
48 
49 return new Response(asBodyInit(concatChunks(chunks)), {
50 status: 200,
51 headers: {
52 "Content-Type": "application/x-git-upload-pack-result",
53 "Cache-Control": responseCacheControl(cacheCtx),
54 },
55 });
56}