Bug 60575 - HTTP request: Even if there are no Parameters, a Body is sent for GET method
Summary: HTTP request: Even if there are no Parameters, a Body is sent for GET method
Status: RESOLVED FIXED
Alias: None
Product: JMeter
Classification: Unclassified
Component: HTTP (show other bugs)
Version: 3.1
Hardware: All All
: P1 regression (vote)
Target Milestone: ---
Assignee: JMeter issues mailing list
URL:
Keywords:
: 60579 60941 (view as bug list)
Depends on:
Blocks:
 
Reported: 2017-01-11 19:35 UTC by Jerome
Modified: 2017-03-30 13:44 UTC (History)
4 users (show)



Attachments
JMX (1.79 KB, application/xml)
2017-01-11 19:35 UTC, Jerome
Details
JMX showing the error (11.39 KB, application/xml)
2017-01-12 12:09 UTC, Jerome
Details
Only send Parameters as Post-Body, if there are Parameters (1.19 KB, patch)
2017-01-12 14:28 UTC, Felix Schumacher
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jerome 2017-01-11 19:35:50 UTC
Created attachment 34610 [details]
JMX

When executing the attached JMX (one single HTTPS request), it works fine on JMeter 3.0 (with HttpClient 4.5.2, HttpCore 4.4.4). It fails with JMeter 3.1 (HttpClient 4.5.2, HttpCore 4.4.5), the server throws an Http 500 error.

Works fine with HttpClient 3.1 in both version, but it's an EOL client. Nothing shown in JMeter logs, from JMeter point of view everything is fine.
Comment 1 Jerome 2017-01-11 19:41:00 UTC
The detailed stack on server side when running with JMeter 3.1: (although it doesn't help much)

<html><head><title>Apache Tomcat/7.0.52 - Rapport d''erreur</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>Etat HTTP 500 - Unexpected exception occurred: runtime.support.UnimplementedMethodOptionException</h1><HR size="1" noshade="noshade"><p><b>type</b> Rapport d''exception</p><p><b>message</b> <u>Unexpected exception occurred: runtime.support.UnimplementedMethodOptionException</u></p><p><b>description</b> <u>Le serveur a rencontré une erreur interne qui l''a empêché de satisfaire la requête.</u></p><p><b>exception</b> <pre>runtime.support.InternalException: Unexpected exception occurred: runtime.support.UnimplementedMethodOptionException
	com.pearson.powerschool.web.interceptor.LegacySystemInterceptor$ActionRunner.run(LegacySystemInterceptor.java:44)
	com.pearson.powerschool.web.interceptor.LegacySystemHandler.runInHandler(LegacySystemHandler.java:34)
	com.pearson.powerschool.web.interceptor.LegacySystemInterceptor.intercept(LegacySystemInterceptor.java:27)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
	com.pearson.powerschool.web.interceptor.PowerSchoolEnabledInterceptor.intercept(PowerSchoolEnabledInterceptor.java:21)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
	com.pearson.powerschool.web.interceptor.HttpHeadInterceptor.intercept(HttpHeadInterceptor.java:25)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
	org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
	org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:564)
	org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:81)
	org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter.doFilter(StrutsExecuteFilter.java:93)
	com.opensymphony.sitemesh.webapp.SiteMeshFilter.obtainContent(SiteMeshFilter.java:129)
	com.opensymphony.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:77)
	com.pearson.powerschool.web.filter.PSSiteMeshFilter.doFilter(PSSiteMeshFilter.java:76)
	org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter.doFilter(StrutsPrepareFilter.java:91)
	com.pearson.powerschool.web.filter.LTKFilter.doFilterGuarded(LTKFilter.java:350)
	com.pearson.powerschool.web.filter.LTKFilter.doFilter(LTKFilter.java:164)
	com.pearson.powerschool.web.filter.ResponseTimeMonitorFilter.doFilter(ResponseTimeMonitorFilter.java:66)
	com.pearson.powerschool.web.filter.PSSAMLDelegatingFilterProxy.doFilter(PSSAMLDelegatingFilterProxy.java:79)
	com.pearson.powerschool.web.filter.CleanupFilter.doFilter(CleanupFilter.java:146)
	com.pearson.powerschool.web.servlet.TrustedForwardedForResolutionFilter.doFilter(TrustedForwardedForResolutionFilter.java:328)
	org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:71)
