Bug 65013 - POST multipart/form-data cURL code generated from Postman is not imported correctly
Summary: POST multipart/form-data cURL code generated from Postman is not imported cor...
Status: NEW
Alias: None
Product: JMeter
Classification: Unclassified
Component: Main (show other bugs)
Version: Nightly (Please specify date)
Hardware: PC All
: P2 normal (vote)
Target Milestone: JMETER 5.4.1
Assignee: JMeter issues mailing list
URL:
Keywords: PatchAvailable
Depends on:
Blocks:
 
Reported: 2020-12-20 01:03 UTC by eR@SeR
Modified: 2021-01-15 18:03 UTC (History)
0 users



Attachments
cURL and screenshots (130.13 KB, application/x-zip-compressed)
2020-12-20 01:03 UTC, eR@SeR
Details
unquote form parameters (6.40 KB, patch)
2020-12-20 15:50 UTC, Felix Schumacher
Details | Diff
Fixes for multi-header and -parameter and mime detection (9.67 KB, patch)
2020-12-23 09:48 UTC, Felix Schumacher
Details | Diff
Fixes for multi-header and -parameter and mime detection (19.35 KB, patch)
2020-12-23 10:50 UTC, Felix Schumacher
Details | Diff
Fixes for multi-header and -parameter and mime detection (24.32 KB, patch)
2020-12-23 12:29 UTC, Felix Schumacher
Details | Diff
Fixes for multi-header and -parameter and mime detection (32.12 KB, patch)
2020-12-23 14:51 UTC, Felix Schumacher
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description eR@SeR 2020-12-20 01:03:50 UTC
Created attachment 37634 [details]
cURL and screenshots

Hello,

When POST multipart/form-data request is opened in Code/cURL mode in Postman, then entire lines copied and pasted into "Import from cURL" in JMeter, generated HTTP Sampler is not completely correct:

1. Values in Parameters tab have redundant quotes
2. Values in File upload tab/File path have redundant quotes
3. MIME type value in File upload tab is application/octet-stream

If request with real URL and path is executed, the response is:

"java.io.FileNotFoundException: D:\jmxFileLocation"\D:\fileLocation\Desktop.jpg" (The filename, directory name, or volume label syntax is incorrect)
	at java.base/java.io.FileInputStream.open0(Native Method)
	at java.base/java.io.FileInputStream.open(FileInputStream.java:213)
	at java.base/java.io.FileInputStream.<init>(FileInputStream.java:155)
	at org.apache.http.entity.mime.content.FileBody.writeTo(FileBody.java:116)
	at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl$ViewableFileBody.writeTo(HTTPHC4Impl.java:1513)
	at org.apache.http.entity.mime.AbstractMultipartForm.doWriteTo(AbstractMultipartForm.java:134)
	at org.apache.http.entity.mime.AbstractMultipartForm.writeTo(AbstractMultipartForm.java:157)
	at org.apache.http.entity.mime.MultipartFormEntity.writeTo(MultipartFormEntity.java:113)
	at org.apache.http.impl.DefaultBHttpClientConnection.sendRequestEntity(DefaultBHttpClientConnection.java:156)
	at org.apache.http.impl.conn.CPoolProxy.sendRequestEntity(CPoolProxy.java:152)
	at org.apache.http.protocol.HttpRequestExecutor.doSendRequest(HttpRequestExecutor.java:238)
	at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl$2.doSendRequest(HTTPHC4Impl.java:458)
	at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:123)
	at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272)
	at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
	at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
	at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
	at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
	at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.executeRequest(HTTPHC4Impl.java:935)
	at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.sample(HTTPHC4Impl.java:646)
	at org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy.sample(HTTPSamplerProxy.java:66)
	at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1296)
	at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1285)
	at org.apache.jmeter.threads.JMeterThread.doSampling(JMeterThread.java:638)
	at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:558)
	at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:489)
	at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:256)
	at java.base/java.lang.Thread.run(Thread.java:830)"

If the same request is executed when quotes from all values in parameters and file path in file upload tab are removed, and changing application/octet-stream to image/jpeg, response is then OK.

Maybe for some other APIs application/octet-stream might work, but for mine, it doesn't. Is it possible to check the extension and generate the MIME type according to it?

Check attachment for cURL example and screenshots.

Postman 7.36.1
Jmeter 5.4.1 54e820e
Microsoft Windows 10 Pro 64-bit
java version "1.8.0_251"
Comment 1 Felix Schumacher 2020-12-20 10:12:11 UTC
The used curl command from the zip file is:

