Author: pmouawad
Date: Tue Mar 28 10:14:49 2017
New Revision: 1789082

URL: http://svn.apache.org/viewvc?rev=1789082&view=rev
Log:
Bug 60928 - Http Request : Connection Leak when keepalive is used with Embedded 
Resources
Bugzilla Id: 60928

Modified:
    
jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPHC4Impl.java
    jmeter/trunk/xdocs/changes.xml

Modified: 
jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPHC4Impl.java
URL: 
http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPHC4Impl.java?rev=1789082&r1=1789081&r2=1789082&view=diff
==============================================================================
--- 
jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPHC4Impl.java
 (original)
+++ 
jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPHC4Impl.java
 Tue Mar 28 10:14:49 2017
@@ -61,11 +61,11 @@ import org.apache.http.auth.NTCredential
 import org.apache.http.client.AuthCache;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.client.CredentialsProvider;
-import org.apache.http.client.HttpClient;
 import org.apache.http.client.HttpRequestRetryHandler;
 import org.apache.http.client.config.CookieSpecs;
 import org.apache.http.client.config.RequestConfig;
 import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpHead;
@@ -97,6 +97,7 @@ import org.apache.http.entity.mime.conte
 import org.apache.http.impl.auth.BasicScheme;
 import org.apache.http.impl.client.AbstractHttpClient;
 import org.apache.http.impl.client.BasicAuthCache;
+import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.DefaultClientConnectionReuseStrategy;
 import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
 import org.apache.http.impl.client.DefaultHttpClient;
@@ -137,6 +138,7 @@ import org.apache.jmeter.threads.JMeterV
 import org.apache.jmeter.util.JMeterUtils;
 import org.apache.jmeter.util.JsseSSLManager;
 import org.apache.jmeter.util.SSLManager;
+import org.apache.jorphan.util.JOrphanUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -254,7 +256,7 @@ public class HTTPHC4Impl extends HTTPHCA
     /**
      * 1 HttpClient instance per combination of (HttpClient,HttpClientKey)
      */
-    private static final ThreadLocal<Map<HttpClientKey, HttpClient>> 
HTTPCLIENTS_CACHE_PER_THREAD_AND_HTTPCLIENTKEY = 
+    private static final ThreadLocal<Map<HttpClientKey, CloseableHttpClient>> 
HTTPCLIENTS_CACHE_PER_THREAD_AND_HTTPCLIENTKEY = 
         InheritableThreadLocal.withInitial(() -> new HashMap<>(5));
 
     // Scheme used for slow HTTP sockets. Cannot be set as a default, because 
must be set on an HttpClient instance.
@@ -348,7 +350,7 @@ public class HTTPHC4Impl extends HTTPHCA
 
         HTTPSampleResult res = createSampleResult(url, method);
 