</pre></p><p><b>cause mère</b> <pre>runtime.support.UnimplementedMethodOptionException: Unexpected call to WEB__ProcessUpload! ContentType=text/plain; charset=ISO-8859-1
	com.pearson.powerschool.webserver.web.WEB__ProcessUpload.WEB__ProcessUpload(WEB__ProcessUpload.java:86)
	com.pearson.powerschool.webserver.web.WEB_ReceiveMessageBody.WEB_ReceiveMessageBody(WEB_ReceiveMessageBody.java:176)
	com.pearson.powerschool.web.interceptor.PublicInterceptor.intercept(PublicInterceptor.java:32)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
	com.pearson.powerschool.web.interceptor.PageHitInterceptor.intercept(PageHitInterceptor.java:59)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
	com.pearson.powerschool.web.interceptor.HandleHitInterceptor.intercept(HandleHitInterceptor.java:168)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
	org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:253)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
	com.pearson.powerschool.web.interceptor.LegacySystemInterceptor$ActionRunner.run(LegacySystemInterceptor.java:42)
	com.pearson.powerschool.web.interceptor.LegacySystemHandler.runInHandler(LegacySystemHandler.java:34)
	com.pearson.powerschool.web.interceptor.LegacySystemInterceptor.intercept(LegacySystemInterceptor.java:27)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
	com.pearson.powerschool.web.interceptor.PowerSchoolEnabledInterceptor.intercept(PowerSchoolEnabledInterceptor.java:21)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
	com.pearson.powerschool.web.interceptor.HttpHeadInterceptor.intercept(HttpHeadInterceptor.java:25)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
	org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
	org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:564)
	org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:81)
	org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter.doFilter(StrutsExecuteFilter.java:93)
	com.opensymphony.sitemesh.webapp.SiteMeshFilter.obtainContent(SiteMeshFilter.java:129)
	com.opensymphony.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:77)
	com.pearson.powerschool.web.filter.PSSiteMeshFilter.doFilter(PSSiteMeshFilter.java:76)
	org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter.doFilter(StrutsPrepareFilter.java:91)
	com.pearson.powerschool.web.filter.LTKFilter.doFilterGuarded(LTKFilter.java:350)
	com.pearson.powerschool.web.filter.LTKFilter.doFilter(LTKFilter.java:164)
	com.pearson.powerschool.web.filter.ResponseTimeMonitorFilter.doFilter(ResponseTimeMonitorFilter.java:66)
	com.pearson.powerschool.web.filter.PSSAMLDelegatingFilterProxy.doFilter(PSSAMLDelegatingFilterProxy.java:79)
	com.pearson.powerschool.web.filter.CleanupFilter.doFilter(CleanupFilter.java:146)
	com.pearson.powerschool.web.servlet.TrustedForwardedForResolutionFilter.doFilter(TrustedForwardedForResolutionFilter.java:328)
	org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:71)
</pre></p><p><b>note</b> <u>La trace complète de la cause mère de cette erreur est disponible dans les fichiers journaux de Apache Tomcat/7.0.52.</u></p><HR size="1" noshade="noshade"><h3>Apache Tomcat/7.0.52</h3></body></html>
Comment 2 Philippe Mouawad 2017-01-11 19:45:28 UTC
Hello Jérôme,
Could you add in user.properties:

log_level.org.apache.http.wire=ERROR
log_level.org.apache.http=DEBUG

With each version and attach jmeter.log file for each version ?
Thank you
Comment 3 Jerome 2017-01-11 19:46:45 UTC
I think I got the issue: JMeter 3.1 has added support for GET request body. It seems like it's sending a get body, even if none have been set. By simply adding a GET parameter name=value, it works again.

So the bug is linked to GET request body support.
Comment 4 Jerome 2017-01-11 19:51:51 UTC
Got a little further, found this in the jmx:
<boolProp name="HTTPSampler.postBodyRaw">true</boolProp>

Possibly my mistake, I had body data field tab open in the request, with nothing set.
Comment 5 Jerome 2017-01-11 20:13:27 UTC
Closing as invalid, since it's a misconfiguration i've made, not a JMeter bug. :)
Comment 6 Jerome 2017-01-12 12:07:05 UTC
Reopening since the issue is not resolved. It still happens with the following JMX. It contains the request both with and without a dummy http query parameter.

When the query parameter is absent, a get body is sent to the server which doesn't expect this. The server fails and throws an exception, because it doesn't support GET request body. (Tomcat 7.0.52)
Comment 7 Jerome 2017-01-12 12:09:21 UTC
Created attachment 34614 [details]
JMX showing the error

JMX reproducing the error. It seems that JMeter is always sending a GET request body (even when empty) for GET requests without parameters.
Comment 8 Felix Schumacher 2017-01-12 14:26:40 UTC
*** Bug 60579 has been marked as a duplicate of this bug. ***
Comment 9 Felix Schumacher 2017-01-12 14:28:51 UTC
Created attachment 34617 [details]
Only send Parameters as Post-Body, if there are Parameters
Comment 10 Jerome 2017-01-12 14:47:40 UTC
Thanks Felix for the patch :)

Is there any release date for JMeter 3.2 which includes this patch?
Comment 11 Felix Schumacher 2017-01-13 17:48:08 UTC
Discussion about the next release is taking place on the mailing list, it could be soon.

On the other hand, the patch makes one test (PutWriterTest) fail. I believe the test is not correct and I think it uncovers a problem in PutWriter#setHeaders.

