This is important in tests that check that streams have been removed from sessions after counting down a latch in the notification.
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
Fixed initial session recv window update: it was wrong if the initial value was less than the default value (65535).
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
Fixed logic in onShutdown(): in case of abort the closing action must be
run as callback, so it executes at the end of all the other callbacks.
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
Reimplemented close/idle_timeout/stop/onGoAway/input_shutdown following more closely the specification.
In particular, the semantic of sending a GOAWAY is now to:
* stop creation of new both local and remote streams
* record the last processed stream
* continue processing streams that are pending
This means that a GOAWAY is "graceful" in the sense that it allows for streams to be completed by applications.
The semantic of stop() and idle timeout is harsher: for pending streams a RST_STREAM is sent to the other peer and they are failed locally.
Added support for GOAWAY with 2^31-1 lastStreamId.
Added support for a peer to send and receive multiple GOAWAY frames.
Reviewed the stream creation/destruction mechanism so that when the last stream completes after a GOAWAY, proper actions can be run to tear down the connection.
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
Make EOF and errors be special content.
Transition to a much simplified FSM by using the needContent() / produceContent() model.
Implement blocking on top of async, this way there is only one FSM.
(Milestone 6)
Signed-off-by: Ludovic Orban <lorban@bitronix.be>
* use our fork of h2spec-maven-plugin and upgrade version
Signed-off-by: olivier lamy <oliver.lamy@gmail.com>
* add a profile to run spec server
Signed-off-by: olivier lamy <oliver.lamy@gmail.com>
* use h2spec plugin new version
Signed-off-by: olivier lamy <oliver.lamy@gmail.com>
* version h2spec 1.0.0
Signed-off-by: olivier lamy <oliver.lamy@gmail.com>
* exclude specs we know not working
Signed-off-by: olivier lamy <oliver.lamy@gmail.com>
* use our own package name
Signed-off-by: olivier lamy <oliver.lamy@gmail.com>
* test no exclusion
Signed-off-by: olivier lamy <oliver.lamy@gmail.com>
* restore known failure
Signed-off-by: olivier lamy <oliver.lamy@gmail.com>
* h2spec maven plugin version 1.0.0
Signed-off-by: olivier lamy <oliver.lamy@gmail.com>
* change default port for manual testing
Signed-off-by: olivier lamy <oliver.lamy@gmail.com>
* Fixes#3766 - Introduce HTTP/2 API to batch frames.
Introduced Stream.FrameList to hold HEADERS+DATA+HEADERS frames.
These are often used by the client and by the server when the
request/response content is known and FrameList will allow to
send them in a single TCP write, rather than multiple ones.
Rewritten HttpSenderOverHTTP2.sendHeaders() and
HttpTransportOverHTTP2.sendHeaders() to take advantage of
FrameList.
Now using ConcurrentHashMap as a client context, because
with DEBUG logging enabled it may be access concurrently.
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
Fixed by removing the explicit version copy.
Leaving it at default would make the client transport
decide the version based on the transport protocol it uses.
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
Reworked HTTP/2 release after an exchange is terminated.
Previously, the release was bound to 2 events: onStreamClosed(),
introduced for #2796, and exchangeTerminated().
Unfortunately, if the former happens before the latter and
closes the connection, the latter will see the exchange as
aborted, while in fact it was successful, causing what
reported in #5147, an AsynchronousCloseException.
Now, the release is always performed by the exchangeTerminated()
event. With respect to #2796, the stream is always already
closed by the time the exchangeTerminated() event fires (it
was not before).
Reworked the implementation of RoundRobinConnectionPool using
a lock and aggressively trying to open new connections.
A second fix is related to HttpDestination.release(Connection).
If the connection is closed for e.g. overuse, we need to trigger
the processing of queued requests via send(create: true).
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
* Replaced relevant usages of synchronized with AutoLock.
* Made AutoLock serializable since classes that use it may be stored in the HttpSession.
* Added convenience methods to AutoLock to execute lambdas with the lock held.
* Introduced AutoLock.WithCondition to use a Lock and a Condition together.
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
Fixed MaxConcurrentStreamsTest - it was always broken.
The problem was that the call to super.onSettings(...) was done
_after_ sending the request, so the connection pool was still
configured with the default maxMultiplex=1024.
Also fixed AbstractConnectionPool to avoid a second call to
activate() if we are not trying to create a new connection.
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
Fixed test failure after merge.
Made sure the lastStreamId is updated when resetting a new
stream since it has been seen by the server and handled.
This avoids that a new stream arriving during shutdown is
interpreted as a connection failure, therefore failing all
pending streams - we want them to complete.
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
Fixes#4971 - Simplify Connection.upgradeFrom()/upgradeTo().
Now the upgrade-from connection produces a "floating" buffer
(not belonging to a pool), so that it can release the original buffer.
The upgrade-to connection is free to copy or store this "floating" buffer.
Strengthened ByteBufferPool behavior when releasing non-pooled
ByteBuffers: the buffer is now discarded.
Updated javadocs and all implementations.
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
Fixes#4967 - Possible buffer corruption in HTTP/2 session failures
Partially reverted the changes introduced in #4855, because they
were working only when sends were synchronous.
Introduced ByteBufferPool.remove(ByteBuffer) to fix the issue.
Now when a concurrent failure happens while frames are being
generated or sent, the buffer is discarded instead of being
recycled, therefore resolving the buffer corruption.
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
* Issue #4965 - WINDOW_UPDATE for locally failed stream should not close the HTTP/2 session.
Improved HTTP2Session.onWindowUpdate() code to correctly check whether
the stream is already closed, and if so, just drop the WINDOW_UPDATE.
Refactored onResetForUnknownStream() to base class.
Other small refactorings to improve logging.
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
* Fixes#4855 - Occasional h2spec failures on CI
In case of bad usage of the HTTP/2 API, we don't want to close()
the stream but just fail the callback, because the stream
may be performing actions triggered by a legit API usage.
In case of a call to `AsyncListener.onError()`, applications may decide to call
AsyncContext.complete() and that would be a correct usage of the Servlet API.
This case was not well handled and was wrongly producing a WARN log with an
`IllegalStateException`.
Completely rewritten `HttpTransportOverHTTP2.TransportCallback`.
The rewrite handles correctly asynchronous failures that now are executed
sequentially (and not concurrently) with writes.
If a write is in progress, the failure will just change the state and at the
end of the write a check on the state will determine what actions to take.
A session failure is now handled in HTTP2Session by first failing all the
streams - which notifies the Stream.Listeners - and then failing the session
- which notifies the Session.Listener.
The stream failures are executed concurrently by dispatching each one to a
different thread; this means that the stream failure callbacks are executed
concurrently (likely sending RST_STREAM frames).
The session failure callback is completed only when all the stream failure
callbacks have completed, to ensure that a GOAWAY frame is processed after
all the RST_STREAM frames.
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
* Fixes#4904 - WebsocketClient creates more connections than needed.
Fixed connection pool's `acquire()` methods to correctly take into account the number of queued requests.
Now the connection creation is conditional, triggered by
explicit send() or failures.
The connection creation is not triggered _after_ a send(),
where we aggressively send more queued requests - or
in release(), where we send queued request after a previous
one was completed.
Now the connection close/removal aggressively sends more
requests triggering the connection creation.
Also fixed a collateral bug in `BufferingResponseListener` - wrong calculation of the max content length.
Restored `ConnectionPoolTest` that was disabled in #2540, cleaned it up, and let it run for hours without failures.
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>