curl --location --request POST 'http://example.com/api/somepath' \
--header 'Accept-Language: it-IT' \
--header 'HTTP_X_FORWARDED_FOR: 127.0.0.1' \
--form 'FrontsideImage=@"/C:/Users/someuser/Desktop/Desktop.jpg"' \
--form 'BacksideImage=@"/C:/Users/someuser/Desktop/Desktop.jpg"' \
--form 'ApplicationTypeId="13"' \
--form 'Country="ITA"' \
--form 'DocumentType="ID_CARD"'

The filenames are placed together with their quotes into the fields in JMeter (as shown in the images in the zip).

The quotes from around the values of the form parameters are kept, too. (Shown again in the images inside the zip).

So there are two problems reported here:

1) quotes around the values are kept, but curl would drop them
2) the mime type is set to a very generel mime-type (probably curl is doing a better job at guessing the mime-type)
Comment 2 Felix Schumacher 2020-12-20 15:50:56 UTC
Created attachment 37635 [details]
unquote form parameters
Comment 3 Felix Schumacher 2020-12-22 10:21:46 UTC
Can you test the next build from trunk or nightly and report back, whether it fixes your issue?

commit bb0c4557e10278f334844f8c1af873b708981b08
AuthorDate: Tue Dec 22 11:19:21 2020 +0100

    POST multipart/form-data cURL code with quoted arguments is not imported correctly
    
    Bugzilla Id: 65013
---
 .../jmeter/protocol/http/curl/BasicCurlParser.java | 17 ++++++++---
 .../http/gui/action/ParseCurlCommandAction.java    |  9 +++++-
 .../apache/jmeter/curl/BasicCurlParserTest.java    | 34 ++++++++++++++++++++++
 .../gui/action/ParseCurlCommandActionTest.java     | 23 +++++++++++++++
 xdocs/changes.xml                                  |  1 +
 5 files changed, 79 insertions(+), 5 deletions(-)
Comment 4 eR@SeR 2020-12-23 01:34:41 UTC
Hi,

Quotes around parameter values are not generated anymore and if file extension is .png .jpg .jpeg .gif .avi (might be more) MIME type is properly recognized.

However, some commonly used extensions like .bmp .pdf .doc .docx .xls .xlsx .rar .zip etc. are still not recognized and generated MIME type is still application/octet-stream. You can check "Common MIME types" list on https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types and add all mentioned MIME types.

Besides this, I've found a few more findings that might be bugs:

1. If parameter starts with @ like "@somevalue", form-data parameter is put inside Files upload tab instead to remain in Parameters tab.
2. If same header or parameter name with same or different value is added, only last header or parameter is generated. All headers or parameters should be added even if they are duplicated.

cURL example:

curl --location --request POST 'http://example.com/api/somepath' \
--header 'Accept-Language: it-IT' \
--header 'HTTP_X_FORWARDED_FOR: 127.0.0.1' \
--header 'HTTP_X_FORWARDED_FOR: 127.0.0.2' \
--form 'FrontsideImage=@"/C:/Users/someuser/Desktop/Desktop.avi"' \
--form 'BacksideImage=@"/C:/Users/someuser/Desktop/Desktop.jpg"' \
--form 'BacksideImage=@"/C:/Users/someuser/Desktop/Desktop.jpeg"' \
--form 'ApplicationTypeId="13"' \
--form 'Country="ITA"' \
--form 'DocumentType="@ID_CARD"' \
--form 'BacksideImage=@"/C:/Users/n.aleksic/Desktop/BTT flow .xlsx"' \
--form 'ApplicationTypeId="11"'

DocumentType parameter moved to Files upload.
Only one HTTP_X_FORWARDED_FOR header and ApplicationTypeId, BacksideImage parameters are imported.


-----------------------------

And definitely the bug:

3. If URL, header or parameter value is blank, cURL is not imported.

cURL example - URL:

curl --location --request POST '' \
--header 'Accept-Language: it-IT' \
--header 'HTTP_X_FORWARDED_FOR: 127.0.0.1' \
--form 'FrontsideImage=@"/C:/Users/someuser/Desktop/Desktop.avi"' \
--form 'BacksideImage=@"/C:/Users/someuser/Desktop/Desktop.jpg"' \
--form 'ApplicationTypeId="13"' \
--form 'Country="ITA"' \
--form 'DocumentType="ID_CARD"'

Error:

ERROR o.a.j.p.h.g.a.ParseCurlCommandAction: Error creating test plan from cURL command:curl --location --request POST '' \
--header 'Accept-Language: it-IT' \
--header 'HTTP_X_FORWARDED_FOR: 127.0.0.1' \
--form 'FrontsideImage=@"/C:/Users/someuser/Desktop/Desktop.avi"' \
--form 'BacksideImage=@"/C:/Users/someuser/Desktop/Desktop.jpg"' \
--form 'ApplicationTypeId="13"' \
--form 'Country="ITA"' \
--form 'DocumentType="ID_CARD"', error:Unexpected format for command line:curl --location --request POST '' \
--header 'Accept-Language: it-IT' \
--header 'HTTP_X_FORWARDED_FOR: 127.0.0.1' \
--form 'FrontsideImage=@"/C:/Users/someuser/Desktop/Desktop.avi"' \
--form 'BacksideImage=@"/C:/Users/someuser/Desktop/Desktop.jpg"' \
--form 'ApplicationTypeId="13"' \
--form 'Country="ITA"' \
--form 'DocumentType="ID_CARD"', error:Unknown option -h
java.lang.IllegalArgumentException: Unexpected format for command line:curl --location --request POST '' \
--header 'Accept-Language: it-IT' \
--header 'HTTP_X_FORWARDED_FOR: 127.0.0.1' \
--form 'FrontsideImage=@"/C:/Users/someuser/Desktop/Desktop.avi"' \
--form 'BacksideImage=@"/C:/Users/someuser/Desktop/Desktop.jpg"' \
--form 'ApplicationTypeId="13"' \
--form 'Country="ITA"' \
--form 'DocumentType="ID_CARD"', error:Unknown option -h
	at org.apache.jmeter.protocol.http.curl.BasicCurlParser.parse(BasicCurlParser.java:797) ~[ApacheJMeter_http.jar:5.4.1-SNAPSHOT]
	at org.apache.jmeter.protocol.http.gui.action.ParseCurlCommandAction.parseCommands(ParseCurlCommandAction.java:670) ~[ApacheJMeter_http.jar:5.4.1-SNAPSHOT]
	at org.apache.jmeter.protocol.http.gui.action.ParseCurlCommandAction.actionPerformed(ParseCurlCommandAction.java:619) ~[ApacheJMeter_http.jar:5.4.1-SNAPSHOT]
	at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967) ~[?:?]
	at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2308) ~[?:?]
	at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405) ~[?:?]
	at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262) ~[?:?]
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279) ~[?:?]
	at java.awt.Component.processMouseEvent(Component.java:6636) ~[?:?]
	at javax.swing.JComponent.processMouseEvent(JComponent.java:3342) ~[?:?]
	at java.awt.Component.processEvent(Component.java:6401) ~[?:?]
	at java.awt.Container.processEvent(Container.java:2263) ~[?:?]
	at java.awt.Component.dispatchEventImpl(Component.java:5012) ~[?:?]
	at java.awt.Container.dispatchEventImpl(Container.java:2321) ~[?:?]
	at java.awt.Component.dispatchEvent(Component.java:4844) ~[?:?]
	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4918) ~[?:?]
	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4547) ~[?:?]
	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4488) ~[?:?]
	at java.awt.Container.dispatchEventImpl(Container.java:2307) ~[?:?]
	at java.awt.Window.dispatchEventImpl(Window.java:2762) ~[?:?]
	at java.awt.Component.dispatchEvent(Component.java:4844) ~[?:?]
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772) ~[?:?]
	at java.awt.EventQueue$4.run(EventQueue.java:721) ~[?:?]
	at java.awt.EventQueue$4.run(EventQueue.java:715) ~[?:?]
	at java.security.AccessController.doPrivileged(AccessController.java:391) [?:?]
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85) ~[?:?]
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95) ~[?:?]
	at java.awt.EventQueue$5.run(EventQueue.java:745) ~[?:?]
	at java.awt.EventQueue$5.run(EventQueue.java:743) ~[?:?]
	at java.security.AccessController.doPrivileged(AccessController.java:391) [?:?]
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85) [?:?]
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:742) [?:?]
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203) [?:?]
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124) [?:?]
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113) [?:?]
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109) [?:?]
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) [?:?]
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:90) [?:?]
ERROR o.a.j.p.h.g.a.ParseCurlCommandAction: Error creating test plan from cURL command list:[curl --location --request POST '' \
--header 'Accept-Language: it-IT' \
--header 'HTTP_X_FORWARDED_FOR: 127.0.0.1' \
--form 'FrontsideImage=@"/C:/Users/someuser/Desktop/Desktop.avi"' \
--form 'BacksideImage=@"/C:/Users/someuser/Desktop/Desktop.jpg"' \
--form 'ApplicationTypeId="13"' \
--form 'Country="ITA"' \
--form 'DocumentType="ID_CARD"']
java.lang.IllegalArgumentException: Unexpected format for command line:curl --location --request POST '' \
--header 'Accept-Language: it-IT' \
--header 'HTTP_X_FORWARDED_FOR: 127.0.0.1' \
--form 'FrontsideImage=@"/C:/Users/someuser/Desktop/Desktop.avi"' \
--form 'BacksideImage=@"/C:/Users/someuser/Desktop/Desktop.jpg"' \
--form 'ApplicationTypeId="13"' \
--form 'Country="ITA"' \
--form 'DocumentType="ID_CARD"', error:Unknown option -h
	at org.apache.jmeter.protocol.http.curl.BasicCurlParser.parse(BasicCurlParser.java:797) ~[ApacheJMeter_http.jar:5.4.1-SNAPSHOT]
	at org.apache.jmeter.protocol.http.gui.action.ParseCurlCommandAction.parseCommands(ParseCurlCommandAction.java:670) ~[ApacheJMeter_http.jar:5.4.1-SNAPSHOT]
	at org.apache.jmeter.protocol.http.gui.action.ParseCurlCommandAction.actionPerformed(ParseCurlCommandAction.java:619) ~[ApacheJMeter_http.jar:5.4.1-SNAPSHOT]
	at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967) ~[?:?]
	at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2308) ~[?:?]
	at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405) ~[?:?]
	at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262) ~[?:?]
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279) ~[?:?]
	at java.awt.Component.processMouseEvent(Component.java:6636) ~[?:?]
	at javax.swing.JComponent.processMouseEvent(JComponent.java:3342) ~[?:?]
	at java.awt.Component.processEvent(Component.java:6401) ~[?:?]
	at java.awt.Container.processEvent(Container.java:2263) ~[?:?]
	at java.awt.Component.dispatchEventImpl(Component.java:5012) ~[?:?]
	at java.awt.Container.dispatchEventImpl(Container.java:2321) ~[?:?]
	at java.awt.Component.dispatchEvent(Component.java:4844) ~[?:?]
	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4918) ~[?:?]
	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4547) ~[?:?]
	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4488) ~[?:?]
	at java.awt.Container.dispatchEventImpl(Container.java:2307) ~[?:?]
	at java.awt.Window.dispatchEventImpl(Window.java:2762) ~[?:?]
	at java.awt.Component.dispatchEvent(Component.java:4844) ~[?:?]
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772) ~[?:?]
	at java.awt.EventQueue$4.run(EventQueue.java:721) ~[?:?]
	at java.awt.EventQueue$4.run(EventQueue.java:715) ~[?:?]
	at java.security.AccessController.doPrivileged(AccessController.java:391) [?:?]
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85) ~[?:?]
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95) ~[?:?]
	at java.awt.EventQueue$5.run(EventQueue.java:745) ~[?:?]
	at java.awt.EventQueue$5.run(EventQueue.java:743) ~[?:?]
	at java.security.AccessController.doPrivileged(AccessController.java:391) [?:?]
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85) [?:?]
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:742) [?:?]
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203) [?:?]
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124) [?:?]
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113) [?:?]
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109) [?:?]
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) [?:?]
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:90) [?:?]