There it tests for sampler.getSendParameterValuesAsPostBody() and assumes that there are arguments in the sampler - which is not true for the cited test above. That path of code will lead to a Content-Type header with no body (which is probably wrong even for a PUT request.).
Comment 12 Philippe Mouawad 2017-01-19 06:38:18 UTC
Hi Felix,
Could you merge your patch so that we test as much as possible before release?
Thanks
Comment 13 Felix Schumacher 2017-01-19 20:25:05 UTC
Date: Thu Jan 19 20:19:57 2017
New Revision: 1779520

URL: http://svn.apache.org/viewvc?rev=1779520&view=rev
Log:
Split up test case to test only one thing at a time. Correct the second
test case at the same time. PutWriter would use all unnamed arguments for
the body of the request, so set them. This is in preparation for Bug 60575.

Bugzilla Id: 60575

Modified:
    jmeter/trunk/test/src/org/apache/jmeter/protocol/http/sampler/PutWriterTest.java
Comment 14 Felix Schumacher 2017-01-19 20:39:10 UTC
Date: Thu Jan 19 20:35:15 2017
New Revision: 1779521

URL: http://svn.apache.org/viewvc?rev=1779521&view=rev
Log:
Clarify and correct logic of getSendParameterValuesAsPostBody, so that it only
returns true, when there are parameters and none of those have a name.

Without this requests could have a content-type header without a body.

Bugzilla Id: 60575

Modified:
    jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java
Comment 15 Felix Schumacher 2017-01-19 20:41:33 UTC
Can you test a current nightly (well, the one from next night) and report, if it solves your problem? If so, please close this bug.
Comment 16 Jerome 2017-01-20 08:27:52 UTC
Hi, tested nightly svn revision r1779529: it works fine now. Thanks for the fix :)
Comment 17 Felix Schumacher 2017-01-20 18:19:01 UTC
Date: Fri Jan 20 18:17:01 2017
New Revision: 1779663

URL: http://svn.apache.org/viewvc?rev=1779663&view=rev
Log:
Add changes.xml entry for bug 60575

Modified:
    jmeter/trunk/xdocs/changes.xml
Comment 18 lpetr 2017-02-02 10:44:40 UTC
Hello,

I see regression of the issue in latest Jenkins build #5787 - JMeter r1781326.


See example:
GET https://www.google.com/

GET data:

[no cookies]

Request Headers:
Connection: keep-alive
Host: www.google.com
User-Agent: Apache-HttpClient/4.5.3 (Java/1.8.0_111)
Comment 19 Felix Schumacher 2017-02-03 16:25:10 UTC
(In reply to lpetr from comment #18)
> Hello,
> 
> I see regression of the issue in latest Jenkins build #5787 - JMeter
> r1781326.
> 
> 
> See example:
> GET https://www.google.com/
> 
> GET data:
> 
> [no cookies]
> 
> Request Headers:
> Connection: keep-alive
> Host: www.google.com
> User-Agent: Apache-HttpClient/4.5.3 (Java/1.8.0_111)

Can you be a bit more specific, what you are expecting and what you think fails?

I have no problem doing a get request on Google.
Comment 20 Philippe Mouawad 2017-02-04 20:52:50 UTC
*** Bug 60682 has been marked as a duplicate of this bug. ***
Comment 21 lpetr 2017-02-05 18:43:03 UTC
Hello,

As I explained in the ticket #60579 (which was linked to this issue as duplicate), since JMeter 3.1 "HTTP request" sampler adds unnecessary "Content-Type: text/plain; charset=ISO-8859-1" header into GET requests which has NO DATA in body.
It could cause request rejection on FW, because it's considered malicious.


RFC2616 section 7.2.1 says:

"A Content-Type specifies the media type of the underlying data. A Content-Encoding may be used to indicate any additional content coding applied to the type, usually for the purpose of data compression, that is a property of the resource requested. The default for the content encoding is none (i.e., the identity function)."

If my understanding is correct, the header "Content-Type" should not be present for simple GET requests without "entity-body", because there are no "underlying data".


Here are GET requests to google for simple comparison of JMeter 3.0 and JMeter 3.1 behavior:

------
Behavior of the JMeter 3.0 HTTP Sampler (NO content type and length header -  expected):
------
GET https://google.com/

[no cookies]

Request Headers:
Connection: keep-alive
Host: google.com
User-Agent: Apache-HttpClient/4.5.2 (Java/1.8.0_111)


-----
Behavior of the JMeter 3.1 HTTP Sampler (Content type header send - possible problem):
-----
GET http://www.google.com/

GET data:
[no cookies]

Request Headers:
Connection: keep-alive
Content-Length: 0
Content-Type: text/plain; charset=ISO-8859-1
Host: www.google.com
User-Agent: Apache-HttpClient/4.5.2 (Java/1.8.0_111)
Comment 22 lpetr 2017-02-05 19:11:10 UTC
Hello,


I did a retest with build #5796 and it works as expected! 
You can ignore my previous comments #18, #21..

Thanks for support!
Comment 23 UbikLoadPack support 2017-03-30 13:44:19 UTC
*** Bug 60941 has been marked as a duplicate of this bug. ***