forked from farhoodlabs/paperclip
fix(plugin): fail fast on upload protocol drift
This commit is contained in:
@@ -123,6 +123,15 @@ export class FastUploadInterceptor {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const activeUpload = this.findActiveUploadForCommand(command);
|
||||||
|
if (activeUpload) {
|
||||||
|
this.buffers.delete(activeUpload.tempPath);
|
||||||
|
return {
|
||||||
|
action: "error",
|
||||||
|
message: `Fast upload protocol violation for ${activeUpload.upload.targetPath}; retry the upload from the beginning.`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return { action: "passthrough", reason: "no upload pattern" };
|
return { action: "passthrough", reason: "no upload pattern" };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,4 +142,13 @@ export class FastUploadInterceptor {
|
|||||||
get pendingCount(): number {
|
get pendingCount(): number {
|
||||||
return this.buffers.size;
|
return this.buffers.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private findActiveUploadForCommand(command: string): { tempPath: string; upload: BufferedUpload } | null {
|
||||||
|
for (const [tempPath, upload] of this.buffers) {
|
||||||
|
if (command.includes(`'${tempPath}'`)) {
|
||||||
|
return { tempPath, upload };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ describe("FastUploadInterceptor", () => {
|
|||||||
).toMatchObject({ action: "passthrough", reason: "finalize without buffered state" });
|
).toMatchObject({ action: "passthrough", reason: "finalize without buffered state" });
|
||||||
});
|
});
|
||||||
|
|
||||||
it("does not intercept chunks with padding before the end", () => {
|
it("fails fast when an unrecognized command targets an active upload", () => {
|
||||||
const interceptor = new FastUploadInterceptor();
|
const interceptor = new FastUploadInterceptor();
|
||||||
const target = "/workspace/file.bin";
|
const target = "/workspace/file.bin";
|
||||||
|
|
||||||
@@ -56,10 +56,12 @@ describe("FastUploadInterceptor", () => {
|
|||||||
),
|
),
|
||||||
).toMatchObject({ action: "ack" });
|
).toMatchObject({ action: "ack" });
|
||||||
|
|
||||||
expect(
|
const decision = interceptor.decide(`printf '%s' 'aGVs=bG8=' >> '${target}.paperclip-upload.b64'`);
|
||||||
interceptor.decide(`printf '%s' 'aGVs=bG8=' >> '${target}.paperclip-upload.b64'`),
|
expect(decision).toMatchObject({
|
||||||
).toMatchObject({ action: "passthrough", reason: "no upload pattern" });
|
action: "error",
|
||||||
expect(interceptor.pendingCount).toBe(1);
|
message: expect.stringContaining("Fast upload protocol violation"),
|
||||||
|
});
|
||||||
|
expect(interceptor.pendingCount).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("fails fast when data arrives after a padded chunk", () => {
|
it("fails fast when data arrives after a padded chunk", () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user