Lines 483-490
Link Here
|
483 |
|
483 |
|
484 |
private volatile HttpUriRequest currentRequest; // Accessed from multiple threads |
484 |
private volatile HttpUriRequest currentRequest; // Accessed from multiple threads |
485 |
|
485 |
|
486 |
private volatile boolean resetSSLContext; |
|
|
487 |
|
488 |
protected HTTPHC4Impl(HTTPSamplerBase testElement) { |
486 |
protected HTTPHC4Impl(HTTPSamplerBase testElement) { |
489 |
super(testElement); |
487 |
super(testElement); |
490 |
} |
488 |
} |
Lines 539-544
Link Here
|
539 |
log.debug("Start : sample {} method {} followingRedirect {} depth {}", |
537 |
log.debug("Start : sample {} method {} followingRedirect {} depth {}", |
540 |
url, method, areFollowingRedirect, frameDepth); |
538 |
url, method, areFollowingRedirect, frameDepth); |
541 |
} |
539 |
} |
|
|
540 |
JMeterVariables jMeterVariables = JMeterContextService.getContext().getVariables(); |
542 |
|
541 |
|
543 |
HTTPSampleResult res = createSampleResult(url, method); |
542 |
HTTPSampleResult res = createSampleResult(url, method); |
544 |
|
543 |
|
Lines 549-555
Link Here
|
549 |
clientContext.setAttribute(CONTEXT_ATTRIBUTE_AUTH_MANAGER, getAuthManager()); |
548 |
clientContext.setAttribute(CONTEXT_ATTRIBUTE_AUTH_MANAGER, getAuthManager()); |
550 |
|
549 |
|
551 |
try { |
550 |
try { |
552 |
httpClient = setupClient(url, clientContext); |
551 |
httpClient = setupClient(jMeterVariables, url, clientContext); |
553 |
URI uri = url.toURI(); |
552 |
URI uri = url.toURI(); |
554 |
if (method.equals(HTTPConstants.POST)) { |
553 |
if (method.equals(HTTPConstants.POST)) { |
555 |
httpRequest = new HttpPost(uri); |
554 |
httpRequest = new HttpPost(uri); |
Lines 589-595
Link Here
|
589 |
return res; |
588 |
return res; |
590 |
} |
589 |
} |
591 |
|
590 |
|
592 |
setupClientContextBeforeSample(localContext); |
591 |
setupClientContextBeforeSample(jMeterVariables, localContext); |
593 |
|
592 |
|
594 |
res.sampleStart(); |
593 |
res.sampleStart(); |
595 |
|
594 |
|
Lines 609-615
Link Here
|
609 |
|
608 |
|
610 |
// Needs to be done after execute to pick up all the headers |
609 |
// Needs to be done after execute to pick up all the headers |
611 |
final HttpRequest request = (HttpRequest) localContext.getAttribute(HttpCoreContext.HTTP_REQUEST); |
610 |
final HttpRequest request = (HttpRequest) localContext.getAttribute(HttpCoreContext.HTTP_REQUEST); |
612 |
extractClientContextAfterSample(localContext); |
611 |
extractClientContextAfterSample(jMeterVariables, localContext); |
613 |
// We've finished with the request, so we can add the LocalAddress to it for display |
612 |
// We've finished with the request, so we can add the LocalAddress to it for display |
614 |
if (localAddress != null) { |
613 |
if (localAddress != null) { |
615 |
request.addHeader(HEADER_LOCAL_ADDRESS, localAddress.toString()); |
614 |
request.addHeader(HEADER_LOCAL_ADDRESS, localAddress.toString()); |
Lines 718-731
Link Here
|
718 |
/** |
717 |
/** |
719 |
* Store in JMeter Variables the UserToken so that the SSL context is reused |
718 |
* Store in JMeter Variables the UserToken so that the SSL context is reused |
720 |
* See <a href="https://bz.apache.org/bugzilla/show_bug.cgi?id=57804">Bug 57804</a> |
719 |
* See <a href="https://bz.apache.org/bugzilla/show_bug.cgi?id=57804">Bug 57804</a> |
|
|
720 |
* @param jMeterVariables {@link JMeterVariables} |
721 |
* @param localContext {@link HttpContext} |
721 |
* @param localContext {@link HttpContext} |
722 |
*/ |
722 |
*/ |
723 |
private void extractClientContextAfterSample(HttpContext localContext) { |
723 |
private void extractClientContextAfterSample(JMeterVariables jMeterVariables, HttpContext localContext) { |
724 |
Object userToken = localContext.getAttribute(HttpClientContext.USER_TOKEN); |
724 |
Object userToken = localContext.getAttribute(HttpClientContext.USER_TOKEN); |
725 |
if(userToken != null) { |
725 |
if(userToken != null) { |
726 |
log.debug("Extracted from HttpContext user token:{} storing it as JMeter variable:{}", userToken, JMETER_VARIABLE_USER_TOKEN); |
726 |
log.debug("Extracted from HttpContext user token:{} storing it as JMeter variable:{}", userToken, JMETER_VARIABLE_USER_TOKEN); |
727 |
// During recording JMeterContextService.getContext().getVariables() is null |
727 |
// During recording JMeterContextService.getContext().getVariables() is null |
728 |
JMeterVariables jMeterVariables = JMeterContextService.getContext().getVariables(); |
|
|
729 |
if (jMeterVariables != null) { |
728 |
if (jMeterVariables != null) { |
730 |
jMeterVariables.putObject(JMETER_VARIABLE_USER_TOKEN, userToken); |
729 |
jMeterVariables.putObject(JMETER_VARIABLE_USER_TOKEN, userToken); |
731 |
} |
730 |
} |
Lines 735-746
Link Here
|
735 |
/** |
734 |
/** |
736 |
* Configure the UserToken so that the SSL context is reused |
735 |
* Configure the UserToken so that the SSL context is reused |
737 |
* See <a href="https://bz.apache.org/bugzilla/show_bug.cgi?id=57804">Bug 57804</a> |
736 |
* See <a href="https://bz.apache.org/bugzilla/show_bug.cgi?id=57804">Bug 57804</a> |
|
|
737 |
* @param jMeterVariables {@link JMeterVariables} |
738 |
* @param localContext {@link HttpContext} |
738 |
* @param localContext {@link HttpContext} |
739 |
*/ |
739 |
*/ |
740 |
private void setupClientContextBeforeSample(HttpContext localContext) { |
740 |
private void setupClientContextBeforeSample(JMeterVariables jMeterVariables, HttpContext localContext) { |
741 |
Object userToken = null; |
741 |
Object userToken = null; |
742 |
// During recording JMeterContextService.getContext().getVariables() is null |
742 |
// During recording JMeterContextService.getContext().getVariables() is null |
743 |
JMeterVariables jMeterVariables = JMeterContextService.getContext().getVariables(); |
|
|
744 |
if(jMeterVariables != null) { |
743 |
if(jMeterVariables != null) { |
745 |
userToken = jMeterVariables.getObject(JMETER_VARIABLE_USER_TOKEN); |
744 |
userToken = jMeterVariables.getObject(JMETER_VARIABLE_USER_TOKEN); |
746 |
} |
745 |
} |
Lines 934-940
Link Here
|
934 |
} |
933 |
} |
935 |
} |
934 |
} |
936 |
|
935 |
|
937 |
private CloseableHttpClient setupClient(URL url, HttpClientContext clientContext) throws GeneralSecurityException { |
936 |
private CloseableHttpClient setupClient(JMeterVariables jMeterVariables, URL url, HttpClientContext clientContext) throws GeneralSecurityException { |
938 |
|
937 |
|
939 |
Map<HttpClientKey, Pair<CloseableHttpClient, PoolingHttpClientConnectionManager>> mapHttpClientPerHttpClientKey = |
938 |
Map<HttpClientKey, Pair<CloseableHttpClient, PoolingHttpClientConnectionManager>> mapHttpClientPerHttpClientKey = |
940 |
HTTPCLIENTS_CACHE_PER_THREAD_AND_HTTPCLIENTKEY.get(); |
939 |
HTTPCLIENTS_CACHE_PER_THREAD_AND_HTTPCLIENTKEY.get(); |
Lines 972-978
Link Here
|
972 |
httpClient = pair != null ? pair.getLeft() : null; |
971 |
httpClient = pair != null ? pair.getLeft() : null; |
973 |
} |
972 |
} |
974 |
|
973 |
|
975 |
resetSSLStateIfNeeded(url, clientContext, pair); |
974 |
resetStateIfNeeded(jMeterVariables, clientContext, mapHttpClientPerHttpClientKey); |
976 |
|
975 |
|
977 |
if (httpClient == null) { // One-time init for this client |
976 |
if (httpClient == null) { // One-time init for this client |
978 |
DnsResolver resolver = this.testElement.getDNSResolver(); |
977 |
DnsResolver resolver = this.testElement.getDNSResolver(); |
Lines 1080-1100
Link Here
|
1080 |
* <li>Close current Idle or Expired connections that hold SSL State</li> |
1079 |
* <li>Close current Idle or Expired connections that hold SSL State</li> |
1081 |
* <li>Remove HttpClientContext.USER_TOKEN from {@link HttpClientContext}</li> |
1080 |
* <li>Remove HttpClientContext.USER_TOKEN from {@link HttpClientContext}</li> |
1082 |
* </ul> |
1081 |
* </ul> |
1083 |
* @param url {@link URL} |
1082 |
* @param jMeterVariables {@link JMeterVariables} |
1084 |
* @param clientContext {@link HttpClientContext} |
1083 |
* @param clientContext {@link HttpClientContext} |
1085 |
* @param pair {@link Pair} holding {@link CloseableHttpClient} and {@link PoolingHttpClientConnectionManager} |
1084 |
* @param mapHttpClientPerHttpClientKey Map of {@link Pair} holding {@link CloseableHttpClient} and {@link PoolingHttpClientConnectionManager} |
1086 |
*/ |
1085 |
*/ |
1087 |
private void resetSSLStateIfNeeded(URL url, HttpClientContext clientContext, |
1086 |
private void resetStateIfNeeded(JMeterVariables jMeterVariables, |
1088 |
Pair<CloseableHttpClient, PoolingHttpClientConnectionManager> pair) { |
1087 |
HttpClientContext clientContext, |
1089 |
if (resetSSLContext && HTTPConstants.PROTOCOL_HTTPS.equalsIgnoreCase(url.getProtocol())) { |
1088 |
Map<HttpClientKey, Pair<CloseableHttpClient, PoolingHttpClientConnectionManager>> mapHttpClientPerHttpClientKey) { |
1090 |
if(pair != null) { |
1089 |
if (resetSSLContext.get()) { |
1091 |
PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = pair.getRight(); |
1090 |
closeCurrentConnections(mapHttpClientPerHttpClientKey); |
1092 |
poolingHttpClientConnectionManager.closeExpiredConnections(); |
|
|
1093 |
poolingHttpClientConnectionManager.closeIdleConnections(1L, TimeUnit.MICROSECONDS); |
1094 |
} |
1095 |
clientContext.removeAttribute(HttpClientContext.USER_TOKEN); |
1091 |
clientContext.removeAttribute(HttpClientContext.USER_TOKEN); |
1096 |
((JsseSSLManager) SSLManager.getInstance()).resetContext(); |
1092 |
((JsseSSLManager) SSLManager.getInstance()).resetContext(); |
1097 |
resetSSLContext = false; |
1093 |
resetSSLContext.set(false); |
|
|
1094 |
} |
1095 |
if (closeConnections.get()) { |
1096 |
closeCurrentConnections(mapHttpClientPerHttpClientKey); |
1097 |
clientContext.removeAttribute(HttpClientContext.USER_TOKEN); |
1098 |
closeConnections.set(false); |
1099 |
} |
1100 |
} |
1101 |
|
1102 |
/** |
1103 |
* @param mapHttpClientPerHttpClientKey |
1104 |
*/ |
1105 |
private void closeCurrentConnections( |
1106 |
Map<HttpClientKey, Pair<CloseableHttpClient, PoolingHttpClientConnectionManager>> mapHttpClientPerHttpClientKey) { |
1107 |
for (Pair<CloseableHttpClient, PoolingHttpClientConnectionManager> pair : |
1108 |
mapHttpClientPerHttpClientKey.values()) { |
1109 |
PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = pair.getRight(); |
1110 |
poolingHttpClientConnectionManager.closeExpiredConnections(); |
1111 |
poolingHttpClientConnectionManager.closeIdleConnections(1L, TimeUnit.MICROSECONDS); |
1098 |
} |
1112 |
} |
1099 |
} |
1113 |
} |
1100 |
|
1114 |
|
Lines 1700-1707
Link Here
|
1700 |
|
1714 |
|
1701 |
@Override |
1715 |
@Override |
1702 |
protected void notifyFirstSampleAfterLoopRestart() { |
1716 |
protected void notifyFirstSampleAfterLoopRestart() { |
1703 |
log.debug("notifyFirstSampleAfterLoopRestart"); |
1717 |
log.debug("notifyFirstSampleAfterLoopRestart called " |
1704 |
resetSSLContext = !USE_CACHED_SSL_CONTEXT; |
1718 |
+ "with config(reuse.http.connections={}, https.use.cached.ssl.context={})", |
|
|
1719 |
REUSE_HTTP_CONNECTIONS, USE_CACHED_SSL_CONTEXT); |
1720 |
closeConnections.set(!REUSE_HTTP_CONNECTIONS); |
1721 |
resetSSLContext.set(!USE_CACHED_SSL_CONTEXT); |
1705 |
} |
1722 |
} |
1706 |
|
1723 |
|
1707 |
@Override |
1724 |
@Override |