Commit Graph

6473 Commits

Author SHA1 Message Date
Scott Mitchell
83ce8a9187 HTTP/2 Prevent modification of activeStreams while iterating
Motivation:
The Http2Connection interface exposes an activeStreams() method which allows direct iteration over the underlying collection. There are a few places that make copies of this collection to avoid modification while iterating, and a few places that do not make copies. The copy operation can be expensive on hot code paths and also we are not consistently iterating over the activeStreams collection.

Modifications:
- The Http2Connection interface should reduce the exposure of the underlying collection and just expose what is necessary for the interface to function.  This is just a means to iterate over the collection.
- The DefaultHttp2Connection should use this new interface and protect it's internal state while iteration is occurring.

Result:
Reduction in surface area of the Http2Connection interface.  Consistent iteration of the set of active streams.  Concurrent modification exceptions are handled in 1 encapsulated spot.
2015-04-07 20:55:48 -07:00
Jakob Buchgraber
d5d932a739 Fix GOAWAY logic in Http2Encoder and Http2Decoder.
Motivation:

1) The current implementation doesn't allow for HEADERS, DATA, PING, PRIORITY and SETTINGS
   frames to be sent after GOAWAY.

2) When receiving or sending a GOAWAY frame, all streams with ids greater than the lastStreamId
   of the GOAWAY frame should be closed. That's not happening.

Modifications:

1) Allow sending of HEADERS and DATA frames after GOAWAY for streams with ids < lastStreamId.
2) Always allow sending PING, PRIORITY AND SETTINGS frames.
3) Allow sending multiple GOAWAY frames with decreasing lastStreamIds.
4) After receiving or sending a GOAWAY frame, close all streams with ids > lastStreamId.

Result:

The GOAWAY handling is more correct.
2015-04-07 20:32:28 -07:00
Scott Mitchell
3ae343b768 HTTP/2 DefaultHttp2Connection recursive call fix
Motivation:
There are methods to manipulate the prioritzable count for streams which have the '0' postfix which are designed to be used during recursion.  However these methods are calling out to an external method without the '0' during the recursive process.  This is doing uneccessary conditional checks during recursion.

Modifications:
Change the decrementPrioritizableForTree to decrementPrioritizableForTree0 while in recursive method.
Change the incrementPrioritizableForTree to incrementPrioritizableForTree0 while in recursive method.

Result:
Less overhead during recursive calls.
2015-04-06 17:12:41 -07:00
Scott Mitchell
86edc88448 HTTP/2 LifecycleManager and Http2ConnectionHandler interface clarifications
Motiviation:
The interface provided by Http2LifecycleManager is not clear as to how the writeXXX methods should behave.  The implementation of this interface from the Http2ConnectionHandler's perspecitve is unclear what writeXXX means in this context.

Modifications:
- Method names in Http2LifecycleManager and Http2ConnectionHandler should be renamed and comments should clarify the interfaces.

Results:
Http2LifecycleManager is more clear and Http2ConnectionHandler's implementation makes sense w.r.t to return values.
2015-04-06 14:34:20 -07:00
Frederic Bregier
190cbf55e4 Fix incorrect null value check in TrafficCounter
In TrafficCounter, a recent change makes the contract of the API (the
constructor) wrong and lead to issue with GlobalChannelTrafficCounter
where executor must be null.

Motivation:
TrafficCounter executor argument in constructor might be null, as
explained in the API, for some particular cases where no executor are
needed (relevant tasks being taken by the caller as in
GlobalChannelTrafficCounter).
A null pointer exception is raised while it should not since it is
legal.

Modifications:
Remove the 2 null checking for this particular attribute.
Note that when null, the attribute is not reached nor used (a null
checking condition later on is applied).

Result:
No more null exception raized while it should not.

This shall be made also to 4.0, 4.1 (present) and master. 3.10 is not
concerned.
2015-04-06 18:27:56 +02:00
Scott Mitchell
609e065fcf HTTP/2 Headers Code Using String instead of AsciiString
Motivation:
The HTTP/2 headers code should be using binary string (currently AsciiString) objects instead of String objects. The DefaultHttp2HeadersEncoder was still using String for sensitiveHeaders.

