[httpclient] HTTP2: Memory Leak with Proxy

Chris Hegarty chris.hegarty at oracle.com
Tue Aug 7 16:05:43 UTC 2018


> On 7 Aug 2018, at 16:55, Albert Schimpf <albi646 at gmx.de> wrote:
> 
> Hi,
> 
> by bad I mean that this proxy is the only one out of ~1000 proxies which causes this behavior. It's also the only one which causes SSLExceptions (General SSL engine problem) and EOFExceptions. I don't think that particular proxy is a valid proxy. Using curl indicates that this is a SSL handshake problem (https):
> 
> * Rebuilt URL to: www.google.de/
> *   Trying 165.165.248.90…

Oh, you mean the proxy at that actual IP address. Ok got it.


> * TCP_NODELAY set
> * Connected to 165.165.248.90 (165.165.248.90) port 8080 (#0)
> * successfully set certificate verify locations:
> *   CAfile: /etc/ssl/certs/ca-certificates.crt
>   CApath: /etc/ssl/certs
> * TLSv1.2 (OUT), TLS handshake, Client hello (1):
> * OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to 165.165.248.90:8080
> * Closing connection 0
> curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to 165.165.248.90:8080
> 
> I don't know that much about the protocol itself,  so I don't think I can help very much.
> 
> Thank you for looking into this!


-Chris.


> Best,
> Albert
> 
> 
> On 07.08.2018 12:05, Chris Hegarty wrote:
>> Hi Albert,
>> 
>> Very strange indeed. Thanks for reporting it, I’ll investigate.
>> 
>> What do your mean by “bad proxy”. What is bad about it, and how does it behave?
>> 
>> -Chris.
>> 
>> 
>>> On 7 Aug 2018, at 10:25, Albert Schimpf <albi646 at gmx.de> wrote:
>>> 
>>> Hi,
>>> 
>>> I stumbled upon some strange behavior when using the new Java httpclient.
>>> 
>>> The issue is very simple to reproduce. Send a GET request via a known bad proxy:
>>> 
>>> HttpClient client = HttpClient.newBuilder()
>>>                     .proxy(ProxySelector.of(BAD_PROXY))
>>>                     .build();
>>> 
>>> HttpRequest req = HttpRequest
>>>                     // target is not relevant
>>>                     .newBuilder(...)
>>>                     .GET()
>>>                     .build();
>>> 
>>> // body handler is not relevant
>>> HttpResponse.BodyHandler<?> t = HttpResponse.BodyHandler.asString();
>>> 
>>> // happens with both async and sync send
>>> client.sendAsync(req, t).get(30, TimeUnit.SECONDS);
>>> 
>>> The result is that the heap size increases dramatically (to about 1.5GB) and resources are not released. CPU consumption increases by a constant factor, too. I have tried many variations of the above code, and the only thing which seems to work (i.e. heap size does not explode) is to set the HTTP version to 1.1.
>>> 
>>> In my main application this leads to both memory and CPU starvation (4GB memory limit, 100% CPU usage). It usually uses only 5% CPU and 200MB memory at worst.
>>> 
>>> I have attached a working example code with a bad proxy. I uploaded the generated garbage collection log and three heap dumps (before, during, and after the request) to dropbox:
>>> 
>>> https://www.dropbox.com/s/ulqnmrmgr58rrul/debug.zip
>>> 
>>> I tried the 10.0.0-openjdk and 10.0.1-zulu version. I can reproduce the issue 100% of times.
>>> 
>>> Am I doing something wrong? Is this to be expected if one somehow happens to use a bad proxy? If this is to be expected, how can I protect my application against such behavior?
>>> 
>>> 
>>> Best,
>>> Albert
>>> <mon.png><Main.java>
> 



More information about the net-dev mailing list