Commit Graph

841 Commits

Author SHA1 Message Date
Norman Maurer
0035630bd0 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:23 +02:00
Norman Maurer
718bf2fa45 Fix resource-leak which was reported as a result of commit 69070c37ba 2016-04-12 16:27:02 +02:00
Norman Maurer
4652223dec Fix resource leak in test introduced by 69070c37ba 2016-04-10 08:04:57 +02:00
Hyangtack Lee
24254b159f Propagate h2c upgrade success event to the next handler before removing source codec
Motivation:

When upgrading h2c, I found that sometimes both of http2 settings frame and http response message was arrived before receiving upgrade success event. It was because ByteToMessageDecoder propagated its internally buffered message to the next handler when removing itself from pipeline.(refer to ByteToMessageDecoder#handlerRemoved)
I think it's better to propagate upgrade success event when handling 101 switching protocol response.

Modifications:

Upgrade success event will be propagated before removing source codec.

Result:

It guarantees that upgrade success event will be arrived first at the next handler.
2016-04-07 17:41:46 +02:00
Norman Maurer
f46cfbc590 [#5059] Deprecate method with typo and introduce a new one without typo
Motivation:

There is a spelling error in FileRegion.transfered() as it should be transferred().

Modifications:

Deprecate old method and add a new one.

Result:

Fix typo and can remove the old method later.
2016-04-05 15:06:46 +02:00
Stephane Landelle
881ff3cd98 Drop broken DefaultCookie name validation, close #4999
Motivation:

DefaultCookie constructor performs a name validation that doesn’t match
RFC6265. Moreover, such validation is already performed in strict
encoders and decoders.

Modifications:

Drop DefaultCookie name validation, rely on encoders and decoders.

Result:

no more duplicate broken validation
2016-03-22 12:32:09 +01:00
Norman Maurer
4e3a413047 Correctly handle UpgradeEvent.release(decrement).
Motivation:

We missed to pass the decrement value to the wrapped FullHttpRequest and so missed to decrement the reference count in the correct way.

Modifications:

Correctly pass the decrement value to the wrapped request.

Result:

UpgradeEvent.release(decrement) works as expected.
2016-03-20 09:34:12 +01:00
Norman Maurer
8ec594c6eb Change HttpServerUpgradeHandler.UpgradeCodec to allow aborting upgrade
Motivation:

HttpServerUpgradeHandler.UpgradeCodec.prepareUpgradeResponse should allow to abort the upgrade and so just continue with using HTTP. Beside this we should only pass in the response HttpHeaders as this is inline with the docs.

Modifications:

- UpgradeCodec.prepareUpgradeResponse now allows to return a boolean and so allows to specifiy if the upgrade should take place.
- Change the param from FullHttpResponse to HttpHeaders to be inline with the javadocs.

Result:

More flexible and correct handling of upgrades.
2016-03-18 17:01:59 +01:00
Stephane Landelle
d747438366 Add ! to allowed cookie value chars
Motivation:

! is missing from allowed cookie value chars, as per https://tools.ietf.org/html/rfc6265#section-4.1.1.
Issue was originally reported on Play!, see https://github.com/playframework/playframework/issues/4460#issuecomment-198177302.

Modifications:

Stick to RFC6265 ranges.

Result:

RFC6265 compliance, ! is supported
2016-03-18 16:58:54 +01:00
Norman Maurer
ed9d6c79bc [#4972] Remove misleading argument from HttpServerUpgradeHandler.UpgradeCodec.upgradeTo
Motivation:

upgradeTo(...) takes the response as paramater, but the respone itself was already written to the Channel. This gives the user the impression the response can be changed or even act on it which may not be safe anymore once it was written and has been released.

Modifications:

Remove the response param from the method.

Result:

Less confusion and safer usage.
2016-03-17 10:50:07 +01:00
Julien Viet
3d7cec6376 Bug fix for HttpPostMultipartRequestDecoder part decoding with an invalid charset not reported as an ErrorDataDecoderException
Motivation:

The current HttpPostMultipartRequestDecoder can decode multipart/form-data parts with a Content-Type that specifies a charset. When this charset is invalid the Charset.forName() throws an unchecked UnsupportedCharsetException. This exception is not catched by the decoder. It should actually be rethrown as an ErrorDataDecoderException, because the developer using the API would expect this validation failure to be reported as such.

Modifications:

Add a catch block for UnsupportedCharsetException and rethrow it as an ErrorDataDecoderException.

Result:

UnsupportedCharsetException are now rethrown as ErrorDataDecoderException.
2016-03-10 18:33:06 +01:00
Sergey Polovko
68bbd4e966 Handle only those http requests that equal to adjusted websocket path
Motivation:

It will be easier to support websockets in server application by using WebSocketServerProtocolHandshakeHandler class and not reinvent its functionality. But currently it handles all http requests as if they were websocket handshake requests.

Modifications:

Check if http request path is equals to adjusted websocket path.
Fixed example of websocket server implementation.

Result:

WebSocketServerProtocolHandshakeHandler handles only websocket handshake requests.
2016-03-04 08:36:14 +01:00
Dmitry Spikhalskiy
0d3eda38e1 Helper method to get mime-type from Content-Type header of HttpMessage 2016-03-03 15:18:39 +01:00
Norman Maurer
9aac6dac2e [#4386] ByteToMessage.decodeLast(...) should not call decode(...) if buffer is empty.
Motivation:

If the input buffer is empty we should not have decodeLast(...) call decode(...) as the user may not expect this.

Modifications:

- Not call decode(...) in decodeLast(...) if the input buffer is empty.
- Add testcases.

Result:

decodeLast(...) will not call decode(...) if input buffer is empty.
2016-03-01 08:42:26 +01:00
Brendt Lucas
41d0a81691 Use ByteBufAllocator to allocate ByteBuf for FullHttpMessage Motivation: When converting SPDY or HTTP/2 frames to HTTP/1.x, netty always used an unpooled heap ByteBuf.
Modifications:
When constructing the FullHttpMessage pass in the ByteBuf to use via the ByteBufAllocator assigned via the context.

Result:
The ByteBuf assigned to the FullHttpMessage can now be configured as a pooled/unpooled, direct/heap based ByteBuf via the ByteBufAllocator used.
2016-02-17 19:55:52 -08:00
Xiaoyan Lin
333f55e9ce Add unescapeCsvFields to parse a CSV line and implement CombinedHttpHeaders.getAll
Motivation:

See #4855

Modifications:

Unfortunately, unescapeCsv cannot be used here because the input could be a CSV line like `"a,b",c`. Hence this patch adds unescapeCsvFields to parse a CSV line and split it into multiple fields and unescaped them. The unit tests should define the behavior of unescapeCsvFields.

Then this patch just uses unescapeCsvFields to implement `CombinedHttpHeaders.getAll`.

Result:

`CombinedHttpHeaders.getAll` will return the unescaped values of a header.
2016-02-15 15:26:15 -08:00
Scott Mitchell
b112673554 ByteToMessageDecoder ChannelInputShutdownEvent support
Motivation:
b714297a44 introduced ChannelInputShutdownEvent support for HttpObjectDecoder. However this should have been added to the super class ByteToMessageDecoder, and ByteToMessageDecoder should not propegate a channelInactive event through the pipeline in this case.

Modifications:
- Move the ChannelInputShutdownEvent handling from HttpObjectDecoder to ByteToMessageDecoder
- ByteToMessageDecoder doesn't call ctx.fireChannelInactive() on ChannelInputShutdownEvent

Result:
Half closed events are treated more generically, and don't get translated into a channelInactive pipeline event.
2016-02-12 16:15:17 -08:00
Scott Mitchell
a15ff32608 HttpObjectDecoder configurable initial buffer size
Motivation:
The initial buffer size used to decode HTTP objects is currently fixed at 128. This may be too small for some use cases and create a high amount of overhead associated with resizing/copying. The user should be able to configure the initial size as they please.

Modifications:
- Make HttpObjectDecoder's AppendableCharSequence initial size configurable

Result:
Users can more finely tune initial buffer size for increased performance or to save memory.
Fixes https://github.com/netty/netty/issues/4807
2016-02-07 21:23:29 -08:00
Xiaoyan Lin
f59392d9f5 Make "CorsConfigBuilder.allowNullOrigin()" public
Motivation:

"CorsConfigBuilder.allowNullOrigin()" should be public otherwise people can not set it. See #4835

Modifications:

Make "CorsConfigBuilder.allowNullOrigin()" public.

Result:

The user can call "CorsConfigBuilder.allowNullOrigin()" now.
2016-02-07 10:23:24 -08:00
Norman Maurer
7ef6db3ffd [#4754] Correctly detect websocket upgrade
Motivation:

If the Connection header contains multiple values (which is valid) we fail to detect a websocket upgrade

Modification:

- Add new method which allows to check if a header field contains a specific value (and also respect multiple header values)
- Use this method to detect handshake

Result:

Correct detect handshake if Connection header contains multiple values (seperated by ',').
2016-02-04 14:03:08 +01:00
Norman Maurer
a0758e7e60 [#4794] Support window size flag by default if ZlibCodecFactory supports it.
Motivation:

If the ZlibCodecFactory can support using a custom window size we should support it by default in the websocket extensions as well.

Modifications:

Detect if a custom window size can be handled by the ZlibCodecFactory and if so enable it by default for PerMessageDeflate*ExtensionHandshaker.

Result:

Support window size flag by default in most installations.
2016-02-04 14:01:40 +01:00
Norman Maurer
7a562943ad [#4533] Ensure replacement of decoder is delayed after finishHandshake() is called
Motivation:

If the user calls handshake.finishHandshake() we need to ensure that the user has the chance to setup the pipeline before any WebSocketFrames are read. Because of this we need
to delay the removal of the HttpRequestDecoder.

Modifications:

- Remove the HttpRequestDecoder via the EventLoop and so delay it which gives the user a chance to setup the pipeline after finishHandshake() completes
- Add unit test for this.

Result:

Less surpising and correct behaviour even if the http response and websocket frame are received in one read operation.
2016-02-04 13:57:35 +01:00
Luke Daley
d97f17060f Support non chunked HTTP request bodies larger than Integer.MAX_VALUE.
Motivation:

Request bodies can easily be larger than Integer.MAX_VALUE in practice.
There's no reason, or intention, for Netty to impose this artificial constraint.

Worse, it currently does not fail if the body is larger than this value;
it just silently only reads the first Integer.MAX_VALUE bytes and discards the rest.

This restriction doesn't effect chunked transfers, with no Content-Length header.

Modifications:

Force the use of `long HttpUtil.getContentLength(HttpMessage, long)` instead of
`long HttpUtil.getContentLength(HttpMessage, long)`.

Result:

Netty will support HTTP request bodies of up to Long.MAX_VALUE length.
2016-02-02 08:28:27 +01:00
Trustin Lee
4d6ab1d30d Fix missing trailing data on HTTP client upgrade
Motivation:

When HttpClientUpgradeHandler upgrades from HTTP/1 to another protocol,
it performs a two-step opertion:

1. Remove the SourceCodec (HttpClientCodec)
2. Add the UpgradeCodec

When HttpClientCodec is removed from the pipeline, the decoder being
removed triggers channelRead() event with the data left in its
cumulation buffer. However, this is not received by the UpgradeCodec
becuase it's not added yet. e.g. HTTP/2 SETTINGS frame sent by the
server can be missed out.

To fix the problem, we need to reverse the steps:

1. Add the UpgradeCodec
2. Remove the SourceCodec

However, this does not work as expected either, because UpgradeCodec can
send a greeting message such as HTTP/2 Preface. Such a greeting message
will be handled by the SourceCodec and will trigger an 'unsupported
message type' exception.

To fix the problem really, we need to make the upgrade process 3-step:

1. Remove/disable the encoder of SourceCodec
2. Add the UpgradeCodec
3. Remove the SourceCodec

Modifications:

- Add SourceCodec.prepareUpgradeFrom() so that SourceCodec can remove or
  disable its encoder
- Implement HttpClientCodec.prepareUpgradeFrom() properly
- Miscellaneous:
  - Log the related channel as well When logging the failure to send a
    GOAWAY

Result:

Cleartext HTTP/1-to-HTTP/2 upgrade works again.
2016-02-01 15:52:37 +01:00
Xiaoyan Lin
b7415a3307 Add a reusable ArrayList to InternalThreadLocalMap
Motivation:

See #3411. A reusable ArrayList in InternalThreadLocalMap can avoid allocations in the following pattern:

```
List<...> list = new ArrayList<...>();

add something to list but never use InternalThreadLocalMap

return list.toArray(new ...[list.size()]);

```

Modifications:

Add a reusable ArrayList to InternalThreadLocalMap and update codes to use it.

Result:

Reuse a thread local ArrayList to avoid allocations.
2016-02-01 15:49:28 +01:00
liuzhengyang
b354868dd8 Fix spelling in javadocs and field name.
Motivation:

Fix a spell mistake.

Modifications:

Change 'treshold' to 'threshold'

Result:

The spellchecker warnings of the IDE disappeared.
2016-02-01 12:03:14 +01:00
liuzhengyang
2a9d392a31 Motivation:
Fix a spell mistake.

Modifications:

Change 'treshold' to 'threshold'

Result:

The spellchecker warnings of the IDE disappeared.
2016-02-01 12:03:06 +01:00
Norman Maurer
a2732c6542 [#4755] Make WebSocketClientCompressionHandler @Sharable
Motivation:

WebSocketClientCompressionHandler is stateless so it should be @Sharable.

Modifications:

Add @Sharable annotation to WebSocketClientCompressionHandler, make constructor private and add static field to get the instance.

Result:

Less object creation.
2016-01-28 10:28:09 +01:00
houdejun214
a6fd8a96bf Set default CONTENT_TYPE when it is absent in multipart request body
Motivation:

I am use netty as a http server, it fail to decode some POST request when the request absent Content-Type in the multipart/form-data body.

Modifications:

Set content_type with default application/octet-stream to parse the uploaded file data when the Content-Type is absent in multipart request body

Result:

Can decode the http request as normal.
2016-01-26 10:47:11 +01:00
Norman Maurer
e969b6917c Let CombinedChannelDuplexHandler correctly handle exceptionCaught. Related to [#4528]
Motivation:

ChannelInboundHandler and ChannelOutboundHandler both can implement exceptionCaught(...) method and so we need to dispatch to both of them.

Modifications:

- Correctly first dispatch exceptionCaught to the ChannelInboundHandler but also make sure the next handler it will be dispatched to will be the ChannelOutboundHandler
- Add removeInboundHandler() and removeOutboundHandler() which allows to remove one of the combined handlers
- Let *Codec extends it and not ChannelHandlerAppender
- Remove ChannelHandlerAppender

Result:

Correctly handle events and also have same behavior as in 4.0
2016-01-18 09:54:48 +01:00
Xiaoyan Lin
9ae155d257 Fix InternalAttribute.equals
Motivation:

InternalAttribute doesn't extend Attribute, but its equals only returns true when it compares with an Attribute. So it will return false when comparing with itself.

Modifications:

Make sure InternalAttribute return false for non InternalAttribute objects.

Result:

InternalAttribute's equals works correctly.
2016-01-11 09:25:17 +01:00
Xiaoyan Lin
751ed6cc94 Avoid unnecessary boxing/unboxing
Motivation:

Boxing/unboxing can be avoided.

Modifications:

Use parseInt/parseLong to avoid unnecessary boxing/unboxing.

Result:

Remove unnecessary boxing/unboxing.
2016-01-08 17:38:20 +01:00
Fabian Lange
619d82b56f Removed unused imports
Motivation:

Warnings in IDE, unclean code, negligible performance impact.

Modification:

Deletion of unused imports

Result:

No more warnings in IDE, cleaner code, negligible performance improvement.
2016-01-04 14:32:29 +01:00
Norman Maurer
8dc164ace6 Correctly reset MessageDigest before reusing it.
Motivation:

I missed to reset the MessageDigest before reusing it. This bug was introduced by 79634e661b.

Modifications:

Call reset() on the MessageDigest.

Result:

Correctly reset MessageDigest before re-using
2016-01-04 14:29:21 +01:00
Xiaoyan Lin
1b0adb334b Fix incorrect Serializable
Motivation:

SpdySession.StreamComparator should not be Serializable since SpdySession is not Serializable

Modifications:

Remove Serializable fom SpdySession.StreamComparator

Result:

StreamComparator is not Serializable any more
2015-12-31 22:28:32 +01:00
Alex Petrov
78c4bd474e IllealRefCountException should be IllegalReferenceCountException, fix typos
Motivation:

Typos in javadoc, in "combine" and "recommendations", IllegalReferenceCountException

Modification:

Rename incorrect reference, typos are modified

Result:

Reference is correct, typos are fixed
2015-12-31 19:03:27 +01:00
Norman Maurer
8716b9d4bd Revert "Fix unnecessary boxing and incorrect Serializable"
This reverts commit 0ae6f17285.
2015-12-31 14:48:10 +01:00
Norman Maurer
79634e661b Obtain MessageDigest via FastThreadLocal
Motivation:

Creating a new MessageDigest every time is wasteful, we should store them in FastThreadLocal.

Modifications:

Change WebSocketUtil to store MD5 and SHA1 MessageDigest in FastThreadLocal and use these.

Result:

Less overhead and less GC.
2015-12-31 11:30:47 +01:00
Xiaoyan Lin
0ae6f17285 Fix unnecessary boxing and incorrect Serializable
Motivation:

- AbstractHttp2ConnectionHandlerBuilder.encoderEnforceMaxConcurrentStreams can be the primitive boolean
- SpdySession.StreamComparator should not be Serializable since SpdySession is not Serializable

Modifications:

Use boolean instead and remove Serializable

Result:

- Minor improvement for AbstractHttp2ConnectionHandlerBuilder
- StreamComparator is not Serializable any more
2015-12-31 10:45:24 +01:00
Alex Petrov
0b16c3c513 Add a possibility to create HttpMessage instances with pre-existing Headers
Motivation:

Allow passing HttpHeaders instance to DefaultHttpMessage
in order to avoid eager creation of Headers to
allow users reuse their Headers instance.

Modifications:

Added a constructor with HttpHeaders to DefaultHttpMessage,
Modified DefaultHttpResponse and DefaultHttpRequest
to receive HttpHeaders instances.
Modified DefaultFullHttpReqest and DefaultFullHttpResponse
to receive HttpHeaders, and updated `duplicate` and
`copy` to use new constructors.

Result:

Users can now pass HttpHeaders instance when
constructing Http Requests and Responses.
2015-12-31 08:52:30 +01:00
Norman Maurer
79bc90be32 Fix buffer leak introduced by 693633eeff
Motivation:

As we not used Unpooled anymore for allocate buffers in Base64.* methods we need to ensure we realease all the buffers.

Modifications:

Correctly release buffers

Result:

No more buffer leaks
2015-12-29 17:13:07 +01:00
Xiaoyan Lin
475d901131 Fix errors reported by javadoc
Motivation:

Javadoc reports errors about invalid docs.

Modifications:

Fix some errors reported by javadoc.

Result:

A lot of javadoc errors are fixed by this patch.
2015-12-27 08:36:45 +01:00
Xiaoyan Lin
a96d52fe66 Fix javadoc links and tags
Motivation:

There are some wrong links and tags in javadoc.

Modifications:

Fix the wrong links and tags in javadoc.

Result:

These links will work correctly in javadoc.
2015-12-26 08:34:31 +01:00
Scott Mitchell
fd5316ed6f ChunkedInput.readChunk parameter of type ByteBufAllocator
Motivation:
ChunkedInput.readChunk currently takes a ChannelHandlerContext object as a parameters. All current implementations of this interface only use this object to get the ByteBufAllocator object. Thus taking a ChannelHandlerContext as a parameter is more restrictive for users of this API than necessary.

Modifications:
- Add a new method readChunk(ByteBufAllocator)
- Deprecate readChunk(ChannelHandlerContext) and updates all implementations to call readChunk(ByteBufAllocator)

Result:
API that only requires ByteBufAllocator to use ChunkedInput.
2015-12-24 12:46:40 -08:00
Shixiong Zhu
b5d90388ea Fix HttpHeaderValues.IDENTITY equals usage
Motivation:

HttpHeaderValues.IDENTITY is an AsciiString, but was compared using equals to a String.

Modifications:

Use contentEquals instead.

Result:
Correct comparison.
2015-12-22 09:05:27 +01:00
Norman Maurer
1a2162ec35 Fix broken tests introduced by dc615ecaaf 2015-12-18 10:16:07 +01:00
Norman Maurer
dc615ecaaf [#4212] Backport WebSocket Extension handlers for client and server.
Motivation:

We have websocket extension support (with compression) in old master. We should port this to 4.1

Modifications:

Backport relevant code.

Result:

websocket extension support (with compression) is now in 4.1.
2015-12-18 09:48:10 +01:00
Trustin Lee
412f719aa8 Extract the builder of CorsConfig to top level
Motivation:

Consistency in API design

Modifications:

- Deprecate CorsConfig.Builder and its factory methods
- Deprecate CorsConfig.DateValueGenerator
- Add CorsConfigBuilder and its factory methods
- Fix typo (curcuit -> circuit)

Result:

Consistency with other builder APIs such as SslContextBuilder and
Http2ConnectionHandlerBuilder
2015-12-18 12:38:44 +09:00
Norman Maurer
f31be51774 [#4505] Correctly handle whitespaces in websocket uri's.
Motivation:

If a uri contains whitespaces we need to ensure we correctly escape these when creating the request for the handshake.

Modifications:

- Correctly encode path for uri
- Add tests

Result:

Correctly handle whitespaces when doing websocket upgrade requests.
2015-12-10 13:52:42 +01:00
Trustin Lee
c1f3200c87 Fix the incorrect usage/value of 'Connection: upgrade'
Motivation:

HttpClientUpgradeHandler uses HttpHeaderNames.UPGRADE as the value of
the 'Connection' header, which is incorrect. It should use
HttpHeaderValues.UPGRADE instead (note Names vs Values.)

Also, HttpHeaderValues.UPGRADE should be 'upgrade' rather than
'Upgrade', as defined in:

- https://tools.ietf.org/html/rfc7230#section-6.7

Modifications:

- Use HttpHeaderValues.UPGRADE for a 'Connection' header
- Lowercase the value of HttpHeaderValues.UPGRADE

Result:

- Fixes #4508
- Correct behavior
2015-11-29 07:22:53 +01:00