|
55 | 55 | import org.apache.http.HttpRequest; |
56 | 56 | import org.apache.http.HttpRequestInterceptor; |
57 | 57 | import org.apache.http.HttpResponse; |
58 | | -import org.apache.http.HttpResponseInterceptor; |
59 | 58 | import org.apache.http.NameValuePair; |
60 | 59 | import org.apache.http.StatusLine; |
61 | 60 | import org.apache.http.auth.AuthSchemeProvider; |
|
70 | 69 | import org.apache.http.client.config.AuthSchemes; |
71 | 70 | import org.apache.http.client.config.CookieSpecs; |
72 | 71 | import org.apache.http.client.config.RequestConfig; |
73 | | -import org.apache.http.client.entity.InputStreamFactory; |
74 | 72 | import org.apache.http.client.entity.UrlEncodedFormEntity; |
75 | 73 | import org.apache.http.client.methods.CloseableHttpResponse; |
76 | 74 | import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; |
|
84 | 82 | import org.apache.http.client.methods.HttpTrace; |
85 | 83 | import org.apache.http.client.methods.HttpUriRequest; |
86 | 84 | import org.apache.http.client.protocol.HttpClientContext; |
87 | | -import org.apache.http.client.protocol.ResponseContentEncoding; |
88 | 85 | import org.apache.http.config.Lookup; |
89 | 86 | import org.apache.http.config.Registry; |
90 | 87 | import org.apache.http.config.RegistryBuilder; |
|
146 | 143 | import org.apache.jmeter.protocol.http.control.DynamicKerberosSchemeFactory; |
147 | 144 | import org.apache.jmeter.protocol.http.control.DynamicSPNegoSchemeFactory; |
148 | 145 | import org.apache.jmeter.protocol.http.control.HeaderManager; |
149 | | -import org.apache.jmeter.protocol.http.sampler.hc.LaxDeflateInputStream; |
150 | | -import org.apache.jmeter.protocol.http.sampler.hc.LaxGZIPInputStream; |
151 | 146 | import org.apache.jmeter.protocol.http.sampler.hc.LazyLayeredConnectionSocketFactory; |
152 | 147 | import org.apache.jmeter.protocol.http.util.ConversionUtils; |
153 | 148 | import org.apache.jmeter.protocol.http.util.HTTPArgument; |
|
165 | 160 | import org.apache.jmeter.util.SSLManager; |
166 | 161 | import org.apache.jorphan.util.JOrphanUtils; |
167 | 162 | import org.apache.jorphan.util.StringUtilities; |
168 | | -import org.brotli.dec.BrotliInputStream; |
169 | 163 | import org.slf4j.Logger; |
170 | 164 | import org.slf4j.LoggerFactory; |
171 | 165 |
|
@@ -194,20 +188,8 @@ public class HTTPHC4Impl extends HTTPHCAbstractImpl { |
194 | 188 |
|
195 | 189 | private static final boolean DISABLE_DEFAULT_UA = JMeterUtils.getPropDefault("httpclient4.default_user_agent_disabled", false); |
196 | 190 |
|
197 | | - private static final boolean GZIP_RELAX_MODE = JMeterUtils.getPropDefault("httpclient4.gzip_relax_mode", false); |
198 | | - |
199 | | - private static final boolean DEFLATE_RELAX_MODE = JMeterUtils.getPropDefault("httpclient4.deflate_relax_mode", false); |
200 | | - |
201 | 191 | private static final Logger log = LoggerFactory.getLogger(HTTPHC4Impl.class); |
202 | 192 |
|
203 | | - private static final InputStreamFactory GZIP = |
204 | | - instream -> new LaxGZIPInputStream(instream, GZIP_RELAX_MODE); |
205 | | - |
206 | | - private static final InputStreamFactory DEFLATE = |
207 | | - instream -> new LaxDeflateInputStream(instream, DEFLATE_RELAX_MODE); |
208 | | - |
209 | | - private static final InputStreamFactory BROTLI = BrotliInputStream::new; |
210 | | - |
211 | 193 | private static final class ManagedCredentialsProvider implements CredentialsProvider { |
212 | 194 | private final AuthManager authManager; |
213 | 195 | private final Credentials proxyCredentials; |
@@ -464,55 +446,6 @@ protected HttpResponse doSendRequest( |
464 | 446 | } |
465 | 447 | }; |
466 | 448 |
|
467 | | - private static final String[] HEADERS_TO_SAVE = new String[]{ |
468 | | - "content-length", |
469 | | - "content-encoding", |
470 | | - "content-md5" |
471 | | - }; |
472 | | - |
473 | | - /** |
474 | | - * Custom implementation that backups headers related to Compressed responses |
475 | | - * that HC core {@link ResponseContentEncoding} removes after uncompressing |
476 | | - * See Bug 59401 |
477 | | - */ |
478 | | - @SuppressWarnings("UnnecessaryAnonymousClass") |
479 | | - private static final HttpResponseInterceptor RESPONSE_CONTENT_ENCODING = new ResponseContentEncoding(createLookupRegistry()) { |
480 | | - @Override |
481 | | - public void process(HttpResponse response, HttpContext context) |
482 | | - throws HttpException, IOException { |
483 | | - ArrayList<Header[]> headersToSave = null; |
484 | | - |
485 | | - final HttpEntity entity = response.getEntity(); |
486 | | - final HttpClientContext clientContext = HttpClientContext.adapt(context); |
487 | | - final RequestConfig requestConfig = clientContext.getRequestConfig(); |
488 | | - // store the headers if necessary |
489 | | - if (requestConfig.isContentCompressionEnabled() && entity != null && entity.getContentLength() != 0) { |
490 | | - final Header ceheader = entity.getContentEncoding(); |
491 | | - if (ceheader != null) { |
492 | | - headersToSave = new ArrayList<>(3); |
493 | | - for(String name : HEADERS_TO_SAVE) { |
494 | | - Header[] hdr = response.getHeaders(name); // empty if none |
495 | | - headersToSave.add(hdr); |
496 | | - } |
497 | | - } |
498 | | - } |
499 | | - |
500 | | - // Now invoke original parent code |
501 | | - super.process(response, clientContext); |
502 | | - // Should this be in a finally ? |
503 | | - if(headersToSave != null) { |
504 | | - for (Header[] headers : headersToSave) { |
505 | | - for (Header headerToRestore : headers) { |
506 | | - if (response.containsHeader(headerToRestore.getName())) { |
507 | | - break; |
508 | | - } |
509 | | - response.addHeader(headerToRestore); |
510 | | - } |
511 | | - } |
512 | | - } |
513 | | - } |
514 | | - }; |
515 | | - |
516 | 449 | /** |
517 | 450 | * 1 HttpClient instance per combination of (HttpClient,HttpClientKey) |
518 | 451 | */ |
@@ -549,19 +482,6 @@ protected HTTPHC4Impl(HTTPSamplerBase testElement) { |
549 | 482 | super(testElement); |
550 | 483 | } |
551 | 484 |
|
552 | | - /** |
553 | | - * Customize to plug Brotli |
554 | | - * @return {@link Lookup} |
555 | | - */ |
556 | | - private static Lookup<InputStreamFactory> createLookupRegistry() { |
557 | | - return |
558 | | - RegistryBuilder.<InputStreamFactory>create() |
559 | | - .register("br", BROTLI) |
560 | | - .register("gzip", GZIP) |
561 | | - .register("x-gzip", GZIP) |
562 | | - .register("deflate", DEFLATE).build(); |
563 | | - } |
564 | | - |
565 | 485 | /** |
566 | 486 | * Implementation that allows GET method to have a body |
567 | 487 | */ |
@@ -666,7 +586,12 @@ protected HTTPSampleResult sample(URL url, String method, |
666 | 586 | } |
667 | 587 | HttpEntity entity = httpResponse.getEntity(); |
668 | 588 | if (entity != null) { |
669 | | - res.setResponseData(readResponse(res, entity.getContent(), entity.getContentLength())); |
| 589 | + Header contentEncodingHeader = entity.getContentEncoding(); |
| 590 | + if (contentEncodingHeader != null) { |
| 591 | + res.setResponseData(EntityUtils.toByteArray(entity), contentEncodingHeader.getValue()); |
| 592 | + } else { |
| 593 | + res.setResponseData(EntityUtils.toByteArray(entity)); |
| 594 | + } |
670 | 595 | } |
671 | 596 |
|
672 | 597 | res.sampleEnd(); // Done with the sampling proper. |
@@ -1147,7 +1072,7 @@ private HttpClientState setupClient(HttpClientKey key, JMeterVariables jMeterVar |
1147 | 1072 | } |
1148 | 1073 | builder.setDefaultCredentialsProvider(credsProvider); |
1149 | 1074 | } |
1150 | | - builder.disableContentCompression().addInterceptorLast(RESPONSE_CONTENT_ENCODING); |
| 1075 | + builder.disableContentCompression(); // Disable automatic decompression |
1151 | 1076 | if(BASIC_AUTH_PREEMPTIVE) { |
1152 | 1077 | builder.addInterceptorFirst(PREEMPTIVE_AUTH_INTERCEPTOR); |
1153 | 1078 | } else { |
|
0 commit comments