Skip to content

Commit

Permalink
fix: multipart form data boundary gets overridden client-side [INC-14…
Browse files Browse the repository at this point in the history
…1] (#1992)
  • Loading branch information
abvthecity authored Jan 12, 2025
1 parent dca62fe commit 9bc5425
Show file tree
Hide file tree
Showing 8 changed files with 27 additions and 148 deletions.

This file was deleted.

47 changes: 0 additions & 47 deletions packages/fern-docs/bundle/src/server/buildFormData.ts

This file was deleted.

29 changes: 0 additions & 29 deletions packages/fern-docs/bundle/src/server/buildRequestBody.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,16 @@ const PROXY_URL = "https://proxy.ferndocs.com/";
export async function executeProxyRest(
req: ProxyRequest
): Promise<PlaygroundResponse> {
const requestHeaders = { ...req.headers };
requestHeaders["X-Fern-Proxy-Request-Headers"] = Object.keys(
req.headers
).join(",");
const requestHeaders = new Headers(req.headers);
requestHeaders.set(
"X-Fern-Proxy-Request-Headers",
Object.keys(req.headers).join(",")
);

// multipart/form-data will be handled by the fetch API with a boundary, and should not be forwarded
if (req.body?.type === "form-data") {
requestHeaders.delete("Content-Type");
}

const res = await fetch(urljoin(PROXY_URL, req.url), {
method: req.method,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ export async function executeProxyStream(
Object.keys(req.headers).join(",")
);

// multipart/form-data will be handled by the fetch API with a boundary, and should not be forwarded
if (req.body?.type === "form-data") {
requestHeaders.delete("Content-Type");
}

const response = await fetch(urljoin(PROXY_URL, req.url), {
method: req.method,
headers: requestHeaders,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,17 @@ export async function toBodyInit(
const formData = new FormData();
for (const [key, value] of Object.entries(body.value)) {
switch (value.type) {
case "json":
formData.append(key, JSON.stringify(value.value));
case "json": {
formData.append(
key,
value.contentType
? new Blob([JSON.stringify(value.value)], {
type: value.contentType,
})
: JSON.stringify(value.value)
);
break;
}
case "file":
if (value.value?.dataUrl != null) {
const response = await fetch(value.value.dataUrl);
Expand Down
10 changes: 0 additions & 10 deletions packages/workers/proxy/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,6 @@ export default {
}
}

// multipart/form-data will be handled by the fetch API with a boundary, and should not be forwarded
if (
requestHeaders
.get("Content-Type")
?.toLowerCase()
.includes("multipart/form-data")
) {
requestHeaders.delete("Content-Type");
}

const newRequest = new Request(forwardedUrl, {
method: request.method,
headers: requestHeaders,
Expand Down
4 changes: 2 additions & 2 deletions packages/workers/proxy/test/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,8 @@ describe("rest", () => {
return methodNotAllowed();
}

// content-type should not be set because form-data will be automatically parsed and set as multipart/form-data + boundary
expect(headers.get("content-type")).toBeNull();
// the content-type must include a boundary
expect(headers.get("content-type")).toContain("boundary=");
const bodyText = await fromReadableStream(body);
const formData = new FormData();
const boundary = bodyText.split("\r\n")[0];
Expand Down

0 comments on commit 9bc5425

Please sign in to comment.