Skip to content

Commit

Permalink
chore: revert support of duplicate form data fields in multipart post…
Browse files Browse the repository at this point in the history
… data (#30127)

We want to adopt FormData API for the requests.

This is a revert of 4b3c596 and
a849ea9

Reference #28070
  • Loading branch information
yury-s committed Mar 26, 2024
1 parent e4403dd commit 021c5c1
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 250 deletions.
2 changes: 1 addition & 1 deletion docs/src/api/class-apirequestcontext.md
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,7 @@ api_request_context.post("https://example.com/api/createBook", data=data)

```csharp
var data = new Dictionary<string, object>() {
{ "firstName", "John" },
{ "firstNam", "John" },
{ "lastName", "Doe" }
};
await request.PostAsync("https://example.com/api/createBook", new() { DataObject = data });
Expand Down
69 changes: 1 addition & 68 deletions docs/src/api/class-formdata.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,72 +14,6 @@ FormData form = FormData.create()
page.request().post("http://localhost/submit", RequestOptions.create().setForm(form));
```

## method: FormData.add
* since: v1.43
- returns: <[FormData]>

Adds a field to the form. File values can be passed either as `Path` or as `FilePayload`.
Multiple fields with the same name can be added.

```java
import com.microsoft.playwright.options.FormData;
...
FormData form = FormData.create()
// Only name and value are set.
.add("firstName", "John")
// Name and value are set, filename and Content-Type are inferred from the file path.
.add("attachment", Paths.get("pic.jpg"))
// Name, value, filename and Content-Type are set.
.add("attachment", new FilePayload("table.csv", "text/csv", Files.readAllBytes(Paths.get("my-tble.csv"))));
page.request().post("http://localhost/submit", RequestOptions.create().setForm(form));
```

```csharp
var multipart = Context.APIRequest.CreateFormData();
// Only name and value are set.
multipart.Add("firstName", "John");
// Name, value, filename and Content-Type are set.
multipart.Add("attachment", new FilePayload()
{
Name = "pic.jpg",
MimeType = "image/jpeg",
Buffer = File.ReadAllBytes("john.jpg")
});
// Name, value, filename and Content-Type are set.
multipart.Add("attachment", new FilePayload()
{
Name = "table.csv",
MimeType = "text/csv",
Buffer = File.ReadAllBytes("my-tble.csv")
});
await Page.APIRequest.PostAsync("https://localhost/submit", new() { Multipart = multipart });
```

### param: FormData.add.name
* since: v1.43
- `name` <[string]>

Field name.

### param: FormData.add.value
* since: v1.43
- `value` <[string]|[boolean]|[int]|[Path]|[Object]>
- `name` <[string]> File name
- `mimeType` <[string]> File type
- `buffer` <[Buffer]> File content

Field value.

### param: FormData.add.value
* since: v1.43
* langs: csharp
- `value` <[string]|[boolean]|[int]|[Object]>
- `name` <[string]> File name
- `mimeType` <[string]> File type
- `buffer` <[Buffer]> File content

Field value.

## method: FormData.create
* since: v1.18
* langs: java
Expand All @@ -102,7 +36,7 @@ FormData form = FormData.create()
// Name and value are set, filename and Content-Type are inferred from the file path.
.set("profilePicture1", Paths.get("john.jpg"))
// Name, value, filename and Content-Type are set.
.set("profilePicture2", new FilePayload("john.jpg", "image/jpeg", Files.readAllBytes(Paths.get("john.jpg"))))
.set("profilePicture2", new FilePayload("john.jpg", "image/jpeg", Files.readAllBytes(Paths.get("john.jpg"))));
.set("age", 30);
page.request().post("http://localhost/submit", RequestOptions.create().setForm(form));
```
Expand All @@ -118,7 +52,6 @@ multipart.Set("profilePicture", new FilePayload()
MimeType = "image/jpeg",
Buffer = File.ReadAllBytes("john.jpg")
});
multipart.Set("age", 30);
await Page.APIRequest.PostAsync("https://localhost/submit", new() { Multipart = multipart });
```

Expand Down
5 changes: 2 additions & 3 deletions docs/src/api/params.md
Original file line number Diff line number Diff line change
Expand Up @@ -405,16 +405,15 @@ An instance of [FormData] can be created via [`method: APIRequestContext.createF

## js-python-fetch-option-multipart
* langs: js, python
- `multipart` <[Object]<[string], [string]|[float]|[boolean]|[ReadStream]|[Object]|Array<[string]|[float]|[boolean]|[ReadStream]|[Object]>>>
- `multipart` <[Object]<[string], [string]|[float]|[boolean]|[ReadStream]|[Object]>>
- `name` <[string]> File name
- `mimeType` <[string]> File type
- `buffer` <[Buffer]> File content

Provides an object that will be serialized as html form using `multipart/form-data` encoding and sent as
this request body. If this parameter is specified `content-type` header will be set to `multipart/form-data`
unless explicitly provided. File values can be passed either as [`fs.ReadStream`](https://nodejs.org/api/fs.html#fs_class_fs_readstream)
or as file-like object containing file name, mime-type and its content. If the value is an array, each element
will be sent as a separate field with the same name.
or as file-like object containing file name, mime-type and its content.

## csharp-fetch-option-multipart
* langs: csharp
Expand Down
27 changes: 9 additions & 18 deletions packages/playwright-core/src/client/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export type FetchOptions = {
headers?: Headers,
data?: string | Buffer | Serializable,
form?: { [key: string]: string|number|boolean; };
multipart?: { [key: string]: string|number|boolean|fs.ReadStream|FilePayload|Array<string|number|boolean|fs.ReadStream|FilePayload>; };
multipart?: { [key: string]: string|number|boolean|fs.ReadStream|FilePayload; };
timeout?: number,
failOnStatusCode?: boolean,
ignoreHTTPSErrors?: boolean,
Expand Down Expand Up @@ -188,11 +188,15 @@ export class APIRequestContext extends ChannelOwner<channels.APIRequestContextCh
multipartData = [];
// Convert file-like values to ServerFilePayload structs.
for (const [name, value] of Object.entries(options.multipart)) {
if (Array.isArray(value)) {
for (const item of value)
multipartData.push(await toFormField(name, item));
if (isFilePayload(value)) {
const payload = value as FilePayload;
if (!Buffer.isBuffer(payload.buffer))
throw new Error(`Unexpected buffer type of 'data.${name}'`);
multipartData.push({ name, file: filePayloadToJson(payload) });
} else if (value instanceof fs.ReadStream) {
multipartData.push({ name, file: await readStreamToJson(value as fs.ReadStream) });
} else {
multipartData.push(await toFormField(name, value));
multipartData.push({ name, value: String(value) });
}
}
}
Expand Down Expand Up @@ -230,19 +234,6 @@ export class APIRequestContext extends ChannelOwner<channels.APIRequestContextCh
}
}

async function toFormField(name: string, value: string|number|boolean|fs.ReadStream|FilePayload): Promise<channels.FormField> {
if (isFilePayload(value)) {
const payload = value as FilePayload;
if (!Buffer.isBuffer(payload.buffer))
throw new Error(`Unexpected buffer type of 'data.${name}'`);
return { name, file: filePayloadToJson(payload) };
} else if (value instanceof fs.ReadStream) {
return { name, file: await readStreamToJson(value as fs.ReadStream) };
} else {
return { name, value: String(value) };
}
}

function isJsonParsable(value: any) {
if (typeof value !== 'string')
return false;
Expand Down

0 comments on commit 021c5c1

Please sign in to comment.