-------------------------


cURL example - blank parameter:

curl --location --request POST 'http://example.com/api/somepath' \
--header 'Accept-Language: it-IT' \
--header 'HTTP_X_FORWARDED_FOR: 127.0.0.1' \
--form 'FrontsideImage=@"/C:/Users/someuser/Desktop/Desktop.avi"' \
--form 'BacksideImage=@"/C:/Users/someuser/Desktop/Desktop.jpg"' \
--form 'ApplicationTypeId=""' \
--form 'Country="ITA"' \
--form 'DocumentType="ID_CARD"'

Error:

ERROR o.a.j.p.h.g.a.ParseCurlCommandAction: Error creating test plan from cURL command:curl --location --request POST 'http://example.com/api/somepath' \
--header 'Accept-Language: it-IT' \
--header 'HTTP_X_FORWARDED_FOR: 127.0.0.1' \
--form 'FrontsideImage=@"/C:/Users/someuser/Desktop/Desktop.avi"' \
--form 'BacksideImage=@"/C:/Users/someuser/Desktop/Desktop.jpg"' \
--form 'ApplicationTypeId=""' \
--form 'Country="ITA"' \
--form 'DocumentType="ID_CARD"', error:begin 0, end 1, length 0
java.lang.StringIndexOutOfBoundsException: begin 0, end 1, length 0
	at java.lang.String.checkBoundsBeginEnd(String.java:3720) ~[?:?]
	at java.lang.String.substring(String.java:1909) ~[?:?]
	at org.apache.jmeter.protocol.http.gui.action.ParseCurlCommandAction.setFormData(ParseCurlCommandAction.java:526) ~[ApacheJMeter_http.jar:5.4.1-SNAPSHOT]
	at org.apache.jmeter.protocol.http.gui.action.ParseCurlCommandAction.createSampler(ParseCurlCommandAction.java:313) ~[ApacheJMeter_http.jar:5.4.1-SNAPSHOT]
	at org.apache.jmeter.protocol.http.gui.action.ParseCurlCommandAction.addToTestPlan(ParseCurlCommandAction.java:691) ~[ApacheJMeter_http.jar:5.4.1-SNAPSHOT]
	at org.apache.jmeter.protocol.http.gui.action.ParseCurlCommandAction.actionPerformed(ParseCurlCommandAction.java:636) ~[ApacheJMeter_http.jar:5.4.1-SNAPSHOT]
	at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967) ~[?:?]
	at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2308) ~[?:?]
	at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405) ~[?:?]
	at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262) ~[?:?]
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279) ~[?:?]
	at java.awt.Component.processMouseEvent(Component.java:6636) ~[?:?]
	at javax.swing.JComponent.processMouseEvent(JComponent.java:3342) ~[?:?]
	at java.awt.Component.processEvent(Component.java:6401) ~[?:?]
	at java.awt.Container.processEvent(Container.java:2263) ~[?:?]
	at java.awt.Component.dispatchEventImpl(Component.java:5012) ~[?:?]
	at java.awt.Container.dispatchEventImpl(Container.java:2321) ~[?:?]
	at java.awt.Component.dispatchEvent(Component.java:4844) ~[?:?]
	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4918) ~[?:?]
	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4547) ~[?:?]
	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4488) ~[?:?]
	at java.awt.Container.dispatchEventImpl(Container.java:2307) ~[?:?]
	at java.awt.Window.dispatchEventImpl(Window.java:2762) ~[?:?]
	at java.awt.Component.dispatchEvent(Component.java:4844) ~[?:?]
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772) ~[?:?]
	at java.awt.EventQueue$4.run(EventQueue.java:721) ~[?:?]
	at java.awt.EventQueue$4.run(EventQueue.java:715) ~[?:?]
	at java.security.AccessController.doPrivileged(AccessController.java:391) [?:?]
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85) ~[?:?]
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95) ~[?:?]
	at java.awt.EventQueue$5.run(EventQueue.java:745) ~[?:?]
	at java.awt.EventQueue$5.run(EventQueue.java:743) ~[?:?]
	at java.security.AccessController.doPrivileged(AccessController.java:391) [?:?]
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85) [?:?]
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:742) [?:?]
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203) [?:?]
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124) [?:?]
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113) [?:?]
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109) [?:?]
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) [?:?]
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:90) [?:?]


