You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@jakarta.apache.org by sebb <se...@gmail.com> on 2011/04/04 02:18:57 UTC

Re: svn commit: r1088435 - in /jakarta/jmeter/trunk: bin/ src/core/org/apache/jmeter/util/ src/protocol/http/org/apache/jmeter/protocol/http/sampler/ xdocs/ xdocs/usermanual/

On 4 April 2011 00:13,  <mi...@apache.org> wrote:
> Author: milamber
> Date: Sun Apr  3 23:13:09 2011
> New Revision: 1088435
>
> URL: http://svn.apache.org/viewvc?rev=1088435&view=rev
> Log:
> Bug 50170 - Bytes reported by http sampler is after GUnZip
> Add an optional property to allow change the method to get response size.
>
> Modified:
>    jakarta/jmeter/trunk/bin/jmeter.properties
>    jakarta/jmeter/trunk/src/core/org/apache/jmeter/util/JMeterUtils.java
>    jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampleResult.java
>    jakarta/jmeter/trunk/xdocs/changes.xml
>    jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml
>
> Modified: jakarta/jmeter/trunk/bin/jmeter.properties
> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/bin/jmeter.properties?rev=1088435&r1=1088434&r2=1088435&view=diff
> ==============================================================================
> --- jakarta/jmeter/trunk/bin/jmeter.properties (original)
> +++ jakarta/jmeter/trunk/bin/jmeter.properties Sun Apr  3 23:13:09 2011
> @@ -243,6 +243,16 @@ log_level.jorphan=INFO
>  #log_config=logkit.xml
>
>  #---------------------------------------------------------------------------
> +# HTTP common configuration
> +#---------------------------------------------------------------------------
> +
> +# Response size calculate method
> +# default: only data (uncompress size if deflate)
> +#http.getbytes.type=default
> +#http.getbytes.type=calculate_headers_size+default
> +#http.getbytes.type=calculate_headers_size+content-length_value

These values are a bit complicated; I'd prefer to see true/false
values if possible.