-        HttpClient httpClient = setupClient(url, res);
+        CloseableHttpClient httpClient = setupClient(url, res);
 
         HttpRequestBase httpRequest = null;
         try {
@@ -400,14 +402,14 @@ public class HTTPHC4Impl extends HTTPHCA
         if (cacheManager != null && HTTPConstants.GET.equalsIgnoreCase(method) 
&& cacheManager.inCache(url)) {
             return updateSampleResultForResourceInCache(res);
         }
-
+        CloseableHttpResponse httpResponse = null;
         try {
             currentRequest = httpRequest;
             handleMethod(method, res, httpRequest, localContext);
             // store the SampleResult in LocalContext to compute connect time
             localContext.setAttribute(SAMPLER_RESULT_TOKEN, res);
             // perform the sample
-            HttpResponse httpResponse = 
+            httpResponse = 
                     executeRequest(httpClient, httpRequest, localContext, url);
 
             // Needs to be done after execute to pick up all the headers
@@ -510,6 +512,7 @@ public class HTTPHC4Impl extends HTTPHCA
             errorResult(e, res);
             return res;
         } finally {
+            JOrphanUtils.closeQuietly(httpResponse);
             currentRequest = null;
             
JMeterContextService.getContext().getSamplerContext().remove(HTTPCLIENT_TOKEN);
         }
@@ -616,7 +619,7 @@ public class HTTPHC4Impl extends HTTPHCA
      * @throws IOException
      * @throws ClientProtocolException
      */
-    private HttpResponse executeRequest(final HttpClient httpClient,
+    private CloseableHttpResponse executeRequest(final CloseableHttpClient 
httpClient,
             final HttpRequestBase httpRequest, final HttpContext localContext, 
final URL url)
             throws IOException, ClientProtocolException {
         AuthManager authManager = getAuthManager();
@@ -624,7 +627,7 @@ public class HTTPHC4Impl extends HTTPHCA
             Subject subject = authManager.getSubjectForUrl(url);
             if (subject != null) {
                 try {
-                    return Subject.doAs(subject,
+                    return (CloseableHttpResponse) Subject.doAs(subject,
                             (PrivilegedExceptionAction<HttpResponse>) () ->
                                     httpClient.execute(httpRequest, 
localContext));
                 } catch (PrivilegedActionException e) {
@@ -751,9 +754,9 @@ public class HTTPHC4Impl extends HTTPHCA
         }
     }
 
-    private HttpClient setupClient(URL url, SampleResult res) {
+    private CloseableHttpClient setupClient(URL url, SampleResult res) {
 
-        Map<HttpClientKey, HttpClient> mapHttpClientPerHttpClientKey = 
HTTPCLIENTS_CACHE_PER_THREAD_AND_HTTPCLIENTKEY.get();
+        Map<HttpClientKey, CloseableHttpClient> mapHttpClientPerHttpClientKey 
= HTTPCLIENTS_CACHE_PER_THREAD_AND_HTTPCLIENTKEY.get();
         
         final String host = url.getHost();
         String proxyHost = getProxyHost();
@@ -778,10 +781,10 @@ public class HTTPHC4Impl extends HTTPHCA
         // Lookup key - must agree with all the values used to create the 
HttpClient.
         HttpClientKey key = new HttpClientKey(url, useProxy, proxyHost, 
proxyPort, proxyUser, proxyPass);
         
-        HttpClient httpClient = null;
+        CloseableHttpClient httpClient = null;
         boolean concurrentDwn = this.testElement.isConcurrentDwn();
         if(concurrentDwn) {
-            httpClient = (HttpClient) 
JMeterContextService.getContext().getSamplerContext().get(HTTPCLIENT_TOKEN);
+            httpClient = (CloseableHttpClient) 
JMeterContextService.getContext().getSamplerContext().get(HTTPCLIENT_TOKEN);
         }
         
         if (httpClient == null) {
@@ -1136,7 +1139,7 @@ public class HTTPHC4Impl extends HTTPHCA
      * @param authManager {@link AuthManager}
      * @param key key
      */
-    private void setConnectionAuthorization(HttpClient client, URL url, 
AuthManager authManager, HttpClientKey key) {
+    private void setConnectionAuthorization(CloseableHttpClient client, URL 
url, AuthManager authManager, HttpClientKey key) {
         CredentialsProvider credentialsProvider = 
             ((AbstractHttpClient) client).getCredentialsProvider();
         if (authManager != null) {
@@ -1535,12 +1538,12 @@ public class HTTPHC4Impl extends HTTPHCA
      */
     private void closeThreadLocalConnections() {
         // Does not need to be synchronised, as all access is from same thread
-        Map<HttpClientKey, HttpClient> mapHttpClientPerHttpClientKey = 
HTTPCLIENTS_CACHE_PER_THREAD_AND_HTTPCLIENTKEY.get();
+        Map<HttpClientKey, CloseableHttpClient> mapHttpClientPerHttpClientKey 
= HTTPCLIENTS_CACHE_PER_THREAD_AND_HTTPCLIENTKEY.get();
         if ( mapHttpClientPerHttpClientKey != null ) {
-            for ( HttpClient cl : mapHttpClientPerHttpClientKey.values() ) {
+            for ( CloseableHttpClient cl : 
mapHttpClientPerHttpClientKey.values() ) {
                 ((AbstractHttpClient) cl).clearRequestInterceptors(); 
                 ((AbstractHttpClient) cl).clearResponseInterceptors();
-                ((AbstractHttpClient) cl).close();
+                JOrphanUtils.closeQuietly(cl);
                 cl.getConnectionManager().shutdown();
             }
             mapHttpClientPerHttpClientKey.clear();

Modified: jmeter/trunk/xdocs/changes.xml
URL: 
http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1789082&r1=1789081&r2=1789082&view=diff
==============================================================================
--- jmeter/trunk/xdocs/changes.xml [utf-8] (original)
+++ jmeter/trunk/xdocs/changes.xml [utf-8] Tue Mar 28 10:14:49 2017
@@ -357,6 +357,7 @@ listeners hold and a rework of the way G
     <li><bug>60778</bug>Http Java Impl does not show Authorization header in 
SampleResult even if it is sent</li>
     <li><bug>60837</bug>GET with body, PUT are not retried even if 
<code>httpclient4.retrycount</code> is higher than 0</li>
     <li><bug>60842</bug>Trim extracted URLs when loading embedded resources 
using the Lagarto based HTML Parser.</li>
+    <li><bug>60928</bug>Http Request : Connection Leak when keepalive is used 
with Embedded Resources</li>
 </ul>
 
 <h3>Other Samplers</h3>


Reply via email to