New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Invalid request using Proxy for a multipart/form-data with no filename specified. #1642
Comments
Benjamin Francisoud (migrated from Bugzilla): cocoon.html<html><head><title>Problem in creating the Request</title><style><!--body { background-color: white; color: black; font-family: verdana, helvetica, sanf serif;}h1 {color: #336699; margin: 0px 0px 20px 0px; border-width: 0px 0px 1px 0px; border-style: solid; border-color: #336699;}p.footer { color: #336699; border-width: 1px 0px 0px 0px; border-style: solid; border-color: #336699; }span {color: #336699;}pre {padding-left: 20px;}a:link {font-weight: bold; color: #336699;}a:visited {color: #336699; }a:hover {color: #800000; background-color: #ffff80;}a:active {color: #006666;}--></style></head><body><h1>Problem in creating the Request</h1><p><span>Message:</span> Malformed stream</p><p><span>Description:</span> org.apache.cocoon.servlet.multipart.MultipartException: Malformed stream</p><p><span>Sender:</span> org.apache.cocoon.servlet.CocoonServlet</p><p><span>Source:</span> Cocoon Servlet</p><p><span>cause</span><pre>org.apache.cocoon.servlet.multipart.MultipartException: Malformed stream</pre></p><p><span>request-uri</span><pre>/repons/portal/portal</pre></p><p><span>full exception chain stacktrace</span><pre>org.apache.cocoon.servlet.multipart.MultipartException: Malformed stream
at org.apache.cocoon.servlet.multipart.MultipartParser.parseMultiPart(MultipartParser.java:160)
at org.apache.cocoon.servlet.multipart.MultipartParser.parseParts(MultipartParser.java:108)
at org.apache.cocoon.servlet.multipart.MultipartParser.getParts(MultipartParser.java:134)
at org.apache.cocoon.servlet.multipart.RequestFactory.getServletRequest(RequestFactory.java:91)
at org.apache.cocoon.servlet.CocoonServlet.service(CocoonServlet.java:1055)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:152)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:160)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:799)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:705)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:577)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683)
at java.lang.Thread.run(Thread.java:534)
</pre></p><p><span>stacktrace</span><pre>org.apache.cocoon.servlet.multipart.MultipartException: Malformed stream
at org.apache.cocoon.servlet.multipart.MultipartParser.parseMultiPart(MultipartParser.java:160)
at org.apache.cocoon.servlet.multipart.MultipartParser.parseParts(MultipartParser.java:108)
at org.apache.cocoon.servlet.multipart.MultipartParser.getParts(MultipartParser.java:134)
at org.apache.cocoon.servlet.multipart.RequestFactory.getServletRequest(RequestFactory.java:91)
at org.apache.cocoon.servlet.CocoonServlet.service(CocoonServlet.java:1055)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:152)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:160)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:799)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:705)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:577)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683)
at java.lang.Thread.run(Thread.java:534)
</pre></p><p class='footer'><a href='http://cocoon.apache.org/'>Apache Cocoon 2.1.8-dev</p></body></html>````
</details> |
Benjamin Francisoud (migrated from Bugzilla): Created attachment test.htm: simple multipart form |
Benjamin Francisoud (migrated from Bugzilla): Created attachment rails.txt: webrick - ruby on rails - stacktrace rails.txt
|
Benjamin Francisoud (migrated from Bugzilla): In sendPostData(), the filename is tested with those lines: But in setHeaders(), the filename is not use: Where sampler.getFileField() is the "name" attribut of the html input ("upload" See patch-bug-37716.txt |
Benjamin Francisoud (migrated from Bugzilla): patch-bug-37716.txtIndex: C:/Documents and Settings/Benjamin/Mes documents/workspaces/workspaceApache/jakarta-jmeter-rel2.1/src/protocol/http/org/apache/jmeter/protocol/http/sampler/PostWriter.java
===================================================================
--- C:/Documents and Settings/Benjamin/Mes documents/workspaces/workspaceApache/jakarta-jmeter-rel2.1/src/protocol/http/org/apache/jmeter/protocol/http/sampler/PostWriter.java (revision 349940)
+++ C:/Documents and Settings/Benjamin/Mes documents/workspaces/workspaceApache/jakarta-jmeter-rel2.1/src/protocol/http/org/apache/jmeter/protocol/http/sampler/PostWriter.java (working copy)
@@ -78,7 +78,7 @@
((HttpURLConnection) connection).setRequestMethod("POST");
// If filename was specified then send the post using multipart syntax
- String filename = sampler.getFileField();
+ String filename = sampler.getFilename();
if ((filename != null) && (filename.trim().length() > 0)) {
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
connection.setDoOutput(true); |
Benjamin Francisoud (migrated from Bugzilla): Done under windows XP and eclipse 3.1. Launch from eclipse: green bar. Created attachment PostWriterTest.java: junit test case for PostWriter PostWriterTest.javapackage org.apache.jmeter.protocol.http.sampler;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;
import junit.framework.TestCase;
import org.apache.jmeter.config.Arguments;
public class PostWriterTest extends TestCase {
// TODO: put PostWriter.CRLF public an use it instead of this one
private final static byte[] CRLF = { 0x0d, 0x0A };
private PostWriter postWriter;
private URLConnection connection;
private HTTPSampler sampler;
private File temporaryFile;
protected void setUp() throws Exception {
postWriter = new PostWriter();
connection = new StubURLConnection("http://fake_url/test");
sampler = new HTTPSampler();
// create a temporary file to make sure we always have a file to give to the PostWriter
// Whereever we are or Whatever the current path is.
temporaryFile = File.createTempFile("foo", "txt");
OutputStream output = new FileOutputStream(temporaryFile);
output.write("foo content".getBytes());
output.flush();
output.close();
}
protected void tearDown() throws Exception {
// delete temporay file
temporaryFile.delete();
}
/*
* Test method for 'org.apache.jmeter.protocol.http.sampler.PostWriter.sendPostData(URLConnection, HTTPSampler)'
*/
public void testSendPostData() throws IOException {
setupFilename(sampler);
setupCommons(sampler);
postWriter.sendPostData(connection, sampler);
assertEquals(createExpectedOutputStream().toString(), connection.getOutputStream().toString());
}
/*
* Test method for 'org.apache.jmeter.protocol.http.sampler.PostWriter.sendPostData(URLConnection, HTTPSampler)'
*/
public void testSendPostData_NoFilename() throws IOException {
setupNoFilename(sampler);
setupCommons(sampler);
postWriter.sendPostData(connection, sampler);
assertEquals("title=mytitle&description=mydescription", connection.getOutputStream().toString());
}
/*
* Test method for 'org.apache.jmeter.protocol.http.sampler.PostWriter.setHeaders(URLConnection, HTTPSampler)'
*/
public void testSetHeaders() throws IOException {
setupFilename(sampler);
setupCommons(sampler);
postWriter.setHeaders(connection, sampler);
assertEquals("multipart/form-data; boundary=" + PostWriter.BOUNDARY, connection.getRequestProperty("Content-Type"));
}
/*
* Test method for 'org.apache.jmeter.protocol.http.sampler.PostWriter.setHeaders(URLConnection, HTTPSampler)'
*/
public void testSetHeaders_NoFilename() throws IOException {
setupNoFilename(sampler);
setupCommons(sampler);
postWriter.setHeaders(connection, sampler);
assertEquals("application/x-www-form-urlencoded", connection.getRequestProperty("Content-Type"));
assertEquals("39", connection.getRequestProperty("Content-Length"));
}
/**
* setup commons parts of HTTPSampler with a no filename.
*
* @param httpSampler
* @throws IOException
*/
private void setupNoFilename(HTTPSampler httpSampler) throws IOException {
httpSampler.setFilename("");
httpSampler.setMimetype("application/octet-stream");
}
/**
* setup commons parts of HTTPSampler with a filename.
*
* @param httpSampler
* @throws IOException
*/
private void setupFilename(HTTPSampler httpSampler) throws IOException {
// httpSampler.setFilename("test/src/org/apache/jmeter/protocol/http/sampler/foo.txt");
httpSampler.setFilename(temporaryFile.getAbsolutePath());
httpSampler.setMimetype("text/plain");
}
/**
* setup commons parts of HTTPSampler form test* methods.
*
* @param httpSampler
* @throws IOException
*/
private void setupCommons(HTTPSampler httpSampler) throws IOException {
httpSampler.setFileField("upload");
Arguments args = new Arguments();
args.addArgument("title", "mytitle");
args.addArgument("description", "mydescription");
httpSampler.setArguments(args);
}
/**
* Create the expected output with CRLF.
*/
private OutputStream createExpectedOutputStream() throws IOException {
/*
-----------------------------7d159c1302d0y0
Content-Disposition: form-data; name="title"
mytitle
-----------------------------7d159c1302d0y0
Content-Disposition: form-data; name="description"
mydescription
-----------------------------7d159c1302d0y0
Content-Disposition: form-data; name="upload"; filename="test/src/org/apache/jmeter/protocol/http/sampler/foo.txt"
Content-Type: plain/text
foo content
-----------------------------7d159c1302d0y0--
*/
final OutputStream output = new ByteArrayOutputStream();
output.write("-----------------------------7d159c1302d0y0".getBytes());
output.write(CRLF);
output.write("Content-Disposition: form-data; name=\"title\"".getBytes());
output.write(CRLF);
output.write(CRLF);
output.write("mytitle".getBytes());
output.write(CRLF);
output.write("-----------------------------7d159c1302d0y0".getBytes());
output.write(CRLF);
output.write("Content-Disposition: form-data; name=\"description\"".getBytes());
output.write(CRLF);
output.write(CRLF);
output.write("mydescription".getBytes());
output.write(CRLF);
output.write("-----------------------------7d159c1302d0y0".getBytes());
output.write(CRLF);
// replace all backslash with double backslash
String filename = temporaryFile.getAbsolutePath().replaceAll("\\\\","\\\\\\\\");
output.write(("Content-Disposition: form-data; name=\"upload\"; filename=\"" + filename + "\"").getBytes());
output.write(CRLF);
output.write("Content-Type: text/plain".getBytes());
output.write(CRLF);
output.write(CRLF);
output.write("foo content".getBytes());
output.write(CRLF);
output.write("-----------------------------7d159c1302d0y0--".getBytes());
output.write(CRLF);
output.flush();
output.close();
return output;
}
/**
* Mock an HttpURLConnection.
* extends HttpURLConnection instead of just URLConnection because there is a cast in PostWriter.
*/
private class StubURLConnection extends HttpURLConnection {
private OutputStream output = new ByteArrayOutputStream();
private Map properties = new HashMap();
public StubURLConnection(String url) throws MalformedURLException {
super(new URL(url));
}
public void connect() throws IOException {
}
public OutputStream getOutputStream() throws IOException {
return output;
}
public void disconnect() {
}
public boolean usingProxy() {
return false;
}
public String getRequestProperty(String key) {
return (String) properties.get(key);
}
public void setRequestProperty(String key, String value) {
properties.put(key, value);
}
}
} |
Sebb (migrated from Bugzilla): I've applied the patch to the 2.1 branch. BTW, PostWriter.CRLF and PostWriterTest.CRLF need to remain private - final |
Benjamin Francisoud (migrated from Bugzilla): |
Benjamin Francisoud (Bug 37716):
When using the JMmeter proxy (to record pages) on a multipart/form-data whith an
upload file field, if the filename is not specified, an invalid request is send
to the server.
My actual webapp (with cocoon) and the form are too complex to be put as an
attachment, but I'll provide the stacktrace.
I recreated the same problem using a simple form with ruby on rails, I'll put
the webrick stacktrace too.
I think I've spoted the problem in PostWriter.java, I'll provide a patch (as
soon as I'll have checkout sources from svn).
Severity: normal
OS: Windows XP
The text was updated successfully, but these errors were encountered: