Am 2020-05-27 um 12:14 schrieb Oleg Kalnichevski:
On Wed, 2020-05-27 at 00:01 +0200, Michael Osipov wrote:
Am 2020-05-26 um 23:09 schrieb Oleg Kalnichevski:
On Tue, 2020-05-26 at 22:28 +0200, Michael Osipov wrote:
Am 2020-05-26 um 20:20 schrieb Oleg Kalnichevski:
On Tue, 2020-05-26 at 17:58 +0000, Bernd Eckenfels wrote:
Michael, this looks a bit like the packets in between have
been
TLS
handshakes which have not been carried out because the engine
was
not
kicked off. Maybe a starHandshake() would help? Or can you
share
the
full traces? Did you try http as well?


Michael,

I can only second what Bernd has said. Try to simplify the
setup
and
see if you can get things to work with plain HTTP first.

Also feel free to tweak my code as you see fit.

I followed Bernd's advise and disabled TLS. Although I already
had a
clue what is going wrong. Attached is a patch on top of Oleg's
branch
which makes it work unencrypted and encrypted. I will explain in
detail
why the changes are necessary.

-    public static final Timeout
DEFAULT_WAIT_FOR_EARLY_RESPONSE =
Timeout.ofMilliseconds(5);
+    public static final Timeout
DEFAULT_WAIT_FOR_EARLY_RESPONSE =
Timeout.ofMilliseconds(50);

unless client and server are physically next to each other 5 ms
are
virtually impossible. I have tried with our server at work. I am
connected with my laptop via VPN to the corporate network, I
don't
know
where the peering point of our VPN provider is, but the server is
physically 10 km away from me and with TLS 1.3 it takes 28 ms to
produce
the 401.

Maybe both timeouts (expect and early) should be configurable via
RequestConfig?

+            conn.flush();

Michael

You are absolutely right. Not flushing the request head was the
cause
of the problem.

Could you please try out a slightly different take on your original
patch, though?


https://github.com/ok2c/httpcomponents-core/commit/39f6d69a87586c147dc080431d45d6d48acb2c80

HttpRequestExecutor ought not be flushing all request message heads
indiscriminately and should still try to pack small payload
messages
into a single IP frame for performance reasons.

Makes sense!

I also would not overload RequestConfig with too many options but
we
can discuss that later.

Agreed.

This is why it did not work before is that headers were stuck in
the
local buffer and were flushed only when the body was sent. So the
server
never saw the headers before the body. The wait was pointless.

Please also note that even the buffer for headers might be large
due
to
some authnz tokens. E.g., JWT or SPNEGO, cookies, etc.

+                        response =
conn.receiveResponseHeader();

One needs to read the headers because the client shall be able to
see
the status code and if fast enough the response body. In my case
the
error page from Tomcat.

RFC 7230, section 6.5 says:
     A client sending a message body SHOULD monitor the network
connection
     for an error response while it is transmitting the
request.  If
the
     client sees a response that indicates the server does not
wish
to
     receive the message body and is closing the connection, the
client
     SHOULD immediately cease transmitting the body and close
its
side of
     the connection.

I have issued another request and HttpClient reuses the
connection
because Tomcat forgot to send "Connection: close".

Hmm. That sounds weird. HttpClient must terminate the connection if
it
failed to submit the entire message body declared in `Content-
Length`
header. The #terminateRequest should have marked the connection as
`inconsistent`.

Could you please send me a wire log of the session?

So far, the patch works and I can access the first 401 response.


This should fix the problem with incorrect connection re-use. Please
review:

https://github.com/apache/httpcomponents-client/commit/a554aadabafe26ae5412b26a311ffa105e623cc2

Tried with various timeouts, 5 ms, 15 ms, 25 ms, 50 ms, 500 ms.
Connections are correctly closed when:
* early response is received
* early response did not arrive in time and the server reached its swallow limit (worked already)

I ran multiple requests in a loop as well as a subsequent one with authentication header.

I am happily accepting this patch!

---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscr...@hc.apache.org
For additional commands, e-mail: httpclient-users-h...@hc.apache.org

Reply via email to