Great you have a simple reproducer. On my side , looking inti HC4 I notice issue triggers when we enter proxy tunnel mode
http://httpcomponents.10934.n7.nabble.com/Strange-behaviour-when-using-Proxy-td34776.html did you submit a bug or not yet ? Thanks On Saturday, December 15, 2018, Felix Schumacher < felix.schumac...@internetallee.de> wrote: > > Am 14.12.18 um 17:37 schrieb Philippe Mouawad: > >> Hi Felix, >> Thanks for investigations ! >> Is it an issue due to our code or a bug in hc4? >> > > It looks like a bug in hc4 to me (or we haven't understood that feature :) > > If you change your test code to use https for the request, you will get > the same behaviour that we see in our bug report. > > @Test > public void checkThatHeadersAreNotHidden() throws Exception { > TrustStrategy trustStrategy = new TrustAllStrategy(); > SSLContext sslContext = new SSLContextBuilder() > .loadTrustMaterial(null, trustStrategy).build(); > SSLConnectionSocketFactory socketFactory = new > SSLConnectionSocketFactory( > sslContext); > CloseableHttpClient httpclient = HttpClients.custom() > .setSSLSocketFactory(socketFactory).build(); > try { > > HttpHost target = new HttpHost("jmeter.apache.org", 443, > "https"); > HttpHost proxy = new HttpHost("localhost", 8888, "http"); > > RequestConfig config = RequestConfig.custom().setProxy(proxy) > .build(); > HttpGet request = new HttpGet("/"); > request.addHeader("X-sleep", "5"); > request.setConfig(config); > > HttpContext localContext = new BasicHttpContext(); > CloseableHttpResponse response = httpclient.execute(target, > request, > localContext); > final HttpRequest httpRequestFromLocalContext = (HttpRequest) > localContext > .getAttribute(HttpCoreContext.HTTP_REQUEST); > try { > Assert.assertThat(httpRequestFromLocalContext.getRequestLine() > .getMethod(), CoreMatchers.is("CONNECT")); > Assert.assertThat(response.getStatusLine().getStatusCode(), > CoreMatchers.is(200)); > Assert.assertThat( > Arrays.asList(request.getAllHeaders()).toString(), > CoreMatchers.containsString("X-sleep")); > Assert.assertThat( > Arrays.asList( > httpRequestFromLocalContext.getAllHeaders()) > .toString(), > CoreMatchers > .not(CoreMatchers.containsString("X-sleep"))); > } finally { > response.close(); > } > } finally { > httpclient.close(); > } > } > > I have add a trust all ssl context and changed the class to be a JUnit > test case. > > Regards, > > Felix > > > ps: didn’t look deeply yet qt your findings >> >> Regards >> >> On Friday, December 14, 2018, Felix Schumacher < >> felix.schumac...@internetallee.de> wrote: >> >> Am 14.12.18 um 13:17 schrieb Felix Schumacher: >>> >>> Am 13.12.18 um 23:28 schrieb Philippe Mouawad: >>>> >>>> Hello, >>>>> >>>>> We have a confirmed bug report : >>>>> >>>>> - https://bz.apache.org/bugzilla/show_bug.cgi?id=62852 >>>>> >>>>> It appears that when using proxy for a request, the method >>>>> request.getRequestHeaders() called on the request returned >>>>> HttpContext#getAttribute(HttpCoreContext.HTTP_REQUEST) returns only >>>>> part of >>>>> the headers. >>>>> >>>>> While it returns them all if not using proxy. >>>>> >>>>> The headers (context) gets changed on line 189 in >>>> org.apache.http.impl.execchain.ProtcolExec. >>>> >>>> final CloseableHttpResponse response = >>>> this.requestExecutor.execute(route, request, >>>> context, execAware); >>>> try { >>>> // Run response protocol interceptors >>>> context.setAttribute(HttpCoreContext.HTTP_RESPONSE, >>>> response); <-- Here >>>> this.httpProcessor.process(response, context); >>>> return response; >>>> } catch (final RuntimeException ex) { >>>> >>>> Will debug further. >>>> >>>> Thread [Thread Group 1-1] (Suspended) >>> org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl$5(org. >>> apache.http.protocol.HttpRequestExecutor).preProcess(org. >>> apache.http.HttpRequest, >>> org.apache.http.protocol.HttpProcessor, org.apache.http.protocol.HttpC >>> ontext) >>> line: 163 >>> org.apache.http.impl.execchain.MainClientExec.createTunnelTo >>> Target(org.apache.http.auth.AuthState, org.apache.http.HttpClientConn >>> ection, >>> org.apache.http.conn.routing.HttpRoute, org.apache.http.HttpRequest, >>> org.apache.http.client.protocol.HttpClientContext) line: 472 >>> org.apache.http.impl.execchain.MainClientExec.establishRoute >>> (org.apache.http.auth.AuthState, org.apache.http.HttpClientConnection, >>> org.apache.http.conn.routing.HttpRoute, org.apache.http.HttpRequest, >>> org.apache.http.client.protocol.HttpClientContext) line: 411 >>> org.apache.http.impl.execchain.MainClientExec.execute(org. >>> apache.http.conn.routing.HttpRoute, org.apache.http.client.methods >>> .HttpRequestWrapper, >>> org.apache.http.client.protocol.HttpClientContext, >>> org.apache.http.client.methods.HttpExecutionAware) line: 237 >>> org.apache.http.impl.execchain.ProtocolExec.execute(org. >>> apache.http.conn.routing.HttpRoute, org.apache.http.client.methods >>> .HttpRequestWrapper, >>> org.apache.http.client.protocol.HttpClientContext, >>> org.apache.http.client.methods.HttpExecutionAware) line: 185 >>> org.apache.http.impl.execchain.RetryExec.execute(org.apache. >>> http.conn.routing.HttpRoute, >>> org.apache.http.client.methods.HttpRequestWrapper, >>> org.apache.http.client.protocol.HttpClientContext, >>> org.apache.http.client.methods.HttpExecutionAware) line: 89 >>> org.apache.http.impl.execchain.RedirectExec.execute(org. >>> apache.http.conn.routing.HttpRoute, org.apache.http.client.methods >>> .HttpRequestWrapper, >>> org.apache.http.client.protocol.HttpClientContext, >>> org.apache.http.client.methods.HttpExecutionAware) line: 110 >>> org.apache.http.impl.client.InternalHttpClient.doExecute(org >>> .apache.http.HttpHost, >>> org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext) line: >>> 185 >>> org.apache.http.impl.client.InternalHttpClient(org.apache.ht >>> tp.impl.client.CloseableHttpClient).execute(org.apache.http. >>> client.methods.HttpUriRequest, >>> org.apache.http.protocol.HttpContext) line: 83 >>> org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.executeR >>> equest(org.apache.http.impl.client.CloseableHttpClient, >>> org.apache.http.client.methods.HttpRequestBase, >>> org.apache.http.protocol.HttpContext, java.net.URL) line: 840 >>> org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.sample(java.net.URL, >>> java.lang.String, boolean, int) line: 576 >>> org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy.sam >>> ple(java.net.URL, >>> java.lang.String, boolean, int) line: 67 >>> org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy(org >>> .apache.jmeter.protocol.http.sampler.HTTPSamplerBase).sample() line: >>> 1231 >>> org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy(org >>> .apache.jmeter.protocol.http.sampler.HTTPSamplerBase).sampl >>> e(org.apache.jmeter.samplers.Entry) line: 1220 >>> org.apache.jmeter.threads.JMeterThread.doSampling(org.apache >>> .jmeter.threads.JMeterContext, >>> org.apache.jmeter.samplers.Sampler) line: 622 >>> org.apache.jmeter.threads.JMeterThread.executeSamplePackage( >>> org.apache.jmeter.samplers.Sampler, org.apache.jmeter.control.Tran >>> sactionSampler, >>> org.apache.jmeter.threads.SamplePackage, org.apache.jmeter.threads.JMet >>> erContext) >>> line: 546 >>> org.apache.jmeter.threads.JMeterThread.processSampler(org. >>> apache.jmeter.samplers.Sampler, org.apache.jmeter.samplers.Sampler, >>> org.apache.jmeter.threads.JMeterContext) line: 486 >>> org.apache.jmeter.threads.JMeterThread.run() line: 253 >>> java.lang.Thread.run() line: 748 >>> >>> It seems that httpclient initiates the replacement of the "correct" >>> request. I have managed to revert that behaviour by adding a save/restore >>> functionality in our REQUEST_EXECUTOR that is implemented in >>> HTTPHC4Impl. I >>> implemented the method preProcess and saved the old request before >>> calling >>> the super method and restoring the request after the call. >>> >>> That looks quite ugly and I have no idea, if it is correct. But it works >>> for the simple test plan. >>> >>> Felix >>> >>> >>> Felix >>>> >>>> >>>> See: >>>>> >>>>> - >>>>> https://github.com/apache/jmeter/blob/trunk/src/protocol/ >>>>> http/org/apache/jmeter/protocol/http/sampler/HTTPHC4Impl.java#L580 >>>>> >>>>> >>>>> I tried to reproduce behavior with HTTPClient only but couldn't , so it >>>>> seems issue is somewhere in our code possibly due to interceptors or >>>>> request executor. >>>>> >>>>> /* >>>>> * ============================================================ >>>>> ======== >>>>> * Licensed to the Apache Software Foundation (ASF) under one >>>>> * or more contributor license agreements. See the NOTICE file >>>>> * distributed with this work for additional information >>>>> * regarding copyright ownership. The ASF licenses this file >>>>> * to you under the Apache License, Version 2.0 (the >>>>> * "License"); you may not use this file except in compliance >>>>> * with the License. You may obtain a copy of the License at >>>>> * >>>>> * http://www.apache.org/licenses/LICENSE-2.0 >>>>> * >>>>> * Unless required by applicable law or agreed to in writing, >>>>> * software distributed under the License is distributed on an >>>>> * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY >>>>> * KIND, either express or implied. See the License for the >>>>> * specific language governing permissions and limitations >>>>> * under the License. >>>>> * ============================================================ >>>>> ======== >>>>> * >>>>> * This software consists of voluntary contributions made by many >>>>> * individuals on behalf of the Apache Software Foundation. For more >>>>> * information on the Apache Software Foundation, please see >>>>> * <http://www.apache.org/>. >>>>> * >>>>> */ >>>>> >>>>> package org.apache.jmeter.protocol.http.proxy; >>>>> >>>>> import java.util.Arrays; >>>>> >>>>> import org.apache.http.HttpHost; >>>>> import org.apache.http.HttpRequest; >>>>> import org.apache.http.client.config.RequestConfig; >>>>> import org.apache.http.client.methods.CloseableHttpResponse; >>>>> import org.apache.http.client.methods.HttpGet; >>>>> import org.apache.http.impl.client.CloseableHttpClient; >>>>> import org.apache.http.impl.client.HttpClients; >>>>> import org.apache.http.protocol.BasicHttpContext; >>>>> import org.apache.http.protocol.HttpContext; >>>>> import org.apache.http.protocol.HttpCoreContext; >>>>> >>>>> /** >>>>> * How to send a request via proxy. >>>>> * >>>>> * @since 4.0 >>>>> */ >>>>> public class TestProxy { >>>>> >>>>> public static void main(String[] args)throws Exception { >>>>> CloseableHttpClient httpclient = HttpClients.createDefault(); >>>>> try { >>>>> >>>>> HttpHost target = new HttpHost("jmeter.apache.org", 80, >>>>> "http"); >>>>> HttpHost proxy = new HttpHost("localhost", 8888, "http"); >>>>> >>>>> RequestConfig config = RequestConfig.custom() >>>>> .setProxy(proxy) >>>>> .build(); >>>>> HttpGet request = new HttpGet("/"); >>>>> request.addHeader("X-sleep", "5"); >>>>> request.setConfig(config); >>>>> >>>>> System.out.println("Executing request " + >>>>> request.getRequestLine() + " to " + target + " via " + proxy); >>>>> HttpContext localContext = new BasicHttpContext(); >>>>> CloseableHttpResponse response = >>>>> httpclient.execute(target, >>>>> request, localContext); >>>>> final HttpRequest httpRequestFromLocalContext = >>>>> (HttpRequest) >>>>> localContext.getAttribute(HttpCoreContext.HTTP_REQUEST); >>>>> try { >>>>> >>>>> System.out.println("----------------------------------------"); >>>>> System.out.println(response.getStatusLine()); >>>>> System.out.println(Arrays.asList(request.getAllHeaders())); >>>>> >>>>> System.out.println(Arrays.asList(httpRequestFromLocalContext >>>>> .getAllHeaders())); >>>>> >>>>> System.out.println(Arrays.asList(response.getAllHeaders())); >>>>> >>>>> //System.out.println(EntityUtils.toString(response.getEntity())); >>>>> } finally { >>>>> response.close(); >>>>> } >>>>> } finally { >>>>> httpclient.close(); >>>>> } >>>>> } >>>>> >>>>> } >>>>> >>>>> OUTPUT: >>>>> ------------------------------------------------------------ >>>>> ---------------------------------------- >>>>> Executing request GET / HTTP/1.1 to http://jmeter.apache.org:80 via >>>>> http://localhost:8888 >>>>> ---------------------------------------- >>>>> HTTP/1.1 200 OK >>>>> [X-sleep: 5] >>>>> [X-sleep: 5, Host: jmeter.apache.org:80, Proxy-Connection: Keep-Alive, >>>>> User-Agent: Apache-HttpClient/4.5.6 (Java/1.8.0_161), Accept-Encoding: >>>>> gzip,deflate] >>>>> [Date: Thu, 13 Dec 2018 22:23:23 GMT, Server: Apache/2.4.18 (Ubuntu), >>>>> Last-Modified: Sun, 09 Sep 2018 15:25:54 GMT, ETag: >>>>> "3159-57571db50c67a-gzip", Accept-Ranges: bytes, Vary: Accept-Encoding, >>>>> Keep-Alive: timeout=30, max=100, Connection: Keep-Alive, Content-Type: >>>>> text/html, Content-Length: 12633] >>>>> ------------------------------------------------------------ >>>>> ---------------------------------------- >>>>> >>>>> >>>>> Regards >>>>> Philippe M. >>>>> <https://www.openstreetmap.org/#map=18/50.69454/3.16455> >>>>> >>>>> >>>>> -- Cordialement. Philippe Mouawad.