Commit Graph

6752 Commits

Author SHA1 Message Date
Scott Mitchell
453b958988 DefaultPromise LateListener Logic Issues
Motivation:
The LateListener logic is prone to infinite loops and relies on being processed in the EventExecutor's thread for synchronization, but this EventExecutor may not be constant. An infinite loop can occur if the EventExecutor's execute method does not introduce a context switch in LateListener.run. The EventExecutor can be changed by classes which inherit from DefaultPromise. For example the DefaultChannelPromise will return w/e EventLoop the channel is registered to, but this EventLoop can change (re-registration).

Modifications:
- Remove the LateListener concept and instead use a single Object to maintain the listeners while still preserving notification order
- Make the result member variable an atomic variable so it can be outside the synchronized(this) blocks
- Cleanup/simplify existing state management code

Result:
Fixes https://github.com/netty/netty/issues/5185
2016-05-09 10:36:22 -07:00
Daniel Bevenius
5d7a8a5711 Add logging configuration to pom.xml
Motivation:
Currently the default log level when running tests is debug. When
running the build on the CI server it might be nice to avoid this debug
level and allow for the level to be configured.

Modifications:
Added a logback-test.xml configuration that has been added to the
common module. This allows for the logLevel to be configured.
The default level will still be debug.

Result:
The log level can now be configured from the command line:
$ mvn test -DlogLevel=error
2016-05-09 15:18:45 +02:00
Norman Maurer
e4501a5de0 [#5218] Zero out private key copied to ByteBuf before release.
Motivation:

We should zero-out the private key as soon as possible when we not need it anymore.

Modifications:

zero out the private key before release the buffer.

Result:

Limit the time the private key resist in memory.
2016-05-09 10:00:19 +02:00
Norman Maurer
451e6aeb66 [#5216] Correctly increment deallocationsHuge when call PoolArena.free
Motivation:

We called deallocationsHuge.decrement() but it needs to be increment()

Modifications:

Replace decrement() with increment()

Result:

Correct metrics.
2016-05-06 21:44:25 +02:00
Norman Maurer
a96874aad4 [#5171] Ensure NioDatagramChannelConfig can be instanced on android
Motivation:

NioDatagramChannelConfig currently uses NetworkChannel in its static { } block and so fails to init on android which not has this class.

Modifications:

Use reflection to load the NetworkChannel.class

Result:

Be able to use NIO Datagram on android as well.
2016-05-06 08:04:10 +02:00
Norman Maurer
c88761d1d9 [#5202] Correctly throw ErrorDataDecoderException when invalid encoded form parameters are present.
Motivation:

At the moment we let the IllegalArgumentException escape when parsing form parameters. This is not expected.

Modifications:

Correctly catch IllegalArgumentException and rethrow as ErrorDataDecoderException.

Result:

Throw correct exception.
2016-05-04 21:15:12 +02:00
Fabian Lange
5aa87774a0 Rewrite misleading Note in FingerprintTrustManagerFactory javadoc
Motivation:

The current note reads as if this class is dangerous and advises the reader to "understand what this class does".

Modifications:

Rewrite the Javadoc note to describe what fingerprint checks are and what problems remain.

Result:

Clearer description which no longer causes the impression this class is dangerous.
2016-05-03 07:39:52 +02:00
Renjie Sun
ad27387646 Improve client SNI in testSniWithApnHandler
Motivations
The test SniHandlerTest#testSniWithApnHandler() does not actually
involve SNI: given the client setup, the ClientHello in the form of hex
strings is not actually written to the wire, so the server never receives that.
We may need to write in somewhere else (e.g., channelActive()) instead of in
initChannel() in order for the hex strings to reach the server. So here
what's actually going on is an ordinary TLS C/S communication without SNI.

Modifications
The client part is modified to enable SNI by using an SslHandler with an
SSLEngine created by io.netty.handler.ssl.SslContext#newEngine(), where
the server hostname is specified. Also, more clauses are added to verify that
the SNI is indeed successful.

Results
Now the test verifies that both SNI and APN actually happen and succeed.
2016-05-01 20:23:45 +02:00
Guido Medina
6d7bed3431 TreeMap extra get operation removed.
Motivation:
Checking if a key exists on a TreeMap has a Big O of "log 2 N",
doing it twice is not cheap.

Modifications:
Get the key instead which has the same cost and check if it is null.

Result:
Faster code due to one expensive operation removed.
2016-04-25 09:48:39 -07:00
Scott Mitchell
0f5b25797b Revert "EpollEventLoopGroup support Executor"
This reverts commit f8f1efc3ba. It should not have been backported.
2016-04-23 11:02:43 -07:00
Scott Mitchell
096a605f30 NioEventLoop closes channel even if channel is not registered
Motivation:
If a channel is deregistered from an NioEventLoop the associated SelectionKey is cancelled. If the NioEventLoop has yet to process a pending event as a result of that SelectionKey then the NioEventLoop will see the SelecitonKey is invalid and close the channel. The NioEventLoop should not close a channel if it is not registered with that NioEventLoop.

Modifications:
- NioEventLoop.processSelectedKeys should check that the channel is still registered to itself before closing the channel

Result:
NioEventLoop doesn't close a channel that is no longer registered to it when the SelectionKey is invalid
Fixes https://github.com/netty/netty/issues/5125
2016-04-21 09:16:25 -07:00
Scott Mitchell
f8f1efc3ba EpollEventLoopGroup support Executor
Motivation:
NioEventLoopGroup supports constructors which take an executor but EpollEventLoopGroup does not. EPOLL should be consistent with NIO where ever possible.

Modifications:
- Add constructors to EpollEventLoopGroup which accept an Executor as a parameter

Result:
EpollEventLoopGroup is more consistent with NioEventLoopGroup
Fixes https://github.com/netty/netty/issues/5161
2016-04-21 08:34:14 -07:00
Norman Maurer
f94edd2e92 Correctly handle ChannelInputShutdownEvent in ReplayingDecoder
Motivation:

b112673554 added ChannelInputShutdownEvent support to ByteToMessageDecoder but missed updating the code for ReplayingDecoder. This has the effect:

- If a ChannelInputShutdownEvent is fired ByteToMessageDecoder (the super-class of ReplayingDecoder) will call the channelInputClosed(...) method which will pass the incorrect buffer to the decode method of ReplayingDecoder.

Modifications:

Share more code between ByteToMessageDEcoder and ReplayingDecoder and so also support ChannelInputShutdownEvent correctly in ReplayingDecoder

Result:

ChannelInputShutdownEvent is corrrectly handle in ReplayingDecoder as well.
2016-04-14 10:21:12 +02:00
Norman Maurer
527c07e41b Fix resource leak in tests introduced by 69070c37ba. 2016-04-14 10:14:37 +02:00
Norman Maurer
b80a1a077c We need to ensure we correct reset decoder in decodeLast() to not produce multiple LastHttpContent instances.
Motivation:

We missed to reset the decoder when asked for it in HttpObjectDecoder and so sometimes could produce more then one LastHttpContent in a sequence during channelInactive.

This did show up as AssertionError:

22:22:35.499 [nioEventLoopGroup-3-1] WARN  i.n.channel.DefaultChannelPipeline - An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
java.lang.AssertionError: null
	at io.netty.handler.codec.http.HttpObjectAggregator.decode(HttpObjectAggregator.java:205) ~[classes/:na]
	at io.netty.handler.codec.http.HttpObjectAggregator.decode(HttpObjectAggregator.java:57) ~[classes/:na]
	at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:89) ~[classes/:na]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292) [classes/:na]
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278) [classes/:na]
	at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:428) [classes/:na]
	at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:277) [classes/:na]
	at io.netty.handler.codec.ByteToMessageDecoder.channelInputClosed(ByteToMessageDecoder.java:343) [classes/:na]
	at io.netty.handler.codec.ByteToMessageDecoder.channelInactive(ByteToMessageDecoder.java:309) [classes/:na]
	at io.netty.handler.codec.http.HttpClientCodec$Decoder.channelInactive(HttpClientCodec.java:228) [classes/:na]
	at io.netty.channel.CombinedChannelDuplexHandler.channelInactive(CombinedChannelDuplexHandler.java:213) [classes/:na]
        ...