-------------------------


cURL example - blank header:

curl --location --request POST 'http://example.com/api/somepath' \
--header 'Accept-Language: it-IT' \
--header 'HTTP_X_FORWARDED_FOR;' \
--form 'FrontsideImage=@"/C:/Users/someuser/Desktop/Desktop.avi"' \
--form 'BacksideImage=@"/C:/Users/someuser/Desktop/Desktop.jpg"' \
--form 'ApplicationTypeId="13"' \
--form 'Country="ITA"' \
--form 'DocumentType="ID_CARD"'

Error:

2020-12-23 02:24:10,285 ERROR o.a.j.p.h.g.a.ParseCurlCommandAction: Error creating test plan from cURL command list:[curl --location --request POST 'http://example.com/api/somepath' \
--header 'Accept-Language: it-IT' \
--header 'HTTP_X_FORWARDED_FOR;' \
--form 'FrontsideImage=@"/C:/Users/someuser/Desktop/Desktop.avi"' \
--form 'BacksideImage=@"/C:/Users/someuser/Desktop/Desktop.jpg"' \
--form 'ApplicationTypeId="13"' \
--form 'Country="ITA"' \
--form 'DocumentType="ID_CARD"']
java.lang.StringIndexOutOfBoundsException: begin 0, end -1, length 21
	at java.lang.String.checkBoundsBeginEnd(String.java:3720) ~[?:?]
	at java.lang.String.substring(String.java:1909) ~[?:?]
	at org.apache.jmeter.protocol.http.curl.BasicCurlParser.parse(BasicCurlParser.java:693) ~[ApacheJMeter_http.jar:5.4.1-SNAPSHOT]
	at org.apache.jmeter.protocol.http.gui.action.ParseCurlCommandAction.parseCommands(ParseCurlCommandAction.java:670) ~[ApacheJMeter_http.jar:5.4.1-SNAPSHOT]
	at org.apache.jmeter.protocol.http.gui.action.ParseCurlCommandAction.actionPerformed(ParseCurlCommandAction.java:619) ~[ApacheJMeter_http.jar:5.4.1-SNAPSHOT]
	at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967) ~[?:?]
	at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2308) ~[?:?]
	at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405) ~[?:?]
	at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262) ~[?:?]
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279) ~[?:?]
	at java.awt.Component.processMouseEvent(Component.java:6636) ~[?:?]
	at javax.swing.JComponent.processMouseEvent(JComponent.java:3342) ~[?:?]
	at java.awt.Component.processEvent(Component.java:6401) ~[?:?]
	at java.awt.Container.processEvent(Container.java:2263) ~[?:?]
	at java.awt.Component.dispatchEventImpl(Component.java:5012) ~[?:?]
	at java.awt.Container.dispatchEventImpl(Container.java:2321) ~[?:?]
	at java.awt.Component.dispatchEvent(Component.java:4844) ~[?:?]
	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4918) ~[?:?]
	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4547) ~[?:?]
	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4488) ~[?:?]
	at java.awt.Container.dispatchEventImpl(Container.java:2307) ~[?:?]
	at java.awt.Window.dispatchEventImpl(Window.java:2762) ~[?:?]
	at java.awt.Component.dispatchEvent(Component.java:4844) ~[?:?]
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772) ~[?:?]
	at java.awt.EventQueue$4.run(EventQueue.java:721) ~[?:?]
	at java.awt.EventQueue$4.run(EventQueue.java:715) ~[?:?]
	at java.security.AccessController.doPrivileged(AccessController.java:391) [?:?]
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85) ~[?:?]
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95) ~[?:?]
	at java.awt.EventQueue$5.run(EventQueue.java:745) ~[?:?]
	at java.awt.EventQueue$5.run(EventQueue.java:743) ~[?:?]
	at java.security.AccessController.doPrivileged(AccessController.java:391) [?:?]
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85) [?:?]
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:742) [?:?]
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203) [?:?]
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124) [?:?]
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113) [?:?]
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109) [?:?]
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) [?:?]
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:90) [?:?]





