You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jmeter.apache.org by fs...@apache.org on 2020/12/22 10:20:11 UTC
[jmeter] branch master updated: POST multipart/form-data cURL code
with quoted arguments is not imported correctly
This is an automated email from the ASF dual-hosted git repository.
fschumacher pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jmeter.git
The following commit(s) were added to refs/heads/master by this push:
new bb0c455 POST multipart/form-data cURL code with quoted arguments is not imported correctly
bb0c455 is described below
commit bb0c4557e10278f334844f8c1af873b708981b08
Author: Felix Schumacher <fe...@internetallee.de>
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(-)
diff --git a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/curl/BasicCurlParser.java b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/curl/BasicCurlParser.java
index 8d95da2..9471130 100644
--- a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/curl/BasicCurlParser.java
+++ b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/curl/BasicCurlParser.java
@@ -710,9 +710,9 @@ public class BasicCurlParser {
String key = nameAndValue.substring(0, indexOfEqual).trim();
String value = nameAndValue.substring(indexOfEqual + 1).trim();
if ("form-string".equals(option.getDescriptor().getName())) {
- request.addFormStringData(key, value);
+ request.addFormStringData(key, unquote(value));
} else {
- request.addFormData(key, value);
+ request.addFormData(key, unquote(value));
}
request.setMethod("POST");
} else if (option.getDescriptor().getId() == USER_AGENT_OPT) {
@@ -955,7 +955,7 @@ public class BasicCurlParser {
postdata = encodePostdata(postdata);
} else {
if (postdata.charAt(0) == '@' && !"data-raw".equals(dataOptionName)) {
- postdata = postdata.substring(1, postdata.length());
+ postdata = unquote(postdata.substring(1, postdata.length()));
postdata = readFromFile(postdata);
if (!"data-binary".equals(dataOptionName)) {
postdata = deleteLineBreak(postdata);
@@ -965,6 +965,15 @@ public class BasicCurlParser {
return postdata;
}
+ private String unquote(String value) {
+ LoggerFactory.getLogger(this.getClass()).info("Unquote {}", value, new RuntimeException(""));
+ if (value.charAt(0) == '"') {
+ String result = value.substring(1, value.length() - 1);
+ return result.replaceAll("\\\\(.)", "$1");
+ }
+ return value;
+ }
+
/**
* Encode the post data
*
@@ -975,7 +984,7 @@ public class BasicCurlParser {
if (postdata.contains("@")) {
String contentFile = null;
String[] arr = postdata.split("@", 2);
- String dataToEncode = readFromFile(arr[1]);
+ String dataToEncode = readFromFile(unquote(arr[1]));
try {
contentFile = URLEncoder.encode(dataToEncode, StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {
diff --git a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/gui/action/ParseCurlCommandAction.java b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/gui/action/ParseCurlCommandAction.java
index 49ca3d8..e03ae17 100644
--- a/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/gui/action/ParseCurlCommandAction.java
+++ b/src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/gui/action/ParseCurlCommandAction.java
@@ -526,7 +526,7 @@ public class ParseCurlCommandAction extends AbstractAction implements MenuCreato
boolean isContainsFile = "@".equals(formValue.substring(0, 1));
boolean isContainsContentType = formValue.toLowerCase().contains(TYPE_FORM);
if (isContainsFile) {
- formValue = formValue.substring(1, formValue.length());
+ formValue = unquote(formValue.substring(1, formValue.length()));
String contentType;
if (isContainsContentType) {
String[] formValueWithType = formValue.split(TYPE_FORM);
@@ -552,6 +552,13 @@ public class ParseCurlCommandAction extends AbstractAction implements MenuCreato
}
}
+ private String unquote(String substring) {
+ if (substring.charAt(0) == '"') {
+ return substring.substring(1, substring.length() - 1).replaceAll("\\\\(.)", "$1");
+ }
+ return substring;
+ }
+
private void createProxyServer(Request request, HTTPSamplerProxy httpSampler) {
Map<String, String> proxyServer = request.getProxyServer();
for (Map.Entry<String, String> proxyPara : proxyServer.entrySet()) {
diff --git a/src/protocol/http/src/test/java/org/apache/jmeter/curl/BasicCurlParserTest.java b/src/protocol/http/src/test/java/org/apache/jmeter/curl/BasicCurlParserTest.java
index c9f9228..adfa954 100644
--- a/src/protocol/http/src/test/java/org/apache/jmeter/curl/BasicCurlParserTest.java
+++ b/src/protocol/http/src/test/java/org/apache/jmeter/curl/BasicCurlParserTest.java
@@ -423,6 +423,40 @@ public class BasicCurlParserTest {
}
@Test
+ public void testFormWithQuotedValue() {
+ String cmdLine = "curl 'https://www.exaple.invalid/' "
+ + "--form 'test=\"something quoted\"'";
+ BasicCurlParser basicCurlParser = new BasicCurlParser();
+ BasicCurlParser.Request request = basicCurlParser.parse(cmdLine);
+ Map<String, String> res = request.getFormData();
+ assertEquals("something quoted", res.get("test"),
+ "With method 'form', we should post form data");
+ }
+
+ @Test
+ public void testFormWithQuotedValueWithQuotes() {
+ String cmdLine = "curl 'https://www.exaple.invalid/' "
+ + "--form 'test=\"something \\\"quoted\\\"\"'";
+ BasicCurlParser basicCurlParser = new BasicCurlParser();
+ BasicCurlParser.Request request = basicCurlParser.parse(cmdLine);
+ Map<String, String> res = request.getFormData();
+ assertEquals("something \"quoted\"", res.get("test"),
+ "With method 'form', we should post form data");
+ }
+
+ @Test
+ public void testFormWithQuotedFilename() {
+ // The quotes will be removed later by the consumer, which is ParseCurlCommandAction
+ String cmdLine = "curl 'https://www.exaple.invalid/' "
+ + "--form 'image=@\"/some/file.jpg\"'";
+ BasicCurlParser basicCurlParser = new BasicCurlParser();
+ BasicCurlParser.Request request = basicCurlParser.parse(cmdLine);
+ Map<String, String> res = request.getFormData();
+ assertEquals("@\"/some/file.jpg\"", res.get("image"),
+ "With method 'form', we should post form data");
+ }
+
+ @Test
public void testFormString() {
String cmdLine = "curl 'https://www.w3schools.com/html/tryit.asp?filename=tryhtml_form_submit/action_page.php' "
+ "-H 'cache-control: no-cache' --form-string 'image=@C:\\Test\\test.jpg' ";
diff --git a/src/protocol/http/src/test/java/org/apache/jmeter/gui/action/ParseCurlCommandActionTest.java b/src/protocol/http/src/test/java/org/apache/jmeter/gui/action/ParseCurlCommandActionTest.java
index 04c99de..15b984c 100644
--- a/src/protocol/http/src/test/java/org/apache/jmeter/gui/action/ParseCurlCommandActionTest.java
+++ b/src/protocol/http/src/test/java/org/apache/jmeter/gui/action/ParseCurlCommandActionTest.java
@@ -49,6 +49,7 @@ import org.apache.jmeter.protocol.http.curl.BasicCurlParser.Request;
import org.apache.jmeter.protocol.http.gui.action.ParseCurlCommandAction;
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerFactory;
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
+import org.apache.jmeter.protocol.http.util.HTTPFileArg;
import org.apache.jmeter.testelement.TestElement;
import org.apache.jmeter.testelement.TestPlan;
import org.apache.jmeter.threads.ThreadGroup;
@@ -292,6 +293,28 @@ public class ParseCurlCommandActionTest {
}
@Test
+ public void testCreateHttpRequestWithQuotedFilenameAsData() throws Exception {
+ ParseCurlCommandAction p = new ParseCurlCommandAction();
+ BasicCurlParser basicCurlParser = new BasicCurlParser();
+ ThreadGroup threadGroup = new ThreadGroup();
+ TestPlan testPlan = new TestPlan();
+ HashTree tree = new HashTree();
+ HashTree testPlanHT = tree.add(testPlan);
+ HashTree threadGroupHT = testPlanHT.add(threadGroup);
+ Request request = basicCurlParser.parse("curl 'http://jmeter.apache.org/' -X POST --form 'pic=@\"/some/file.jpg\"'");
+ Method method = getMethodFor("createHttpRequest", Request.class, HashTree.class, String.class);
+ HTTPSamplerProxy httpSampler = (HTTPSamplerProxy) method.invoke(p, request, threadGroupHT, "comment");
+ assertEquals("/", httpSampler.getPath(), "path should be set in httpsampler");
+ assertEquals("jmeter.apache.org", httpSampler.getDomain(), "domain should be set in httpsampler");
+ assertEquals(80, httpSampler.getPort(), "port should be 80 in httpsampler");
+ assertEquals("POST", httpSampler.getMethod(), "method should be set in httpsampler");
+ HTTPFileArg fileArg = httpSampler.getHTTPFiles()[0];
+ assertEquals("pic", fileArg.getParamName());
+ assertEquals("/some/file.jpg", fileArg.getPath());
+ assertEquals("image/jpeg", fileArg.getMimeType());
+ }
+
+ @Test
public void testConfigureTimeout() throws Exception {
ParseCurlCommandAction p = new ParseCurlCommandAction();
BasicCurlParser basicCurlParser = new BasicCurlParser();
diff --git a/xdocs/changes.xml b/xdocs/changes.xml
index 6396c56..afac388 100644
--- a/xdocs/changes.xml
+++ b/xdocs/changes.xml
@@ -186,6 +186,7 @@ Summary
<li><bug>64984</bug>Darklaf LAF: Selecting a Test element does not work under certain screen resolutions on Windows. With the help of Jannis Weis</li>
<li><bug>65008</bug>SampleResult.setIgnore() called from PostProcessor is not considered</li>
<li><bug>64993</bug>Daklaf LAF: Menu navigation not working with keyboard shortcuts. With the help of Jannis Weis</li>
+ <li><bug>65013</bug>POST multipart/form-data cURL code with quoted arguments is not imported correctly</li>
</ul>
<!-- =================== Thanks =================== -->