Modifications:
- Remove the usage of String from DefaultHttp2HeadersEncoder.
- Introduce an interface to determine if a header name/value is sensitive or not to 1. prevent necessarily creating/copying sets. 2. Allow the name/value to be considered when checking if sensitive.

Result:
No more String in DefaultHttp2HeadersEncoder and less required set creation/operations.
2015-04-03 15:55:44 -07:00
Scott Mitchell
9517edd498 HTTP/2 RST_STREAM in IDLE
Motivation:
The spec requires that a RST_STREAM received on an IDLE stream results in a connection error. This is not happening.

Modifications:
Check for this condition when a RST_STREAM is received in DefaultHttp2ConnectionDecoder.

Result:
More spec compliant.  Fixes https://github.com/netty/netty/issues/3573.
2015-04-03 15:53:32 -07:00
Scott Mitchell
e5d01c4caf HTTP/2 HEADERS stream dependency fix
Motivation:
The DefaultHttp2ConnectionDecoder has the setPriority call after the Http2FrameListener is notified of the change. The setPriority call has additional verification logic and may even create the dependency stream and so it must be before the Http2FrameListener is notified.

Modifications:
The DefaultHttp2ConnectionDecoder should treat the setPriority call in the same for the HEADERS and PRIORITY frame (call it before notifying the listener).

Result:
Http2FrameListener should see correct state when a HEADERS frame has a stream dependency that has not yet been created yet.  Fixes https://github.com/netty/netty/issues/3572.
2015-04-03 15:50:30 -07:00
Jakob Buchgraber
e40c27d9ed Avoid object allocations for HTTP2 child streams.
Motivation:

We are allocating a hash map for every HTTP2 Stream to store it's children.
Most streams are leafs in the priority tree and don't have children.