> +
> +#---------------------------------------------------------------------------
>  # HTTP Java configuration
>  #---------------------------------------------------------------------------
>
>
> Modified: jakarta/jmeter/trunk/src/core/org/apache/jmeter/util/JMeterUtils.java
> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/util/JMeterUtils.java?rev=1088435&r1=1088434&r2=1088435&view=diff
> ==============================================================================
> --- jakarta/jmeter/trunk/src/core/org/apache/jmeter/util/JMeterUtils.java (original)
> +++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/util/JMeterUtils.java Sun Apr  3 23:13:09 2011
> @@ -36,10 +36,12 @@ import java.util.Iterator;
>  import java.util.LinkedHashMap;
>  import java.util.List;
>  import java.util.Locale;
> +import java.util.Map.Entry;
>  import java.util.MissingResourceException;
>  import java.util.Properties;
>  import java.util.Random;
>  import java.util.ResourceBundle;
> +import java.util.Set;
>  import java.util.StringTokenizer;
>  import java.util.Vector;
>
> @@ -73,6 +75,8 @@ public class JMeterUtils implements Unit
>             new Perl5Compiler());
>
>     private static final String EXPERT_MODE_PROPERTY = "jmeter.expertMode"; // $NON-NLS-1$
> +
> +    private static final String HEADER_CONTENT_LENGTH = "Content-Length"; // $NON-NLS-1$
>
>     private static final String ENGLISH_LANGUAGE = Locale.ENGLISH.getLanguage();
>
> @@ -1237,4 +1241,19 @@ public class JMeterUtils implements Unit
>         return linkedHeaders;
>     }
>
> +    /**
> +     * Get Content-Length value from headers
> +     * @param headers
> +     * @return Content-Length value
> +     */
> +    public static int getHeaderContentLength(String headers) {
> +        LinkedHashMap<String, String> lhm = JMeterUtils.parseHeaders(headers);
> +        Set<Entry<String, String>> keySet = lhm.entrySet();
> +        for (Entry<String, String> entry : keySet) {
> +            if (entry.getKey().equals(HEADER_CONTENT_LENGTH)) {
> +                return Integer.parseInt(entry.getValue());
> +            }
> +        }
> +        return 0; // Content-Length not found

This does not work for chunked input. It might be better to store the
actual response size when receiving the response, rather than trying
to calculate it later.

> +    }
>  }
>
> Modified: jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampleResult.java
> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampleResult.java?rev=1088435&r1=1088434&r2=1088435&view=diff
> ==============================================================================
> --- jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampleResult.java (original)
> +++ jakarta/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampleResult.java Sun Apr  3 23:13:09 2011
> @@ -23,6 +23,7 @@ import java.net.URL;
>
>  import org.apache.jmeter.protocol.http.util.HTTPConstants;
>  import org.apache.jmeter.samplers.SampleResult;
> +import org.apache.jmeter.util.JMeterUtils;
>
>  /**
>  * This is a specialisation of the SampleResult class for the HTTP protocol.
> @@ -31,6 +32,15 @@ import org.apache.jmeter.samplers.Sample
>  public class HTTPSampleResult extends SampleResult {
>
>     private static final long serialVersionUID = 240L;
> +
> +    private static final String GETBYTES_TYPE_DEFAULT = "default";
> +
> +    private static final String GETBYTES_TYPE_HEAD_CONTENTLENGTH = "calculate_headers_size+content-length_value";
> +
> +    private static final String GETBYTES_TYPE_HEAD_DEFAULT = "calculate_headers_size+default";
> +
> +    private static final String GETBYTES_TYPE =
> +        JMeterUtils.getPropDefault("http.getbytes.type", GETBYTES_TYPE_DEFAULT); // $NON-NLS-1$
>
>     private String cookies = ""; // never null
>
> @@ -215,4 +225,36 @@ public class HTTPSampleResult extends Sa
>         setResponseCode(HTTP_NO_CONTENT_CODE);
>         setResponseMessage(HTTP_NO_CONTENT_MSG);
>     }
> +
> +    /*
> +     * (non-Javadoc)
> +     *
> +     * @see org.apache.jmeter.samplers.SampleResult#getBytes()
> +     */
> +    @Override
> +    public int getBytes() {
> +        if (GETBYTES_TYPE.equals(GETBYTES_TYPE_HEAD_CONTENTLENGTH)) {

The string comparison should be done once and turned into a static variable.
But ideally change the properties to use separate variables for:
- include header size in total
- use actual length rather than decompressed length

> +            return calculateHeadersSize()
> +                    + JMeterUtils.getHeaderContentLength(this.getResponseHeaders());
> +        }
> +        if (GETBYTES_TYPE.equals(GETBYTES_TYPE_HEAD_DEFAULT)) {
> +            return calculateHeadersSize() + super.getBytes();
> +        }
> +        return super.getBytes(); // Default
> +    }
> +
> +    /**
> +     * Calculate response headers size
> +     *
> +     * @return the size response headers (in bytes)
> +     */
> +    private int calculateHeadersSize() {
> +        int headersSize = 0;
> +        headersSize += 9 // Http proto length + 1 space (i.e.: "HTTP/1.x ")
> +                + String.valueOf(this.getResponseCode()).length()
> +                + this.getResponseMessage().length();
> +        headersSize += this.getResponseHeaders().length();
> +        return headersSize;
> +    }

Again, maybe this can be done when the data is initially retrieved,
and stored in the HttpSampleResult.

