Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions packages/insomnia/src/main/importers/importers/curl.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,78 @@ describe('curl', () => {
expected: { body: { text: 'key=value' } },
},

// --form / -F flags (multipart/form-data)
{
name: 'should handle --form with plain key=value',
curl: "curl -X POST https://example.com -H 'Content-Type: multipart/form-data' --form 'field=value'",
expected: {
body: {
mimeType: 'multipart/form-data',
params: [{ name: 'field', value: 'value', type: 'text' }],
},
},
},
{
name: 'should handle --form with @filename',
curl: "curl -X POST https://example.com -H 'Content-Type: multipart/form-data' --form 'file=@/tmp/a.json'",
expected: {
body: {
mimeType: 'multipart/form-data',
params: [{ name: 'file', fileName: '/tmp/a.json', type: 'file' }],
},
},
},
{
name: 'should strip ;type= modifier from --form file value',
curl: "curl -X POST https://example.com -H 'Content-Type: multipart/form-data' --form 'data=@/tmp/a.json;type=application/json'",
expected: {
body: {
mimeType: 'multipart/form-data',
params: [{ name: 'data', fileName: '/tmp/a.json', type: 'file' }],
},
},
},
{
name: 'should strip ;filename= modifier from --form file value',
curl: "curl -X POST https://example.com -H 'Content-Type: multipart/form-data' --form 'upload=@/tmp/a.bin;filename=renamed.bin'",
expected: {
body: {
mimeType: 'multipart/form-data',
params: [{ name: 'upload', fileName: '/tmp/a.bin', type: 'file' }],
},
},
},
{
name: 'should strip multiple chained modifiers from --form file value',
curl: "curl -X POST https://example.com -H 'Content-Type: multipart/form-data' --form 'upload=@/tmp/a.bin;type=application/octet-stream;filename=renamed.bin'",
expected: {
body: {
mimeType: 'multipart/form-data',
params: [{ name: 'upload', fileName: '/tmp/a.bin', type: 'file' }],
},
},
},
{
name: 'should strip ;type= modifier from --form text value',
curl: "curl -X POST https://example.com -H 'Content-Type: multipart/form-data' --form 'field=value;type=text/csv'",
expected: {
body: {
mimeType: 'multipart/form-data',
params: [{ name: 'field', value: 'value', type: 'text' }],
},
},
},
{
name: 'should handle -F alias the same as --form',
curl: "curl -X POST https://example.com -H 'Content-Type: multipart/form-data' -F 'data=@/tmp/a.json;type=application/json'",
expected: {
body: {
mimeType: 'multipart/form-data',
params: [{ name: 'data', fileName: '/tmp/a.json', type: 'file' }],
},
},
},

// -H flags
{
name: 'should handle -H with space after colon',
Expand Down
19 changes: 15 additions & 4 deletions packages/insomnia/src/main/importers/importers/curl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,16 +168,27 @@ const extractBody = (
...((pairsByName.form as string[] | undefined) || []),
...((pairsByName.F as string[] | undefined) || []),
].map(str => {
const [name, value] = str.split('=');
const equalsIndex = str.indexOf('=');
if (equalsIndex === -1) {
return { name: str, value: '', type: 'text' } as Parameter;
}
const name = str.slice(0, equalsIndex);
const rawValue = str.slice(equalsIndex + 1);
// curl --form values support trailing modifiers separated by `;`, e.g.
// `@file;type=application/json`, `@file;filename=other.csv`. Only the
// portion before the first `;` is the content (a filename when prefixed
// with `@`, a literal value otherwise). See `curl --manual`.
const semiIndex = rawValue.indexOf(';');
const content = semiIndex === -1 ? rawValue : rawValue.slice(0, semiIndex);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Respect quoted semicolons in --form values

Splitting rawValue at the first ; breaks valid curl -F/--form syntax where semicolons are part of quoted data or filenames (for example, -F 'colors="red; green; blue";type=text/x-myapp' and quoted filenames containing ; shown in curl --manual). In those cases this now truncates imported content to the substring before the first semicolon, producing corrupted multipart field values or file paths instead of preserving the quoted literal.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handled in b95c2db. The form modifier parser now respects quoted semicolons and unquotes form values/filenames.

const item: Parameter = {
name,
};

if (value.indexOf('@') === 0) {
item.fileName = value.slice(1);
if (content.indexOf('@') === 0) {
item.fileName = content.slice(1);
item.type = 'file';
} else {
item.value = value;
item.value = content;
item.type = 'text';
}

Expand Down