Modifications:

Correctly reset decoder.

Result:

Correctly only produce one LastHttpContent per sequence.
2016-04-14 09:33:10 +02:00
Norman Maurer
71d0c26536 [#4836] Enforce 64bit JDK when build netty.
Motivation:

As we only provide tcnative jars for 64bit we should enforce 64bit when try to build netty, to make it easier for the user to understand why the build fails.

Modifications:

Add enforce rule.

Result:

Ensure 64bit is used when build netty.
2016-04-14 09:30:46 +02:00
Norman Maurer
8d3ef3a80e [#4635] Stop decoding if decoder was removed in ReplayingDecoder
We need to check if this handler was removed before continuing with decoding.
If it was removed, it is not safe to continue to operate on the buffer. This was already fixed for ByteToMessageDecoder in 4cdbe39284  but missed for ReplayingDecoder.

Modifications:

Check if decoder was removed after fire messages through the pipeline.

Result:

No illegal buffer access when decoder was removed.
2016-04-14 08:25:32 +02:00
Norman Maurer
e3aced62ed Fix IndexOutOfBoundsException when FixedCompositeByteBuf is constructed with an empty array.
Motivation:

When FixedCompositeByteBuf was constructed with new ByteBuf[0] and IndexOutOfboundsException was thrown.

Modifications:

Fix constructor

Result:

No more exception
2016-04-14 08:08:07 +02:00
Norman Maurer
373b2ba4f1 Fix typo in exception message
Motivation:

Typo in exception message.

Modifications:

Fix the typo.

Result:

No more typo.
2016-04-14 08:04:08 +02:00
Trustin Lee
bb3bf5dc2f Implement the ByteBuf methods that should have been overridden
Motivation:

Some ByteBuf implementations do not override all necessary methods,
which can lead to potentially sub-optimal behavior.

Also, SlicedByteBuf does not perform the range check correctly due to
missing overrides.

Modifications:

- Add missing overrides
- Use unwrap() instead of direct member access in derived buffers for
  consistency
- Merge unwrap0() into unwrap() using covariant return type
- Deprecate AbstractDerivedByteBuf and its subtypes, because they were
  not meant to be public

Result:

Correctness
2016-04-13 21:25:07 +09:00
nmittler
6fc05772d0 Support preloading of tcnative share lib
Motivation:

Some applications may use alternative methods of loading the tcnative JNI symbols. We should support this use case.

Modifications:

Separate the loading and initialzation of the tcnative library so that each can fail independently.

Result:

Fixes #5043
2016-04-12 20:21:19 +02:00
nmittler
d9b4ec050c Support preloading of native epoll lib
Motivation:

Some applications may use alternative methods of loading the epoll JNI symbols. We should support this use case.

Modifications:

Attempt to use a side effect free JNI method. If that fails, load the library.

Result:

Fixes #5122
2016-04-12 20:20:12 +02:00
Norman Maurer
3f52689eb1 Fix compile error introduced by 3046e9b78b 2016-04-12 16:36:23 +02:00
Norman Maurer
3046e9b78b Fix resource-leak which was reported as a result of commit 69070c37ba 2016-04-12 16:27:20 +02:00
Norman Maurer
fb434de598 Fix resource leak in test introduced by 69070c37ba 2016-04-10 08:38:38 +02:00
Norman Maurer
485f642047 Revert "[#5028] Fix re-entrance issue with channelWritabilityChanged(...) and write(...)"
Motivation:
Revert 2e68e37025. Delaying the notification of writability change may lead to notification being missed. This is a ABA type of concurrency problem.

Modifications:

Revert 2e68e37025.

Result:

channelWritabilityChange will be called on every change, and will not be suppressed due to ABA scenario.
2016-04-09 20:33:32 +02:00
Norman Maurer
8d63aae484 ByteBuf.readBytes(...) should use the allocator of the buffer to create the new buffer. Related to [#5093]
Motivation:

ByteBuf.readBytes(...) uses Unpooled.buffer(...) internally which will use a heap ByteBuf and also not able to make use of the allocator which may be pooled. We should better make use of the allocator.

Modifications:

Use the allocator for thenew buffer.

Result:

Take allocator into account when copy bytes.
2016-04-09 20:31:13 +02:00
Norman Maurer
856d6b9402 Add PooledByteBufAllocator.dumpStats() which allows to obtain a human-readable status of the allocator.
Motiviation:

Sometimes it is useful to dump the status of the PooledByteBufAllocator and log it. Doing this is currently a bit cumbersome as the user needs to basically iterate through all the metrics and compose the String. we would better provide an easy way to do this.

Modification:

Add dumpStats() method.

Result:

Easier to get a view into the status of the allocator.
2016-04-09 19:16:30 +02:00
Norman Maurer
bfdfb50df6 Allow to create a JdkSslContext from an existing JDK SSLContext. Related to [#5095] and [#4929]
Motivation:

Sometimes a user only has access to a preconfigured SSLContext but still would like to use our ssl sub-system. For this situations it would be very useful if the user could create a JdkSslContext instance from an existing SSLContext.

Modifications:

- Create new public constructors in JdkSslContext which allow to wrap an existing SSLContext and make the class non-abstract
- Mark JdkSslServerContext and JdkSslClientContext as deprecated as the user should not directly use these.

Result:

It's now possible to create an JdkSslContext from an existing SSLContext.
2016-04-09 19:08:32 +02:00
Norman Maurer
8617df7f2d Ensure EpollSocketChannel.localAddress() returns correct address after connect(...) call.
Motivation:

We missed to correctly retrieve the localAddress() after we called Socket.connect(..) and so the user would always see an incorrect address when calling EpollSocketChannel.localAddress().

Modifications:

- Ensure we always retrieve the localAddress() after we called Socket.connect(...) as only after this we will be able to receive the correct address.
- Add unit test

Result:

Correct and consistent behaviour across different transports (NIO/OIO/EPOLL).
2016-04-09 19:04:59 +02:00
Norman Maurer
87b8bdbbdd PoolChunkList.allocate(...) should return false without the need to walk all the contained PoolChunks when the requested capacity is too big.
Motivation:

PoolChunkList.allocate(...) should return false without the need to walk all the contained PoolChunks when the requested capacity is larger then the capacity that can be allocated out of the PoolChunks in respect to the minUsage() and maxUsage() of the PoolChunkList.

Modifications:

Precompute the maximal capacity that can be allocated out of the PoolChunks that are contained in the PoolChunkList and use this to fast return from the allocate(...) method if an allocation capacity larger then that is requested.

Result:

Faster detection of allocations that can not be handled by the PoolChunkList and so faster allocations in general via the PoolArena.
2016-04-09 19:02:02 +02:00
Norman Maurer
3a1eb6a149 Allow to retrieve the number of active bytes per PoolArena.
Motivation:

To better understand how much memory is used by Netty for ByteBufs it is useful to understand how many bytes are currently active (allocated) per PoolArena.

Modifications:

- Add PoolArenaMetric.numActiveBytes()

Result:

The user is able to get better insight into the PooledByteBufAllocator.
2016-04-09 18:53:27 +02:00
Norman Maurer
c5b74afe58 Cleanup PoolChunk and PoolArena
Motivation:

To make it easier to understand PoolChunk and PoolArena we should cleanup duplicated code.

Modifications:

- Move reused code into methods
- Use Math.max(...)

Result:

Cleaner code and easier to understand.
2016-04-09 18:48:17 +02:00
Norman Maurer
e35b7f982f Remove ByteBuf.readBytes(int) calls when possible
Motivation:

We use ByteBuf.readBytes(int) in various places where we could either remove it completely or use readSlice(int).retain().

Modifications:

- Remove ByteBuf.readBytes(int) when possible or replace by readSlice(int).retain().

Result:

Faster code.
2016-04-09 18:44:58 +02:00
Norman Maurer
db74b2344f Not try to allocate out of the PoolChunkList that contains only full PoolChunks
Motivation:

When doing a normal allocation in PoolArena we also tried to allocate out of the PoolChunkList that only contains completely full PoolChunks. This makes no sense as these are full anyway so an allocation will never work here and just gives a perf hit as we need to walk the whole list of PoolChunks in the list.

Modifications:

Not try to allocate from PoolChunkList that only contains full PoolChunks

Result:

Faster allocation times when a new PoolChunk must be created.
2016-04-09 18:39:33 +02:00
Xiaoyan Lin
b2651cc351 Make all InternalLoggerFactory implementations be singletons
Motivation:

It's better to make all InternalLoggerFactory implementations be singletons according to the discussions in #5047

Modifications:

Make all InternalLoggerFactory implementations be singletons and hide the construtors.

Result:

All InternalLoggerFactory implementations be singletons.
2016-04-08 09:39:47 +02:00
Norman Maurer
560e0946b3 Use Math.min(...) and Math.max(...) as these are intrinsics.
Motivation:

We should better use Math utilities as these are intrinsics. This is a cleanup for ea3ffb8536.

Modifications:

Use Math utilities.

Result:

Cleaner code and use of intrinsics.
2016-04-06 21:32:10 +02:00
Kun Zhang
8bdf73edea Explicit thread group on DefaultThreadFactory.
Motivation:

Fixes #5084. We (gRPC) encountered a bug that was triggered by
grpc/grpc-java@d927180. After that commit, event loop threads are
created per task by NioEventLoopGroup, and inherits the thread group of
the caller, which in our case is an application-provided request-scope
thread. Things go south when the application tries to manipulate (e.g.,
interrupt and join) all threads of the request-scope thread group, which
unexpectedly include the event loop threads.

Modifications:

DefaultThreadFactory will save the current thread group in constructor,
and apply it to all new threads.

Result:

Threads created by DefaultThreadFactory will be in the same thread group
as the thread where the factory is created.
2016-04-06 21:19:18 +02:00
Norman Maurer
66ce014074 PoolChunkList not correctly move PoolChunks when these are moved.
Motivation:

When a PoolChunk needs to get moved to the previous PoolChunkList because of the minUsage / maxUsage constraints we always just moved it one level which is incorrect and so could lead to have PoolChunks in the wrong PoolChunkList (in respect to their minUsage / maxUsage settings). This then could have the effect that PoolChunks are not released / freed in a timely fashion and so.

Modifications:

- Correctly move PoolChunks between PoolChunkLists, which includes moving it multiple "levels".
- Add unit test

Result:

Correctlty move the PoolChunk to PoolChunkList when it is freed, even if its multiple layers.
2016-04-06 11:52:06 +02:00
Trustin Lee
c453c3ce0d Do now swallow an exception triggered by late listener notification
Related: #3449

Motivation:

When a user shut down an EventExecutor/Loop prematurely, a Promise will
fail to execute its listeners. When it happens, DefaultPromise will log
a message at ERROR level, but there's no way to get notified about it
programmatically.

Modifications:

Do not catch and log the RejectedExecutionException unconditionally,
but only catch and log for non-late listener notifications, so that a
user gets notified on submission failure at least when the listener is
late.

Result:

Remedies #3449 to some extent, although we will need fundamental fix for
that, such as #3566
2016-04-06 11:16:58 +02:00
Norman Maurer
2e68e37025 [#5028] Fix re-entrance issue with channelWritabilityChanged(...) and write(...)
Motivation:

When always triggered fireChannelWritabilityChanged() directly when the update the pending bytes in the ChannelOutboundBuffer was made from within the EventLoop. This is problematic as this can cause some re-entrance issue if the user has a custom ChannelOutboundHandler that does multiple writes from within the write(...) method and also has a handler that will intercept the channelWritabilityChanged event and trigger another write when the Channel is writable. This can also easily happen if the user just use a MessageToMessageEncoder subclass and triggers a write from channelWritabilityChanged().

Beside this we also triggered fireChannelWritabilityChanged() too often when a user did a write from outside the EventLoop. In this case we increased the pending bytes of the outboundbuffer before scheduled the actual write and decreased again before the write then takes place. Both of this may trigger a fireChannelWritabilityChanged() event which then may be re-triggered once the actual write ends again in the ChannelOutboundBuffer.

The third gotcha was that a user may get multiple events even if the writability of the channel not changed.

Modification:

- Always invoke the fireChannelWritabilityChanged() later on the EventLoop.
- Only trigger the fireChannelWritabilityChanged() if the channel is still active and if the writability of the channel changed. No need to cause events that were already triggered without a real writability change.
- when write(...) is called from outside the EventLoop we only increase the pending bytes in the outbound buffer (so that Channel.isWritable() is updated directly) but not cause a fireChannelWritabilityChanged(). The fireChannelWritabilityChanged() is then triggered once the task is picked up by the EventLoop as usual.

Result:

No more re-entrance possible because of writes from within channelWritabilityChanged(...) method and no events without a real writability change.
2016-04-06 10:50:41 +02:00
Norman Maurer
a034c1cfc6 Fix PoolChunkList.minUsage() and maxUsage() for head and tail
Motivation:

The PoolChunkList.minUsage() and maxUsage() needs to take special action to translate Integer.MIN_VALUE / MAX_VALUE as these are used internal for tail and head of the linked-list structure.

Modifications:

- Correct the minUsage() and maxUsage() methods.
- Add unit test.

Result:

Correct metrics
2016-04-06 10:03:14 +02:00
Scott Mitchell
4506bbd27b fcbeebf6df unit test bug
Motivation:
fcbeebf6df introduced a unit test to verify ApplicationProtocolNegotiationHandler is compatible with SniHandler. However only the server attempts ALPN and verifies that it completes and the client doesn't verify the handshake is completed. This can lead to the client side SSL engine to prematurely close and throw an exception.

Modifications:
- The client should wait for the SSL handshake and ALPN to complete before the test exits.

Result:
SniHandlerTest.testSniWithApnHandler is more reliable.
2016-04-06 00:12:54 -07:00
Norman Maurer
61ae4a3a78 Include cause that was used to notify the promise when logging an failed try to notify it.
Motivation:

When a promise is notified that was already added to the ChannelOutboundBuffer and we try to notify it later on we only see a warning that it was notified before. This is often not very useful as we have no idea where it was notified at all. We can do better in case it was failed before (which is most of the times the case) and just also log the cause that was used for it.

Modifications:

Add the cause that was used to notify the promise when we fail to notify it as part of the ChannelOutboundBuffer.

Result:

Easier to debug user errors.
2016-04-05 21:13:00 +02:00
Xiaoyan Lin
35c5664a64 Add Log4J2LoggerFactory and Log4J2Logger
Motivation:

See #3095

Modifications:

Add Log4J2LoggerFactory and Log4J2Logger which is an InternalLogger implementation based on log4j2.

Result:

The user can use log4j2 directly without a special slf4j binding.
2016-04-05 14:07:26 +02:00
Norman Maurer
6a1c5611ab Allow to disable leak detection for all buffers when using UnpooledByteBufAllocator.
Motivation:

Sometimes it is useful to allow to disable the leak detection of buffers if the UnpooledByteBufAllocator is used. This is for example true if the app wants to leak buffers into user code but not want to put the burden on the user to always release the buffer.

Modifications:

Add another constructor to UnpooledByteBufAllocator that allows to completely disable leak-detection for all buffers that are allocator out of the UnpooledByteBufAllocator.

Result:

It's possible to disable leak-detection when the UnpooledByteBufAllocator is used.
2016-04-05 13:20:15 +02:00
Norman Maurer
5a0d0daed3 Only increment metric for huge / normal allocations after the allocation was really done.
Motivation:

We should only increment the metric for the huge / normal allocation after it is done. Also we should only decrement once deallocate.

Modifications:

- Move increment after the allocation.
- Fix deallocation metric and move it after deallocation

Result:

More correct metrics.
2016-04-05 12:00:58 +02:00
Norman Maurer
2547438783 PoolThreadCache uses wrong variable in IllegalArgumentException
Motivation:

PoolThreadCache includes the wrong value when throwing a IllegalArgumentException because of freeSweepAllocationThreshold.

Modifications:

Use the correct value.

Result:

Correct exception message.
2016-04-05 11:48:59 +02:00
Scott Mitchell
2263d9b46b ApplicationProtocolNegotiationHandler doesn't work with SniHandler
Motivation:
ApplicationProtocolNegotiationHandler attempts to get a reference to an SslHandler in handlerAdded, but when SNI is in use the actual SslHandler will be added to the pipeline dynamically at some later time. When the handshake completes ApplicationProtocolNegotiationHandler throws an IllegalStateException because its reference to SslHandler is null.

Modifications:
- Instead of saving a reference to SslHandler in handlerAdded just search the pipeline when the SslHandler is needed

Result:
ApplicationProtocolNegotiationHandler support SniHandler.
Fixes https://github.com/netty/netty/issues/5066
2016-04-05 09:03:07 +02:00
Norman Maurer
4b6b167839 [maven-release-plugin] prepare for next development iteration 2016-04-04 16:53:40 +02:00