|
57 | 57 | import org.apache.http.HttpRequest; |
58 | 58 | import org.apache.http.HttpRequestInterceptor; |
59 | 59 | import org.apache.http.HttpResponse; |
60 | | -import org.apache.http.HttpResponseInterceptor; |
61 | 60 | import org.apache.http.NameValuePair; |
62 | 61 | import org.apache.http.StatusLine; |
63 | 62 | import org.apache.http.auth.AuthSchemeProvider; |
|
72 | 71 | import org.apache.http.client.config.AuthSchemes; |
73 | 72 | import org.apache.http.client.config.CookieSpecs; |
74 | 73 | import org.apache.http.client.config.RequestConfig; |
75 | | -import org.apache.http.client.entity.InputStreamFactory; |
76 | 74 | import org.apache.http.client.entity.UrlEncodedFormEntity; |
77 | 75 | import org.apache.http.client.methods.CloseableHttpResponse; |
78 | 76 | import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; |
|
86 | 84 | import org.apache.http.client.methods.HttpTrace; |
87 | 85 | import org.apache.http.client.methods.HttpUriRequest; |
88 | 86 | import org.apache.http.client.protocol.HttpClientContext; |
89 | | -import org.apache.http.client.protocol.ResponseContentEncoding; |
90 | 87 | import org.apache.http.config.Lookup; |
91 | 88 | import org.apache.http.config.Registry; |
92 | 89 | import org.apache.http.config.RegistryBuilder; |
|
147 | 144 | import org.apache.jmeter.protocol.http.control.DynamicKerberosSchemeFactory; |
148 | 145 | import org.apache.jmeter.protocol.http.control.DynamicSPNegoSchemeFactory; |
149 | 146 | import org.apache.jmeter.protocol.http.control.HeaderManager; |
150 | | -import org.apache.jmeter.protocol.http.sampler.hc.LaxDeflateInputStream; |
151 | | -import org.apache.jmeter.protocol.http.sampler.hc.LaxGZIPInputStream; |
152 | 147 | import org.apache.jmeter.protocol.http.sampler.hc.LazyLayeredConnectionSocketFactory; |
153 | 148 | import org.apache.jmeter.protocol.http.util.ConversionUtils; |
154 | 149 | import org.apache.jmeter.protocol.http.util.HTTPArgument; |
|
166 | 161 | import org.apache.jmeter.util.JsseSSLManager; |
167 | 162 | import org.apache.jmeter.util.SSLManager; |
168 | 163 | import org.apache.jorphan.util.JOrphanUtils; |
169 | | -import org.brotli.dec.BrotliInputStream; |
170 | 164 | import org.slf4j.Logger; |
171 | 165 | import org.slf4j.LoggerFactory; |
172 | 166 |
|
@@ -195,20 +189,8 @@ public class HTTPHC4Impl extends HTTPHCAbstractImpl { |
195 | 189 |
|
196 | 190 | private static final boolean DISABLE_DEFAULT_UA = JMeterUtils.getPropDefault("httpclient4.default_user_agent_disabled", false); |
197 | 191 |
|
198 | | - private static final boolean GZIP_RELAX_MODE = JMeterUtils.getPropDefault("httpclient4.gzip_relax_mode", false); |
199 | | - |
200 | | - private static final boolean DEFLATE_RELAX_MODE = JMeterUtils.getPropDefault("httpclient4.deflate_relax_mode", false); |
201 | | - |
202 | 192 | private static final Logger log = LoggerFactory.getLogger(HTTPHC4Impl.class); |
203 | 193 |
|
204 | | - private static final InputStreamFactory GZIP = |
205 | | - instream -> new LaxGZIPInputStream(instream, GZIP_RELAX_MODE); |
206 | | - |
207 | | - private static final InputStreamFactory DEFLATE = |
208 | | - instream -> new LaxDeflateInputStream(instream, DEFLATE_RELAX_MODE); |
209 | | - |
210 | | - private static final InputStreamFactory BROTLI = BrotliInputStream::new; |
211 | | - |
212 | 194 | private static final class ManagedCredentialsProvider implements CredentialsProvider { |
213 | 195 | private final AuthManager authManager; |
214 | 196 | private final Credentials proxyCredentials; |
@@ -472,55 +454,6 @@ protected HttpResponse doSendRequest( |
472 | 454 | } |
473 | 455 | }; |
474 | 456 |
|
475 | | - private static final String[] HEADERS_TO_SAVE = new String[]{ |
476 | | - "content-length", |
477 | | - "content-encoding", |
478 | | - "content-md5" |
479 | | - }; |
480 | | - |
481 | | - /** |
482 | | - * Custom implementation that backups headers related to Compressed responses |
483 | | - * that HC core {@link ResponseContentEncoding} removes after uncompressing |
484 | | - * See Bug 59401 |
485 | | - */ |
486 | | - @SuppressWarnings("UnnecessaryAnonymousClass") |
487 | | - private static final HttpResponseInterceptor RESPONSE_CONTENT_ENCODING = new ResponseContentEncoding(createLookupRegistry()) { |
488 | | - @Override |
489 | | - public void process(HttpResponse response, HttpContext context) |
490 | | - throws HttpException, IOException { |
491 | | - ArrayList<Header[]> headersToSave = null; |
492 | | - |
493 | | - final HttpEntity entity = response.getEntity(); |
494 | | - final HttpClientContext clientContext = HttpClientContext.adapt(context); |
495 | | - final RequestConfig requestConfig = clientContext.getRequestConfig(); |
496 | | - // store the headers if necessary |
497 | | - if (requestConfig.isContentCompressionEnabled() && entity != null && entity.getContentLength() != 0) { |
498 | | - final Header ceheader = entity.getContentEncoding(); |
499 | | - if (ceheader != null) { |
500 | | - headersToSave = new ArrayList<>(3); |
501 | | - for(String name : HEADERS_TO_SAVE) { |
502 | | - Header[] hdr = response.getHeaders(name); // empty if none |
503 | | - headersToSave.add(hdr); |
504 | | - } |
505 | | - } |
506 | | - } |
507 | | - |
508 | | - // Now invoke original parent code |
509 | | - super.process(response, clientContext); |
510 | | - // Should this be in a finally ? |
511 | | - if(headersToSave != null) { |
512 | | - for (Header[] headers : headersToSave) { |
513 | | - for (Header headerToRestore : headers) { |
514 | | - if (response.containsHeader(headerToRestore.getName())) { |
515 | | - break; |
516 | | - } |
517 | | - response.addHeader(headerToRestore); |
518 | | - } |
519 | | - } |
520 | | - } |
521 | | - } |
522 | | - }; |
523 | | - |
524 | 457 | /** |
525 | 458 | * 1 HttpClient instance per combination of (HttpClient,HttpClientKey) |
526 | 459 | */ |
@@ -558,19 +491,6 @@ protected HTTPHC4Impl(HTTPSamplerBase testElement) { |
558 | 491 | super(testElement); |
559 | 492 | } |
560 | 493 |
|
561 | | - /** |
562 | | - * Customize to plug Brotli |
563 | | - * @return {@link Lookup} |
564 | | - */ |
565 | | - private static Lookup<InputStreamFactory> createLookupRegistry() { |
566 | | - return |
567 | | - RegistryBuilder.<InputStreamFactory>create() |
568 | | - .register("br", BROTLI) |
569 | | - .register("gzip", GZIP) |
570 | | - .register("x-gzip", GZIP) |
571 | | - .register("deflate", DEFLATE).build(); |
572 | | - } |
573 | | - |
574 | 494 | /** |
575 | 495 | * Implementation that allows GET method to have a body |
576 | 496 | */ |
@@ -675,7 +595,12 @@ protected HTTPSampleResult sample(URL url, String method, |
675 | 595 | } |
676 | 596 | HttpEntity entity = httpResponse.getEntity(); |
677 | 597 | if (entity != null) { |
678 | | - res.setResponseData(readResponse(res, entity.getContent(), entity.getContentLength())); |
| 598 | + Header contentEncodingHeader = entity.getContentEncoding(); |
| 599 | + if (contentEncodingHeader != null) { |
| 600 | + res.setResponseData(EntityUtils.toByteArray(entity), contentEncodingHeader.getValue()); |
| 601 | + } else { |
| 602 | + res.setResponseData(EntityUtils.toByteArray(entity)); |
| 603 | + } |
679 | 604 | } |
680 | 605 |
|
681 | 606 | res.sampleEnd(); // Done with the sampling proper. |
@@ -1157,7 +1082,7 @@ private MutableTriple<CloseableHttpClient, AuthState, PoolingHttpClientConnectio |
1157 | 1082 | } |
1158 | 1083 | builder.setDefaultCredentialsProvider(credsProvider); |
1159 | 1084 | } |
1160 | | - builder.disableContentCompression().addInterceptorLast(RESPONSE_CONTENT_ENCODING); |
| 1085 | + builder.disableContentCompression(); // Disable automatic decompression |
1161 | 1086 | if(BASIC_AUTH_PREEMPTIVE) { |
1162 | 1087 | builder.addInterceptorFirst(PREEMPTIVE_AUTH_INTERCEPTOR); |
1163 | 1088 | } else { |
|
0 commit comments