Bug 47660

Summary: HTTP Sampler : Enable sending large files using JDK5 method HttpURLConnection#setFixedLengthStreamingMode
Product: JMeter - Now in Github Reporter: Hao Lin <numberzero1029>
Component: HTTPAssignee: JMeter issues mailing list <issues>
Status: RESOLVED DUPLICATE    
Severity: enhancement CC: p.mouawad
Priority: P2    
Version: 2.3.4   
Target Milestone: ---   
Hardware: All   
OS: All   

Description Hao Lin 2009-08-07 01:56:27 UTC
I'm using JMeter-2.3.4 to test a HTTP Server nowadays, and find out that
JMeter can not send HTTP PUT or POST request with large files using HTTP
Sampler.

After reading the the code of HTTP sampler and making experiments with
HttpURLConnection class which is used in HTTP Sampler, I find out that it is
JMeter's misusing HttpURLConnection class that trigerd suck bug.

HttpURLConnection can add 'Content-Length' header automatically, so it will
buffer all the output stream before sending it in order to count the length
of the stream.  So when we want to send a large file, HttpURLConnection will
buffer it until stack overflow.

To fix the problem of PUT(which also exists in POST method) large file, I modified the code of setHeaders
method of org.apache.jmeter.protocol.http.sampler.PutWriter class.
Here is a fragment of the modified code in setHeaders:

if(hasPutBody) {
   ///////////////modified place:////////////////
   // Set the content length
   // the following code makes no sense
   // since the HttpURLConnection can add Content-Length header
   // automatically
   // connection.setRequestProperty(HTTPConstants.HEADER_CONTENT_LENGTH,
   // Long.toString(contentLength));

   // set the HttpURLConnection to send fixed length stream
   // this code prevent HttpURLConnection to buffer output stream
   if(connection instanceof HttpURLConnection){
    ((HttpURLConnection)connection).setFixedLengthStreamingMode(contentLength);
   }
   ////////////////////end of modified place/////////////////////////


   // Make the connection ready for sending post data
   connection.setDoOutput(true);
}

As is shown in the code, I comment out the code
"connection.setRequestProperty(HTTPConstants.HEADER_CONTENT_LENGTH,
Long.toString(contentLength));" (since HttpURLConnection will add it
automatically later), and add "((HttpURLConnection)
connection).setFixedLengthStreamingMode(contentLength);", this tells
HttpURLConnection the fixed length of the request body and enables streaming
of a HTTP request body without internal buffering.

After making this modification, JMeter can send PUT HTTP request with large
files to my HTTP Server.

Regards
Hao Lin
Comment 1 Sebb 2009-08-11 06:53:51 UTC
The method setFixedLengthStreamingMode() is only available with Java 1.5+

The current version of JMeter is targetted at Java 1.4+.

However, Java 1.5 will become the minimum version at which point the proposed fix can be applied.

In the mean-time, you could try using the HttpClient sampler instead.
Comment 2 Sebb 2009-08-18 06:27:20 UTC
There are some problems with the suggested patch:

1) contentLength is currently held as a long, but setFixedLengthStreamingMode() requires an int. This would be easy enough to work round.

2) When output streaming is enabled, authentication and redirection cannot be handled automatically. This is not so easy to fix.
Comment 3 Philippe Mouawad 2011-11-14 12:12:41 UTC
Still in 2.5.1
Comment 4 Philippe Mouawad 2016-02-26 21:28:50 UTC

*** This bug has been marked as a duplicate of bug 58852 ***
Comment 5 The ASF infrastructure team 2022-09-24 20:37:43 UTC
This issue has been migrated to GitHub: https://github.com/apache/jmeter/issues/2267