You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jmeter.apache.org by pm...@apache.org on 2016/05/04 19:49:51 UTC
svn commit: r1742324 -
/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPHC4Impl.java
Author: pmouawad
Date: Wed May 4 19:49:51 2016
New Revision: 1742324
URL: http://svn.apache.org/viewvc?rev=1742324&view=rev
Log:
Bug 59401 - The HttpClient4 implementation uncompresses the compressed response but removes Content-Encoding response header when request has header "Accept-Encoding = gzip, deflate"
Bugzilla Id: 59401
Modified:
jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPHC4Impl.java
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=1742324&r1=1742323&r2=1742324&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 Wed May 4 19:49:51 2016
@@ -59,6 +59,7 @@ import org.apache.http.client.Credential
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.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
@@ -186,6 +187,48 @@ public class HTTPHC4Impl extends HTTPHCA
};
/**
+ * Attribute name used to store headers in {@link BasicHttpContext}
+ */
+ private static final String JMETER_RESPONSE_BACKUP_HEADERS = "__jmeter.RESPONSE_BACKUP_HEADERS";
+
+ /**
+ * Headers to save
+ */
+ private static final String[] HEADERS_TO_SAVE = new String[]{
+ "content-length",
+ "content-encoding",
+ "content-md5"
+ };
+
+ /**
+ * Custom implementation that backups headers related to Compressed responses
+ * that HC core {@link ResponseContentEncoding} removes after uncompressing
+ */
+ private static final HttpResponseInterceptor RESPONSE_CONTENT_ENCODING = new ResponseContentEncoding() {
+ @Override
+ public void process(HttpResponse response, HttpContext context)
+ throws HttpException, IOException {
+
+ context.removeAttribute(JMETER_RESPONSE_BACKUP_HEADERS);
+ final HttpEntity entity = response.getEntity();
+ final HttpClientContext clientContext = HttpClientContext.adapt(context);
+ final RequestConfig requestConfig = clientContext.getRequestConfig();
+ if (requestConfig.isContentCompressionEnabled() && entity != null && entity.getContentLength() != 0) {
+ final Header ceheader = entity.getContentEncoding();
+ if (ceheader != null) {
+ ArrayList<Header[]> headersToSave = new ArrayList<>(3);
+ for(String name : HEADERS_TO_SAVE) {
+ Header[] hdr = response.getHeaders(name); // empty if none
+ headersToSave.add(hdr);
+ }
+ context.setAttribute(JMETER_RESPONSE_BACKUP_HEADERS, headersToSave);
+ }
+ }
+ super.process(response, clientContext);
+ }
+ };
+
+ /**
* 1 HttpClient instance per combination of (HttpClient,HttpClientKey)
*/
private static final ThreadLocal<Map<HttpClientKey, HttpClient>> HTTPCLIENTS_CACHE_PER_THREAD_AND_HTTPCLIENTKEY =
@@ -357,7 +400,7 @@ public class HTTPHC4Impl extends HTTPHCA
res.setResponseMessage(statusLine.getReasonPhrase());
res.setSuccessful(isSuccessCode(statusCode));
- res.setResponseHeaders(getResponseHeaders(httpResponse));
+ res.setResponseHeaders(getResponseHeaders(httpResponse, localContext));
if (res.isRedirect()) {
final Header headerLocation = httpResponse.getLastHeader(HTTPConstants.HEADER_LOCATION);
if (headerLocation == null) { // HTTP protocol violation, but avoids NPE
@@ -750,7 +793,7 @@ public class HTTPHC4Impl extends HTTPHCA
}
// see https://issues.apache.org/jira/browse/HTTPCORE-397
((AbstractHttpClient) httpClient).setReuseStrategy(DefaultClientConnectionReuseStrategy.INSTANCE);
- ((AbstractHttpClient) httpClient).addResponseInterceptor(new ResponseContentEncoding());
+ ((AbstractHttpClient) httpClient).addResponseInterceptor(RESPONSE_CONTENT_ENCODING);
((AbstractHttpClient) httpClient).addResponseInterceptor(METRICS_SAVER); // HACK
((AbstractHttpClient) httpClient).addRequestInterceptor(METRICS_RESETTER);
@@ -894,24 +937,47 @@ public class HTTPHC4Impl extends HTTPHCA
*
* @param response
* containing the headers
+ * @param localContext {@link HttpContext}
* @return string containing the headers, one per line
*/
- private String getResponseHeaders(HttpResponse response) {
+ private String getResponseHeaders(HttpResponse response, HttpContext localContext) {
StringBuilder headerBuf = new StringBuilder();
- Header[] rh = response.getAllHeaders();
headerBuf.append(response.getStatusLine());// header[0] is not the status line...
headerBuf.append("\n"); // $NON-NLS-1$
+ Header[] rh = response.getAllHeaders();
for (Header responseHeader : rh) {
- headerBuf.append(responseHeader.getName());
- headerBuf.append(": "); // $NON-NLS-1$
- headerBuf.append(responseHeader.getValue());
- headerBuf.append("\n"); // $NON-NLS-1$
+ writeResponseHeader(headerBuf, responseHeader);
}
+ List<Header[]> backupHeaders = (List<Header[]>) localContext.getAttribute(JMETER_RESPONSE_BACKUP_HEADERS);
+ if(backupHeaders != null) {
+ for (Header[] headers : backupHeaders) {
+ for (Header responseHeader: headers) {
+ if (response.containsHeader(responseHeader.getName())) {
+ break; // it was not deleted, so don't store it again
+ }
+ writeResponseHeader(headerBuf, responseHeader);
+ }
+ }
+ }
+
return headerBuf.toString();
}
/**
+ * Write responseHeader to headerBuffer
+ * @param headerBuffer {@link StringBuilder}
+ * @param responseHeader {@link Header}
+ */
+ private void writeResponseHeader(StringBuilder headerBuffer,
+ Header responseHeader) {
+ headerBuffer.append(responseHeader.getName())
+ .append(": ") // $NON-NLS-1$
+ .append(responseHeader.getValue())
+ .append("\n"); // $NON-NLS-1$
+ }
+
+ /**
* Extracts all the required cookies for that particular URL request and
* sets them in the <code>HttpMethod</code> passed in.
*
@@ -1016,10 +1082,7 @@ public class HTTPHC4Impl extends HTTPHCA
for (Header requestHeader : requestHeaders) {
// Exclude the COOKIE header, since cookie is reported separately in the sample
if (!HTTPConstants.HEADER_COOKIE.equalsIgnoreCase(requestHeader.getName())) {
- hdrs.append(requestHeader.getName());
- hdrs.append(": "); // $NON-NLS-1$
- hdrs.append(requestHeader.getValue());
- hdrs.append("\n"); // $NON-NLS-1$
+ writeResponseHeader(hdrs, requestHeader);
}
}