Properly aborting HTTP request/response exchange on error

224 views
Skip to first unread message

Francois Delisle

unread,
Feb 15, 2017, 12:49:11 PM2/15/17
to vert.x
Let's say you are currently consuming a HttpClientResponse as a ReadStream, transferring the incoming data to a HttpServerResponse using a Pump to have flow control.

Assume an error occurs while writing to the HttpServerResponse. It could be that it raised an exception (invoking its registered exceptionHandler) or the connection was closed prematurely (invoking its registered closeHandler). At this point, we can stop the pump, which sets a null handler in the HttpClientResponse. We can also pause the response, making sure it stops producing data. But how can we let the server knows (server from which we receive the data through the HttpClientResponse), that it should stop producing data since it won't be consumed anyways. In a way, we want to abort the "request/response" exchange without necessarily closing the underlying http connection since we are taking advantage of keep-alive and therefore the connection might be reused for other requests.

Perhaps in this case, which we could consider a edge case, it is acceptable to close the connection. However, I'm not convinced that calling response.netSocket().close() is safe as it might not release the connection from the connection pool. Is it the actual recommended way to handle this situation? Is there a better alternative?

Thanks for advising.



Francois Delisle

unread,
Feb 23, 2017, 5:07:12 PM2/23/17
to vert.x
httpClientRequest.connection().close();

Connection will not be immediately evicted from the HttpClient's connection pool. However, the connection manager detects closed connections and do not return them to the pool when trying to reuse them.

Julien Viet

unread,
Feb 23, 2017, 6:47:06 PM2/23/17
to ve...@googlegroups.com
yes, this is true for HTTP/1

however for HTTP/2 you want instead to reset the stream with the reset() method of HttpClientRequest and not close the connection otherwise you would terminate potentially many http requests/responses.

that being said, HttpClientRequest has a best effort implementation for HTTP/1 : it closes the connection after the current in-flight requests are ended.

so my advice would be try to use the HttpClientRequest#reset() method instead it has been implemented for HTTP/1 as a best effort (for instance if you reset a pipelined request, it waits that the current previous responses are processed before closing the connection, and if the requests has been scheduled but not sent, it will simply not send the request).

Julien

ps: it has been done to ease the implementation of HTTP proxies and this is an contrib/experiment I’m doing on my spare time : https://github.com/vietj/vertx-http-proxy 

On Feb 23, 2017, at 11:07 PM, Francois Delisle <francois...@gmail.com> wrote:

httpClientRequest.connection().close();

Connection will not be immediately evicted from the HttpClient's connection pool. However, the connection manager detects closed connections and do not return them to the pool when trying to reuse them.


--
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
Visit this group at https://groups.google.com/group/vertx.
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/1c26d1bf-3ee8-4fef-86f5-5d3c2bf25595%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Francois Delisle

unread,
Feb 24, 2017, 12:54:25 PM2/24/17
to vert.x
Thanks Julien.

We first wanted to reset the connection as you indicated, but on 3.3.3 it is not yet implemented for HTTP 1.x:

In class ClientConnection.... 

  public void reset(long code) {
    throw new UnsupportedOperationException("HTTP/1.x request cannot be reset");
  }


Will connection().close() for now and leave a note to switch to .reset() once it is available for HTTP 1.x.

Julien Viet

unread,
Feb 24, 2017, 1:50:05 PM2/24/17
to ve...@googlegroups.com
yes it is for 3.4.0

Reply all
Reply to author
Forward
0 new messages