Jmeter 5.4.1 4ed732d
Microsoft Windows 10 Pro 64-bit
java version "1.8.0_251"
Comment 5 Felix Schumacher 2020-12-23 09:15:29 UTC
For the third bug report part, you could look at https://bz.apache.org/bugzilla/show_bug.cgi?id=64636 which is probably the same as your report.
Comment 6 Felix Schumacher 2020-12-23 09:23:58 UTC
For the second part (parameters which values start with @ landing in files upload tab), I believe, JMeter is doing the correct thing here.

The curl man page states in the '--form' section: "...  To force the 'content' part to be a file, prefix the file name with an @ sign. ..." 

If you want to send a value starting with an @ sign, you probably have to use --form-string as parameter. The curl man page for '-form-string' says: "... Similar to -F, --form except that the value string for the named parameter is used literally. Leading '@' and '<' characters, and the ';type='  string  in
the  value  have no special meaning. ..."

Maybe postman tries the value in the parameter, before it decides, whether this is a file or not. JMeter can't really decide this correctly, as the file has not to be present on creation of the test plan. It has to be present when the test plan is being run.

I am not sure, what to do about this, but it might be a good idea to discuss this on the mailing list and/or put this into its own bug report, as it will change the behaviour of detection.
Comment 7 Felix Schumacher 2020-12-23 09:48:33 UTC
Created attachment 37643 [details]
Fixes for multi-header and -parameter and mime detection

With this path multiple headers/parameters with the same name will get added to the generated request.