> +
>  }
>
> Modified: jakarta/jmeter/trunk/xdocs/changes.xml
> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/changes.xml?rev=1088435&r1=1088434&r2=1088435&view=diff
> ==============================================================================
> --- jakarta/jmeter/trunk/xdocs/changes.xml (original)
> +++ jakarta/jmeter/trunk/xdocs/changes.xml Sun Apr  3 23:13:09 2011
> @@ -150,6 +150,7 @@ Fixed RMI startup to provide location of
>  <li>Allow HTTP implementation to be selected at run-time</li>
>  <li>Bug 50684 - Optionally disable Content-Type and Transfer-Encoding in Multipart POST</li>
>  <li>Bug 50943 - Allowing concurrent downloads of embedded resources in html page</li>
> +<li>Bug 50170 - Bytes reported by http sampler is after GUnZip<br></br>Add an optional property to allow change the method to get response size</li>
>  </ul>
>
>  <h3>Other samplers</h3>
>
> Modified: jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml
> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml?rev=1088435&r1=1088434&r2=1088435&view=diff
> ==============================================================================
> --- jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml (original)
> +++ jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml Sun Apr  3 23:13:09 2011
> @@ -333,6 +333,16 @@ The HttpClient version of the sampler su
>  #httpclient.socket.http.cps=0
>  #httpclient.socket.https.cps=0
>  </pre>
> +<p><b>Method to calculate Response size</b><br></br>
> +An optional property to allow change the method to get response size:<br></br>
> +<ul><li>Default behavior: Size in bytes is the response data length (without response headers)
> +<pre>http.getbytes.type=default</pre></li>
> +<li>Response headers length and default (response data length)
> +<pre>http.getbytes.type=calculate_headers_size+default</pre></li>
> +<li>Response headers length and value of "Content-length" header (generally provide by web server)<br></br>
> +Useful when web server uses a deflate/gzip method to compress response data
> +<pre>http.getbytes.type=calculate_headers_size+content-length_value</pre></li></ul>
> +</p>
>  <links>
>         <link href="test_plan.html#assertions">Assertion</link>
>         <link href="build-web-test-plan.html">Building a Web Test Plan</link>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: notifications-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: notifications-help@jakarta.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: dev-help@jakarta.apache.org


Re: svn commit: r1088435 - in /jakarta/jmeter/trunk: bin/ src/core/org/apache/jmeter/util/ src/protocol/http/org/apache/jmeter/protocol/http/sampler/ xdocs/ xdocs/usermanual/