Modification:

 - Only allocate children when we actually use them.
 - Make EmptyIntObjectMap not throw a UnsupportedOperationException on remove, but return null instead (as is stated in it's javadoc).

Result:

Fewer unnecessary allocations.
2015-04-03 11:57:31 -07:00
Scott Mitchell
330bc39d91 Backporting PrimitiveCollections class
Motivation:
PrimitiveCollections is not in the 4.1 branch.  It is needed by HTTP/2.

Modifications:
Backport this class.

Result:
PrimitiveCollections is in 4.1.
2015-04-03 11:57:09 -07:00
Jakob Buchgraber
35b9aa9302 Replace LinkedHashSet by ArrayList to avoid iterators.
Motivation:

In a simple load test that creates and closes several 10k streams per second
I have seen Iterator objects using roughly 1.6% of the total committed heap.

Modifications:

Use an ArrayList instead of a LinkedHashSet to store the connection listeners.
That way we can iterate over the list without creating an iterator every time.

Result:

Zero Iterator allocations due to notifying connection listeners.
2015-04-03 20:13:53 +02:00
nmittler
ef729e7021 Allow non-standard HTTP/2 settings
Motivation:

The Http2Settings class currently disallows setting non-standard settings, which violates the spec.

Modifications:

Updated Http2Settings to permit arbitrary settings. Also adjusting the default initial capacity to allow setting all of the standard settings without reallocation.

Result:

Fixes #3560
2015-04-02 11:10:47 -07:00
Trustin Lee
2e509f7bb7 Fix unbounded expansion of cumulative buffer in SslHandler
Related: #3567

Motivation:

SslHandler.channelReadComplete() forgets to call
super.channelReadComplete(), which discards read bytes from the
cumulative buffer.  As a result, the cumulative buffer can expand its
capacity unboundedly.

Modifications:

Call super.channelReadComplete() instead of calling
ctx.fireChannelReadComplete()

Result:

Fixes #3567
2015-04-02 14:54:29 +09:00
Scott Mitchell
7f2ddb2162 HTTP/2 Closed Streams Conditional Priority Tree Removal
Motivation:
The HTTP/2 specification allows for closed (and streams in any state) to exist in the priority tree. The current code removes streams from the priority tree as soon as they are closed (subject to the removal policy). This may lead to undesired distribution of resources from the peer's perspective.

Modifications:
- We should only remove streams from the priority tree when they have no descendant streams in a viable state.
- We should track when tree edges change or nodes are removed if inviable nodes can then be removed.

Result:
Priority tree doesn't remove closed streams until descendant are all closed, or there are no descendants.
2015-03-31 16:24:25 -07:00
nmittler
ba9f214303 Removing unnecessary use of Math.ceil in HTTP/2 priority algorithm.
Motivation:

We're currently using Math.ceil which isn't necessary. We should exchange for a lighter weight operation.

Modifications:

Changing the logic to just ensure that we allocate at least one byte to the child rather than always performing a ceil.

Result:

Slight performance improvement in the priority algorithm.
2015-03-31 11:03:16 -07:00
nmittler
9737cc6cc9 Include error code and message in GOAWAY events.
Motivation:

The Connection.Listener GOAWAY event handler currently provides no additional information, requiring applications to hack in other ways to get at the error code and debug message.

Modifications:

Modified the Connection.Listener interface to pass on the error code and message that triggered the GOAWAY.

Result:

Application can now use Connection.Listener for all GOAWAY processing.
2015-03-31 09:18:26 -07:00
Trustin Lee
44eeb5f6b4 Fix intermittent test failure in LoggingHandlerTest
Motivation:

LoggingHandlerTest sometimes failure due to unexpected log messages
logged due to the automatic reclaimation of thread-local objects.

  Expectation failure on verify:
    Appender.doAppend([DEBUG] Freed 3 thread-local buffer(s) from thread: nioEventLoopGroup-23-0): expected: 1, actual: 0
    Appender.doAppend([DEBUG] Freed 9 thread-local buffer(s) from thread: nioEventLoopGroup-23-1): expected: 1, actual: 0
    Appender.doAppend([DEBUG] Freed 2 thread-local buffer(s) from thread: nioEventLoopGroup-23-2): expected: 1, actual: 0
    Appender.doAppend([DEBUG] Freed 4 thread-local buffer(s) from thread: nioEventLoopGroup-26-0): expected: 1, actual: 0
    Appender.doAppend(matchesLog(expected: ".+CLOSE$", got: "[id: 0xembedded, embedded => embedded] CLOSE")): expected: 1, actual: 0

Modifications:

Add the mock appender to the related logger only

Result:

No more intermittent test failures
2015-03-31 15:08:52 +09:00
Trustin Lee
f4e527c64d Don't trigger IOException at ChunkedStream.isEndOfInput()
Related: #3368

Motivation:

ChunkedWriteHandler checks if the return value of
ChunkedInput.isEndOfInput() after calling ChunkedInput.close().

This makes ChunkedStream.isEndOfInput() trigger an IOException, which is
originally triggered by PushBackInputStream.read().

By contract, ChunkedInput.isEndOfInput() should not raise an IOException
even when the underlying stream is closed.

Modifications:

Add a boolean flag that keeps track of whether the underlying stream has
been closed or not, so that ChunkedStream.isEndOfInput() does not
propagate the IOException from PushBackInputStream.

Result:

Fixes #3368
2015-03-31 11:38:25 +09:00
nmittler
6fbca14f8a Cleaning up the initialization of Http2ConnectionHandler
Motivation:

It currently takes a builder for the encoder and decoder, which makes it difficult to decorate them.

Modifications:

Removed the builders from the interfaces entirely. Left the builder for the decoder impl but removed it from the encoder since it's constructor only takes 2 parameters. Also added decorator base classes for the encoder and decoder and made the CompressorHttp2ConnectionEncoder extend the decorator.

Result:

Fixes #3530
2015-03-30 11:23:02 -07:00
nmittler
cb63e34bda Removing unnecessary sort in remote flow controller.
Motivation:

The DefaultHttp2RemoteFlowController's priority algorithm doesn't really need to sort the children by weight since it already fairly distributes data based on weight.

Modifications:

Removing the sorting in the priority algorithm and updating one test to allow a small bit of variability in the results.

Result:

Slight improvement on the performance of the priority algorithm.
2015-03-30 09:55:03 -07:00
Norman Maurer
a2428c7e47 Add supported for X509ExtendedTrustManager when using OpenSslEngine
Motivation:

For some use cases X509ExtendedTrustManager is needed as it allows to also access the SslEngine during validation.

Modifications:

Add support for X509ExtendedTrustManager on java >= 7

Result:

It's now possible to use X509ExtendedTrustManager with OpenSslEngine
2015-03-30 09:05:18 +02:00
Trustin Lee
bdf0bddc85 Enforce a release is made with JDK 1.7 (and not w/ 1.8+)
Motivations:

JDK 1.8 adds default methods to collections classes that reference
classes that don't exist in JDK 7. That's binary compatible,
but not source compatible.

Modifications:

Enforce JDK version to be 1.7.* when releasing

Result:

Fixes #3548
2015-03-29 17:07:53 +09:00
Scott Mitchell
ab74dccd23 Http/2 Priority on CLOSED stream
Motivation:
The encoder/decoder currently do not handle streams which have previously existed but no longer exist because they were closed. The specification requires supporting this.

Modifications:
- encoder/decoder should tolerate the frame or the dependent frame not existing in the streams map due to the fact that it may have previously existed.

Result:
encoder/decoder are more compliant with the specification.
2015-03-28 19:10:43 -07:00
Scott Mitchell
0d3a6e0511 HTTP/2 Decoder reduce preface conditional checks
Motivation:
The DefaultHttp2ConnectionDecoder class is calling verifyPrefaceReceived() for almost every frame event at all times.
The Http2ConnectionHandler class is calling readClientPrefaceString() on every decode event.

Modifications:
- DefaultHttp2ConnectionDecoder should not have to continuously call verifyPrefaceReceived() because it transitions boolean state 1 time for each connection.
- Http2ConnectionHandler should not have to continuously call readClientPrefaceString() because it transitions boolean state 1 time for each connection.

Result:
- Less conditional checks for the mainstream usage of the connection.
2015-03-28 18:52:35 -07:00
Scott Mitchell
2bf592c50f Backport of HTTP/2 Microbenchmark fail.
Motivation:
The backport of a6c729bdf8 failed.

Modifications:
- Make sure the interfaces are correctly implemented when backporting.

Result:
Microbenchmark compiles and runs on 4.1 branch.
2015-03-28 18:41:09 -07:00
nmittler
bb059c070f Decoupling allocation from writing in HTTP/2 outbound flow control
Motivation:

The current DefaultHttp2RemoteFlowController's writePendingBytes currently operates in 2 passes. The first allocates bytes and optionally writes some frames. The second pass just loops across all active streams and writes all remaining bytes.

If streams can be removed/added as a side effect of writing (EOS or error) then we need to take more care when the write actually occurs. Moving all of the writes to the second loop (across active streams) is simpler since we can just make a copy of the list and not worry about any restructuring of the priority tree that may result.

Modifications:

Modified DefaultHttp2RemoteFlowController.writePendingBytes to only allocate bytes on the first pass and then write any allocated bytes on the second pass.

Result:

Side effects resulting from writing should no longer impact the flow control algorithm.
2015-03-28 14:19:37 -07:00
scottmitch
2dda917f27 Http2DefaultFrameWriter microbenchmark
Motivation:
A microbenchmark will be useful to get a baseline for performance.

Modifications:
- Introduce a new microbenchmark which tests the Http2DefaultFrameWriter.
- Allow benchmarks to run without thread context switching between JMH and Netty.

Result:
Microbenchmark exists to test performance.
2015-03-27 13:10:57 -07:00
Scott Mitchell
23f881b382 Comment punctuation cleanup
Motivation:
Commit d857b16d76 introduced some comments that had no punctuation.

Modifications:
Add punctuation.

Result:
Comments have punctuation.
2015-03-26 13:01:37 -07:00
Scott Mitchell
d857b16d76 Http/2 RST_STREAM frame robustness
Motivation:
The Http2ConnectionHandler writeRstStream method allows RST_STREAM frames to be sent when we do not know about the stream and after a RST_STREAM frame has already been sent.  This may lead to sending frames when we should not according to the HTTP/2 spec. There is also the potential to notify the closeListener multiple times if the closeStream method is called multiple times.

Modifications:
- Prevent RST_STREAM from being sent if we don't know about the stream, or if we already sent the RST_STREAM.
- Prevent the closeListener from being notified multiple times.

Result:
More robust writeRstStream logic in boundary conditions.
2015-03-26 11:47:00 -07:00
David Dossot
18abc6d893 Fix example in CookieDecoder Javadoc
- CookieDecoder.decode() is a static method.
2015-03-26 11:48:51 +09:00
Scott Mitchell
6dfa1f2d92 Http2 draft 17
Motivation:
There was a new draft for HTTP/2.  We should support the new draft.

Modifications:
- Review the HTTP/2 draft 17 specification, and update code to reflect changes.

Result:
Support for HTTP/2 draft 17.
2015-03-25 09:02:15 -07:00
Scott Mitchell
b0e7992c16 Jetty ALNPN and NPN updates plus backport
Motivation:
There are new versions of the ALPN and NPN dependencies.  There was also some backport misses in the pom file related to ALPN/NPN.

Modifications:
- Add new versions for ALPN/NPN dependencies.
- Backport missed pieces from pom.xml.

Result:
Updated version of ALPN/NPN versions.
2015-03-25 08:55:52 -07:00
Scott Mitchell
a24627aa36 HTTP/2 codec missing from all/pom.xml
Motivation:
The codec-http2 module was excluded from the all/pom.xml.

Modifications:
Include the codec-http2 dependency in the all/pom.xml.

Results:
Projects including the all dependency get codec-http2.
2015-03-23 16:29:28 -07:00
Scott Mitchell
d94eab76b6 HTTP/2 examples run script support
Motivation:
The example script has some changes that have not yet been backported.  These changes should be backported.

Modifications:
run-example.sh changes related to http/2 are backported

Result:
HTTP/2 examples can be run on the 4.1 branch.
2015-03-23 16:27:55 -07:00
Pierre DAL-PRA
2ebf07e622 Small typos fixes in Channel's Javadoc 2015-03-21 16:10:24 +01:00
Jakob Buchgraber
8e04d706de Have FlowState.cancel take a Throwable and code cleanup.
Motivation:

- In FlowState.write(...) we are currently swalloing an exception.
- In my previous commit I introduced a compiler warning by not making
  a local variabe final.

Modifications:

- Have FlowState.cancel() take a Throwable.
- Make the variable final.

Result:

No more swallowed exceptions and warnings.
2015-03-19 22:01:02 -07:00
Jakob Buchgraber
9bad408de5 HTTP2: Close encoder and decoder on channelInactive and initialize clientPrefaceString on handlerAdded.
Motivation:

- The encoder and decoder should be closed right after the handler releases its resources.
- The clientPrefaceString is allocated in the constructor but releases in handlerRemoved.
  If the handler is never added to the pipeline, the clientPrefaceString will never be
  released.

Modifications:

- Call encoder.close() and decoder.close() on channelInactive.
- Release the clientPrefaceString on handlerRemoved.

Result:

- The encoder and decoder get closed right after the handler's resources are freed.
- It's easier to verify that the clientPrefaceString will also get released.
2015-03-19 13:09:34 -07:00
JongYoonLim
3405aee2ab Returns after encoding each message not do check following instance types
Motivation:
Current AbstractMemcacheObjectEncoder does unnecessary message type checking if the message is MemcacheMessage type.

Modifications:
Returns after encoding MemcacheMessage message.

Result:
Small performance improvement for this encoder.
2015-03-19 20:43:59 +01:00
JongYoonLim
d5e67032b5 fix typo 2015-03-19 20:41:11 +01:00
Wouter
baa5990e34 Fix typo in javadoc 2015-03-18 17:15:17 +01:00
Trustin Lee
61859eefa0 Safely encode Strings to ASCII
(Ported @luciferous's changes against 3.10)

Motivation:

The current implementation of the encoder writes each character of the
String as a single byte to the buffer, however not all characters are
mappable to a single byte.

Modifications:

If a character is outside the ASCII range, it's converted to '?'.

Result:

A safer encoder for String to ASCII, which substitutes unmappable
characters with'?'.
2015-03-18 15:55:35 +09:00
nmittler
0fe67cfba5 Using public LogLevel for HTTP/2 frame logging.
Motivation:

The Http2FrameLogger is currently using the internal logging classes. We should change this so that it's using the public classes and then converts internally.

Modifications:

Modified Http2FrameLogger and the examples to use the public LogLevel class.

Result:

Fixes #2512
2015-03-17 15:10:35 -07:00
Idel Pivnitskiy
9ccc1f3155 Update jUnit version to 4.12
Motivation:

Too many new features in the new release of jUnit.
https://github.com/junit-team/junit/blob/master/doc/ReleaseNotes4.12.md

Modifications:

- Changed version of jUnit from 4.11 to 4.12 in the parent pom.

Result:

Allows using new testing features.
2015-03-17 16:17:39 +01:00
Trustin Lee
1d061bbb27 Hide password in exception messages of SocksAuthRequest
Related: #3504

Motivation:

There are two places in the SocksAuthRequest constructor where an
IllegalArgumentException is thrown with a password as part of the
exception message.

This constitutes mishandling of confidential information, which can
compromise user privacy and is flagged as critical by security scanners.

Modifications:

Mask the password in the exception messages

Result:

No unexpected password leak
2015-03-17 17:25:09 +09:00
Leonardo Freitas Gomes
a97e413a65 Ensure server preference order in ALPN
Motivation:
With the current implementation the client protocol preference list
takes precedence over the one of the server, since the select method
will return the first item, in the client list, that matches any of the
protocols supported by the server. This violates the recommendation of
http://tools.ietf.org/html/rfc7301#section-3.2.

It will also fail with the current implementation of Chrome, which
sends back Extension application_layer_protocol_negotiation, protocols:
[http/1.1, spdy/3.1, h2-14]

Modifications:
Changed the protocol negotiator to prefer server’s list. Added a test
case that demonstrates the issue and that is fixed with the
modifications of this commit.

Result:
Server’s preference list is used.
2015-03-17 07:28:53 +01:00
nmittler
c91eaace5e Cleaning up HTTP/2 method names for max_concurrent_streams
Motivation:

The current documentation for Endpoint methods referring to concurrent streams and the SETTINGS_MAX_CONCURRENT_STREAMS setting are a bit confusing.

Modifications:

Renamed a few of the methods and added more clear documentation.

Result:

Fixes #3451
2015-03-16 10:17:39 -07:00
Jakob Buchgraber
fe12d08efe Remove dead code from DefaultHttp2ConnectionEncoder.
Motivation:

There are two writeRstStream methods in the DefaultHttp2ConnectionEncoder.
One of the two is neither used nor part of the Http2FrameWriter interface.

Modifications:

Delete the method.

Result:

Fewer lines of dead code.
2015-03-14 09:02:45 -07:00
Jakob Buchgraber
d5963e069d Remove Frame class from DefaultHttp2RemoteFlowController. Fixes #3488
Motivation:

For every write of a flow controlled frame (HEADERS, DATA) we are allocating
a Frame object that is not necessary anymore as it does not maintain any
state, besides the payload.

Modifications:

Remove the Frame class and directly add the payload to the pending write queue.

Result:

One few object allocation per write of a flow controlled frame.
2015-03-13 15:54:40 -07:00
Robert.Panzer
18443efeab Add support for byte order to LengthFieldPrepender
Motivation:

While the LengthFieldBasedFrameDecoder supports a byte order the LengthFieldPrepender does not.
That means that I can simply add a LengthFieldBasedFrameDecoder with ByteOrder.LITTLE_ENDIAN to my pipeline
but have to write my own Encoder to write length fields in little endian byte order.

Modifications:

Added a constructor that takes a byte order and all other parameters.
All other constructors delegate to this one with ByteOrder.BIG_ENDIAN.
LengthFieldPrepender.encode() uses this byte order to write the length field.

Result:

LengthFieldPrepender will write the length field in the defined byte order.
2015-03-13 18:50:20 +01:00
Norman Maurer
c7827dc16a First load RuntimeException to prevent segfault on error
Motivation:

When an error happens during loading the native library it may try to generate a new RuntimeException before the RuntimeException is loaded.

Modifications:

- Load RuntimeException as first

Result:

No more segfaults possible
2015-03-13 18:28:40 +01:00