It will also change the detection method for mimetypes to be hopefully a bit more precise. It uses Apache Tika and tries to look at the content of the file (if it can), as well as the extension of the filename.
Comment 8 eR@SeR 2020-12-23 09:58:29 UTC
(In reply to Felix Schumacher from comment #5)
> For the third bug report part, you could look at
> https://bz.apache.org/bugzilla/show_bug.cgi?id=64636 which is probably the
> same as your report.

cURL is not the same as I reported, but if https://bz.apache.org/bugzilla/show_bug.cgi?id=64636 gets fixed, might be fixed for reported one. Please note that same happens if parameter or header values are blank.

(In reply to Felix Schumacher from comment #6)
> For the second part (parameters which values start with @ landing in files
> upload tab), I believe, JMeter is doing the correct thing here.
> 
> The curl man page states in the '--form' section: "...  To force the
> 'content' part to be a file, prefix the file name with an @ sign. ..." 
> 
> If you want to send a value starting with an @ sign, you probably have to
> use --form-string as parameter. The curl man page for '-form-string' says:
> "... Similar to -F, --form except that the value string for the named
> parameter is used literally. Leading '@' and '<' characters, and the
> ';type='  string  in
> the  value  have no special meaning. ..."
> 
> Maybe postman tries the value in the parameter, before it decides, whether
> this is a file or not. JMeter can't really decide this correctly, as the
> file has not to be present on creation of the test plan. It has to be
> present when the test plan is being run.
> 
> I am not sure, what to do about this, but it might be a good idea to discuss
> this on the mailing list and/or put this into its own bug report, as it will
> change the behaviour of detection.

You might missed difference between:

--form 'DocumentType="@ID_CARD"' \
--form 'BacksideImage=@"/C:/Users/someuser/Desktop/Desktop.jpg"' \

@ in DocumentType parameter is inside quotes, but in BacksideImage is before quotes. Does this change anything?
Comment 9 Felix Schumacher 2020-12-23 10:50:45 UTC
Created attachment 37644 [details]
Fixes for multi-header and -parameter and mime detection

Now with test cases
Comment 10 Felix Schumacher 2020-12-23 10:54:13 UTC
(In reply to eR@SeR from comment #8)
> (In reply to Felix Schumacher from comment #5)
> > For the third bug report part, you could look at
> > https://bz.apache.org/bugzilla/show_bug.cgi?id=64636 which is probably the
> > same as your report.
> 
> cURL is not the same as I reported, but if
> https://bz.apache.org/bugzilla/show_bug.cgi?id=64636 gets fixed, might be
> fixed for reported one. Please note that same happens if parameter or header
> values are blank.

The currently used parser for CLI options can not cope with empty parameters. So, I think it is the same report.

> 
> (In reply to Felix Schumacher from comment #6)
> > For the second part (parameters which values start with @ landing in files
> > upload tab), I believe, JMeter is doing the correct thing here.
> > 
> > The curl man page states in the '--form' section: "...  To force the
> > 'content' part to be a file, prefix the file name with an @ sign. ..." 
> > 
> > If you want to send a value starting with an @ sign, you probably have to
> > use --form-string as parameter. The curl man page for '-form-string' says:
> > "... Similar to -F, --form except that the value string for the named
> > parameter is used literally. Leading '@' and '<' characters, and the
> > ';type='  string  in
> > the  value  have no special meaning. ..."
> > 
> > Maybe postman tries the value in the parameter, before it decides, whether
> > this is a file or not. JMeter can't really decide this correctly, as the
> > file has not to be present on creation of the test plan. It has to be
> > present when the test plan is being run.
> > 
> > I am not sure, what to do about this, but it might be a good idea to discuss
> > this on the mailing list and/or put this into its own bug report, as it will
> > change the behaviour of detection.
> 
> You might missed difference between:
> 
> --form 'DocumentType="@ID_CARD"' \
> --form 'BacksideImage=@"/C:/Users/someuser/Desktop/Desktop.jpg"' \
> 
> @ in DocumentType parameter is inside quotes, but in BacksideImage is before
> quotes. Does this change anything?

That changes the story :) I missed that one. curl does indeed differentiate between name="@..." and name=@"...".
Comment 11 eR@SeR 2020-12-23 11:16:15 UTC
(In reply to Felix Schumacher from comment #10)
> The currently used parser for CLI options can not cope with empty
> parameters. So, I think it is the same report.
All right.

> That changes the story :) I missed that one. curl does indeed differentiate
> between name="@..." and name=@"...".
Nice :)
Comment 12 Felix Schumacher 2020-12-23 12:29:16 UTC
Created attachment 37645 [details]
Fixes for multi-header and -parameter and mime detection

Now, it tries to differentiate between "@value" and @"value".
Comment 13 Felix Schumacher 2020-12-23 14:51:36 UTC
Created attachment 37646 [details]
Fixes for multi-header and -parameter and mime detection

Another iteration on the remaining problems.

curl can do a lot of stuff when specifying parameters, like 'file=@filename;type=text/html' (which has been partly supported already) or 'param="something with spaces";headers=\"X-something: one\"'

The latter example is not possible right now, but a small step has been taken in that direction. Missing is also support for 'file=@"some/file";type=text/xml' that is a filename which was quoted.
Comment 14 Felix Schumacher 2020-12-23 16:16:07 UTC
Could you try next nightly or build from trunk and report back, whether your issues are solved?

Remember completely empty parameters like in "curl ''" are still not supported. But I think a lot of your reported ones are fixed.

commit f045cf5e1604c68b7d43986fe9bd82a102fa2b76
Author: Felix Schumacher <felix.schumacher@internetallee.de>
AuthorDate: Wed Dec 23 10:45:44 2020 +0100

    Sending mime type with parameter throws IllegalArgumentException
    
    More stuff from that bugzilla entry:
    
    * Better distinguishing between a quoted filename and a quoted name, that contains an @ char
    * Allow more than one header and parameter with the same name to be added
    * Simplify the code in ParseCurlCommandAction by moving some of the logic in extra classes
    
    What is still missing are curl specialities like
    
     --form file=@"file with; semicolon or space";type=text/something
     --form param="red green blue";headers="X-Something: \"yeah; something\""
    
    Bugzilla Id: 65024
---
 src/protocol/build.gradle.kts                      |  8 +++
 .../jmeter/protocol/http/curl/ArgumentHolder.java  | 55 +++++++++++++++
 .../jmeter/protocol/http/curl/BasicCurlParser.java | 51 +++++++++-----
 .../protocol/http/curl/FileArgumentHolder.java     | 80 ++++++++++++++++++++++
 .../protocol/http/curl/StringArgumentHolder.java   | 74 ++++++++++++++++++++
 .../http/gui/action/ParseCurlCommandAction.java    | 57 +++++++--------
 .../apache/jmeter/curl/BasicCurlParserTest.java    | 72 ++++++++++++++-----
 7 files changed, 334 insertions(+), 63 deletions(-)

commit 9d2ba68c16a079c4e7156d847ed9acb7a6d4bb88
Author: Felix Schumacher <felix.schumacher@internetallee.de>
AuthorDate: Wed Dec 23 17:12:47 2020 +0100

    Sending mime type with parameter throws IllegalArgumentException
    
    More stuff from that bugzilla entry:
    
    * Allow empty headers to be added
    
    Bugzilla Id: 65024
---
 .../apache/jmeter/protocol/http/curl/BasicCurlParser.java  | 14 ++++++++++----
 .../java/org/apache/jmeter/curl/BasicCurlParserTest.java   | 10 ++++++++++
 2 files changed, 20 insertions(+), 4 deletions(-)
Comment 15 eR@SeR 2020-12-24 19:48:42 UTC
> However, some commonly used extensions like .bmp .pdf .doc .docx .xls .xlsx .rar .zip etc. are still not recognized and generated MIME type is still application/octet-stream. You can check "Common MIME types" list on https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types and add all mentioned MIME types.
I checked all extensions from the MIME types list and almost all were properly detected. Some are not, some differ a little bit, but I guess that is fine. Nice improvement though :)

> 1. If parameter starts with @ like "@somevalue", form-data parameter is put inside Files upload tab instead to remain in Parameters tab.
> 2. If same header or parameter name with same or different value is added, only last header or parameter is generated. All headers or parameters should be added even if they are duplicated.
> 3. If URL, header or parameter value is blank, cURL is not imported.
Those three are fixed except if URL is blank. As you mentioned, that is already reported in https://bz.apache.org/bugzilla/show_bug.cgi?id=64636

(In reply to Felix Schumacher from comment #13)
> Created attachment 37646 [details]
> Fixes for multi-header and -parameter and mime detection
> 
> Another iteration on the remaining problems.
> 
> curl can do a lot of stuff when specifying parameters, like
> 'file=@filename;type=text/html' (which has been partly supported already) or
> 'param="something with spaces";headers=\"X-something: one\"'
> 
> The latter example is not possible right now, but a small step has been
> taken in that direction. Missing is also support for
> 'file=@"some/file";type=text/xml' that is a filename which was quoted.
Probably, the following parameter and file parameter example that I've found might be related, so please confirm (or fix if not):

curl --location --request POST 'http://example.com/api/somepath' \
--header 'Accept-Language: it-IT' \
--header 'HTTP_X_FORWARDED_FOR: 127.0.0.1' \
--form 'FrontsideImage=@"/C:/Users/someuser/Desktop/Desktop.jpg"' \
--form 'BacksideImage=@"/C:/Users/someuser/Desktop/Desktop.jpg"' \
--form 'ApplicationTypeId=""' \
--form 'Country="ITA"' \
--form 'DocumentType="ID_CARD"' \
--form 'parameterWithAllSymbols="testTEST ~`!@#$%^&*()_+1234567890[]{};'\''\\:\"|,./<>?"' \
--form 'fileNameWithAllAllowedSymbolsByWin=@"/C:/Users/someuser/Desktop/Desktop 0123456789 `~!@#$&()_+{}[];'\''..jpg"'

Actual chars typed in Postman:

parameterWithAllSymbols = testTEST ~`!@#$%^&*()_+1234567890[]{};'\:"|,./<>?
fileNameWithAllAllowedSymbolsByWin = Desktop 0123456789 `~!@#$&()_+{}[];'..jpg

It looks like that ' and ; are problematic ones. If they are removed, cURL is properly imported.

Interesting part was if ; is put at the end of string, but without ' character in parameterWithAllSymbols value, cURL is properly imported, but the same for ' is not working.

You said 'missing support'. Is there a workaround to make exceptions by yourself? Maybe simple find and replace or regex can do the trick?

I noticed that ' is generated in Postman as '\''
Can find and replace fix it?
Comment 16 Felix Schumacher 2021-01-15 18:03:06 UTC
commit 66e492113bde973ce5d0ed163efb5aa61efe3145
AuthorDate: Fri Jan 15 18:54:12 2021 +0100

    Remove leftover log message from debug session
    
    Instead of logging at info level, log it with debug, only and remove the
    unnecessary creation of a RuntimeException.
    
    Cleanup after commit bb0c4557e10278f334844f8c1af873b708981b08
    Bugzilla Id: 65013
---
 .../main/java/org/apache/jmeter/protocol/http/curl/BasicCurlParser.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)