Skip to content

Commit 29c4d09

Browse files
committed
feat: add support for filename in Content-Disposition header
* feat: implement filename support in Content-Disposition header * test: add test cases for filename in Content-Disposition
1 parent 002bc73 commit 29c4d09

File tree

3 files changed

+46
-2
lines changed

3 files changed

+46
-2
lines changed

packages/abstractions/src/multipartBody.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@ export class MultipartBody implements Parsable {
2727
* @param partContentType the content type of the part to add or replace.
2828
* @param content the content of the part to add or replace.
2929
* @param serializationCallback the serialization callback to use when serializing the part.
30+
* @param fileName the name of the file associated with this part.
3031
*/
31-
public addOrReplacePart<T>(partName: string, partContentType: string, content: T, serializationCallback?: ModelSerializerFunction<Parsable>): void {
32+
public addOrReplacePart<T>(partName: string, partContentType: string, content: T, serializationCallback?: ModelSerializerFunction<Parsable>, fileName?: string): void {
3233
if (!partName) throw new Error("partName cannot be undefined");
3334
if (!partContentType) {
3435
throw new Error("partContentType cannot be undefined");
@@ -39,6 +40,7 @@ export class MultipartBody implements Parsable {
3940
contentType: partContentType,
4041
content,
4142
originalName: partName,
43+
fileName,
4244
serializationCallback,
4345
};
4446
}
@@ -90,6 +92,7 @@ interface MultipartEntry {
9092
contentType: string;
9193
content: any;
9294
originalName: string;
95+
fileName?: string;
9396
serializationCallback?: ModelSerializerFunction<Parsable>;
9497
}
9598

@@ -124,7 +127,7 @@ export const serializeMultipartBody = (writer: SerializationWriter, multipartBod
124127
const part = parts[partName];
125128
writer.writeStringValue("Content-Type", part.contentType);
126129
writer.writeStringValue(undefined, "\r\n");
127-
writer.writeStringValue("Content-Disposition", 'form-data; name="' + part.originalName + '"');
130+
writer.writeStringValue("Content-Disposition", `form-data; name="${part.originalName}"${part.fileName ? `; filename="${part.fileName}"` : ""}`);
128131
writer.writeStringValue(undefined, "\r\n");
129132
writer.writeStringValue(undefined, "\r\n");
130133
if (typeof part.content === "string") {

packages/abstractions/test/common/multipartBody.ts

+28
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,31 @@ describe("multipartBody", () => {
4040
});
4141
//serialize method is tested in the serialization library
4242
});
43+
44+
describe("multipartBody with fileName", () => {
45+
const arrayBuffer = new Uint8Array([0x01, 0x01, 0x01]);
46+
const arrayBuffer2 = new Uint8Array([0x02, 0x02, 0x02]);
47+
48+
it("adds parts with a filename", () => {
49+
const mpBody = new MultipartBody();
50+
mpBody.addOrReplacePart("filepart", "application/octet-stream", arrayBuffer, undefined, "file.txt");
51+
52+
const part = mpBody.listParts()["filepart"];
53+
assert.exists(part);
54+
assert.strictEqual(part.contentType, "application/octet-stream");
55+
assert.strictEqual(part.content, arrayBuffer);
56+
assert.strictEqual(part.fileName, "file.txt");
57+
});
58+
59+
it("updates filename when replacing a part", () => {
60+
const mpBody = new MultipartBody();
61+
mpBody.addOrReplacePart("filepart", "application/octet-stream", arrayBuffer, undefined, "file.txt");
62+
mpBody.addOrReplacePart("filepart", "application/pdf", arrayBuffer2, undefined, "document.pdf");
63+
64+
const part = mpBody.listParts()["filepart"];
65+
assert.exists(part);
66+
assert.strictEqual(part.fileName, "document.pdf");
67+
assert.strictEqual(part.content, arrayBuffer2);
68+
assert.strictEqual(part.contentType, "application/pdf");
69+
});
70+
});

packages/serialization/multipart/test/common/multipartSerializationWriter.ts

+13
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,17 @@ describe("MultipartSerializationWriter", () => {
122122
const multipartSerializationWriter = new MultipartSerializationWriter();
123123
assert.throw(() => multipartSerializationWriter.writeCollectionOfObjectValues(undefined, [testEntity]));
124124
});
125+
126+
it("serializes Content-Disposition with filename", () => {
127+
const mpBody = new MultipartBody();
128+
mpBody.addOrReplacePart("file", "application/octet-stream", byteForTest, undefined, "file.txt");
129+
130+
const multipartSerializationWriter = new MultipartSerializationWriter();
131+
multipartSerializationWriter.writeObjectValue(undefined, mpBody, serializeMultipartBody);
132+
const multipartContent = multipartSerializationWriter.getSerializedContent();
133+
const result = new TextDecoder().decode(multipartContent);
134+
135+
const expectedString = "--" + mpBody.getBoundary() + '\r\nContent-Type: application/octet-stream\r\nContent-Disposition: form-data; name="file"; filename="file.txt"\r\n\r\n' + new TextDecoder().decode(byteForTest) + "\r\n--" + mpBody.getBoundary() + "--\r\n";
136+
assert.equal(result, expectedString);
137+
});
125138
});

0 commit comments

Comments
 (0)