Posted by Milamber <mi...@apache.org>.
>
>>>> +    /**
>>>> +     * Get Content-Length value from headers
>>>> +     * @param headers
>>>> +     * @return Content-Length value
>>>> +     */
>>>> +    public static int getHeaderContentLength(String headers) {
>>>> +        LinkedHashMap<String, String> lhm = JMeterUtils.parseHeaders(headers);
>>>> +        Set<Entry<String, String>> keySet = lhm.entrySet();
>>>> +        for (Entry<String, String> entry : keySet) {
>>>> +            if (entry.getKey().equals(HEADER_CONTENT_LENGTH)) {
>>>> +                return Integer.parseInt(entry.getValue());
>>>> +            }
>>>> +        }
>>>> +        return 0; // Content-Length not found
>>>>
>>>>         
>>> This does not work for chunked input. It might be better to store the
>>> actual response size when receiving the response, rather than trying
>>> to calculate it later.
>>>
>>>       
>> Ok, store in sampleresult when receiving the response. If 0 (no value),
>> the response data size is used.
>>
>>
>> With my last submission (r1088748), I try to respond to your feedback.
>> Please say me if another thing to improve.
>>     
> The problem of chunked responses still exists - such responses don't
> have a Content-Length header.
>
> One way round this would be to wrap the input Stream with a
> org.apache.commons.io.input.CountingInputStream.
> I don't think this will affect performance adversely.
>
> Does that make sense?
>   

Yes may be a good idea.
Since your last commit on HC4Impl, entity.getContentLength() return -1
(unknown size) (but http response have a content-length define)
I thinks the ResponseContentEncoding class which decompress stream is
the cause.

On HC4, I try to use a CountingInputStream on instream, but the return
size is uncompressed.
//                InputStream instream = entity.getContent();
                InputStream instream = new
CountingInputStream(entity.getContent());
                res.setResponseData(readResponse(res, instream, (int)
entity.getContentLength()));
                int cnt = ((CountingInputStream) instream).getCount();
                log.debug("CNT=" + cnt);


I thinks that CountingInputStream must be in more deep in code, directly
in HttpClient, or inside the Gzip/deflate input stream?


Milamber

> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: dev-help@jakarta.apache.org
>
>
>   


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: dev-help@jakarta.apache.org


Re: svn commit: r1088435 - in /jakarta/jmeter/trunk: bin/ src/core/org/apache/jmeter/util/ src/protocol/http/org/apache/jmeter/protocol/http/sampler/ xdocs/ xdocs/usermanual/

Posted by sebb <se...@gmail.com>.
On 4 April 2011 20:35, Milamber <mi...@apache.org> wrote:
>
> [snip]
>>> +#http.getbytes.type=default
>>> +#http.getbytes.type=calculate_headers_size+default
>>> +#http.getbytes.type=calculate_headers_size+content-length_value
>>>
>> These values are a bit complicated; I'd prefer to see true/false
>> values if possible.
>>
> Ok I change this to 2 properties true/false.

+1

>>
>>> +    /**
>>> +     * Get Content-Length value from headers
>>> +     * @param headers
>>> +     * @return Content-Length value
>>> +     */
>>> +    public static int getHeaderContentLength(String headers) {
>>> +        LinkedHashMap<String, String> lhm = JMeterUtils.parseHeaders(headers);
>>> +        Set<Entry<String, String>> keySet = lhm.entrySet();
>>> +        for (Entry<String, String> entry : keySet) {
>>> +            if (entry.getKey().equals(HEADER_CONTENT_LENGTH)) {
>>> +                return Integer.parseInt(entry.getValue());
>>> +            }
>>> +        }
>>> +        return 0; // Content-Length not found
>>>
>> This does not work for chunked input. It might be better to store the
>> actual response size when receiving the response, rather than trying
>> to calculate it later.
>>
>
> Ok, store in sampleresult when receiving the response. If 0 (no value),
> the response data size is used.
>
>
> With my last submission (r1088748), I try to respond to your feedback.
> Please say me if another thing to improve.

The problem of chunked responses still exists - such responses don't
have a Content-Length header.

One way round this would be to wrap the input Stream with a
org.apache.commons.io.input.CountingInputStream.
I don't think this will affect performance adversely.

Does that make sense?

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: dev-help@jakarta.apache.org


Re: svn commit: r1088435 - in /jakarta/jmeter/trunk: bin/ src/core/org/apache/jmeter/util/ src/protocol/http/org/apache/jmeter/protocol/http/sampler/ xdocs/ xdocs/usermanual/

Posted by Milamber <mi...@apache.org>.
[snip]
>> +#http.getbytes.type=default
>> +#http.getbytes.type=calculate_headers_size+default
>> +#http.getbytes.type=calculate_headers_size+content-length_value
>>     
> These values are a bit complicated; I'd prefer to see true/false
> values if possible.
>   
Ok I change this to 2 properties true/false.

>
>> +    /**
>> +     * Get Content-Length value from headers
>> +     * @param headers
>> +     * @return Content-Length value
>> +     */
>> +    public static int getHeaderContentLength(String headers) {
>> +        LinkedHashMap<String, String> lhm = JMeterUtils.parseHeaders(headers);
>> +        Set<Entry<String, String>> keySet = lhm.entrySet();
>> +        for (Entry<String, String> entry : keySet) {
>> +            if (entry.getKey().equals(HEADER_CONTENT_LENGTH)) {
>> +                return Integer.parseInt(entry.getValue());
>> +            }
>> +        }
>> +        return 0; // Content-Length not found
>>     
> This does not work for chunked input. It might be better to store the
> actual response size when receiving the response, rather than trying
> to calculate it later.
>   

Ok, store in sampleresult when receiving the response. If 0 (no value),
the response data size is used.


With my last submission (r1088748), I try to respond to your feedback.
Please say me if another thing to improve.

Milamber


>
>> +     * @see org.apache.jmeter.samplers.SampleResult#getBytes()
>> +     */
>> +    @Override
>> +    public int getBytes() {
>> +        if (GETBYTES_TYPE.equals(GETBYTES_TYPE_HEAD_CONTENTLENGTH)) {
>>     
> The string comparison should be done once and turned into a static variable.
> But ideally change the properties to use separate variables for:
> - include header size in total
> - use actual length rather than decompressed length
>
>   
>
>> +    /**
>> +     * Calculate response headers size
>> +     *
>> +     * @return the size response headers (in bytes)
>> +     */
>> +    private int calculateHeadersSize() {
>> +        int headersSize = 0;
>> +        headersSize += 9 // Http proto length + 1 space (i.e.: "HTTP/1.x ")
>> +                + String.valueOf(this.getResponseCode()).length()
>> +                + this.getResponseMessage().length();
>> +        headersSize += this.getResponseHeaders().length();
>> +        return headersSize;
>> +    }
>>     
> Again, maybe this can be done when the data is initially retrieved,
> and stored in the HttpSampleResult. 
>   
>> +
>>  }
>>
>> Modified: jakarta/jmeter/trunk/xdocs/changes.xml
>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/changes.xml?rev=1088435&r1=1088434&r2=1088435&view=diff
>> ==============================================================================
>> --- jakarta/jmeter/trunk/xdocs/changes.xml (original)
>> +++ jakarta/jmeter/trunk/xdocs/changes.xml Sun Apr  3 23:13:09 2011
>> @@ -150,6 +150,7 @@ Fixed RMI startup to provide location of
>>  <li>Allow HTTP implementation to be selected at run-time</li>
>>  <li>Bug 50684 - Optionally disable Content-Type and Transfer-Encoding in Multipart POST</li>
>>  <li>Bug 50943 - Allowing concurrent downloads of embedded resources in html page</li>
>> +<li>Bug 50170 - Bytes reported by http sampler is after GUnZip<br></br>Add an optional property to allow change the method to get response size</li>
>>  </ul>
>>
>>  <h3>Other samplers</h3>
>>
>> Modified: jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml
>> URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml?rev=1088435&r1=1088434&r2=1088435&view=diff
>> ==============================================================================
>> --- jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml (original)
>> +++ jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml Sun Apr  3 23:13:09 2011
>> @@ -333,6 +333,16 @@ The HttpClient version of the sampler su
>>  #httpclient.socket.http.cps=0
>>  #httpclient.socket.https.cps=0
>>  </pre>
>> +<p><b>Method to calculate Response size</b><br></br>
>> +An optional property to allow change the method to get response size:<br></br>
>> +<ul><li>Default behavior: Size in bytes is the response data length (without response headers)
>> +<pre>http.getbytes.type=default</pre></li>
>> +<li>Response headers length and default (response data length)
>> +<pre>http.getbytes.type=calculate_headers_size+default</pre></li>
>> +<li>Response headers length and value of "Content-length" header (generally provide by web server)<br></br>
>> +Useful when web server uses a deflate/gzip method to compress response data
>> +<pre>http.getbytes.type=calculate_headers_size+content-length_value</pre></li></ul>
>> +</p>
>>  <links>
>>         <link href="test_plan.html#assertions">Assertion</link>
>>         <link href="build-web-test-plan.html">Building a Web Test Plan</link>
>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: notifications-unsubscribe@jakarta.apache.org
>> For additional commands, e-mail: notifications-help@jakarta.apache.org
>>
>>
>>     
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: dev-help@jakarta.apache.org
>
>
>   


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: dev-help@jakarta.apache.org