Commit Graph

822 Commits

Author SHA1 Message Date
Frederic Bregier
50315f28c2 Fix for Issue #3308 related to slice missing retain
Motivations:
It seems that slicing a buffer and using this slice to write to CTX will
decrease the initial refCnt to 0, while the original buffer is not yet
fully used (not empty).

Modifications:
As suggested in the ticket and tested, when the currentBuffer is sliced
since it will still be used later on, the currentBuffer is retained.

Add a test case for this issue.

Result:
The currentBuffer still has its correct refCnt when reaching the last
write (not sliced) of 1 and therefore will be released correctly.
The exception does no more occur.

This fix should be applied to all branches >= 4.0.
2015-01-06 21:04:08 +01:00
Trustin Lee
4c258a8828 Fix a compilation error
Thanks to @jknair
2014-12-31 21:42:08 +09:00
Trustin Lee
24c6b599c4 Make sure AggregatedFullHttpMessage.trailingHeaders() return non-null
When handling an oversized message, HttpObjectAggregator does not wait
until the last chunk is received to produce the failed message, making
AggregatedFullHttpMessage.trailingHeaders() return null.
2014-12-31 19:26:44 +09:00
Trustin Lee
befe4ca2e3 Implement toString() for all HttpMessage implementations
Related: #3019

Motivation:

We have multiple (Full)HttpRequest/Response implementations and only
some of them implements toString() properly.

Modifications:

- Add the reusable string converter for HttpMessages to HttpMessageUtil
- Implement toString() of (Full)HttpRequest/Response implementations
  properly using HttpMessageUtil

Result:

Prettier string representation is returned by HttpMessage
implementations.
2014-12-31 18:32:48 +09:00
Norman Maurer
1ed8a120c1 Allow to override how headers are encoded
Motivation:

Even if its against the HTTP RFC there are situations where it may be useful to use other chars then US_ASCII in the headers. We should allow to make it possible by allow the user to override the how headers are encoded.

Modifications:

- Add encodeHeaders(...) method and so allow to override it.

Result:

It's now possible to encode headers with other charset then US_ASCII by just extend the encoder and override the encodeHeaders(...) method.
2014-12-26 15:17:35 +01:00
Scott Mitchell
19f6b420a9 Headers set/add timeMillis for master branch
Motivation:
Commit eb0e127ee9 was designed for the 4.1 branch.  The 5.0 branch had a few additional classes which required updates to get the new timeMillis methods for all the header classes.

Modifications:
Update the *Headers interfaces/classes that were not updated in the 4.1 branch.

Result:
All *Headers interfaces support set/add timeMillis methods.
2014-12-26 16:01:41 +09:00
Jeff Beck
20f5974f01 HttpObjectAggregator only set Content-Length is not already set.
Motivation:

HEAD requests will have a Content-Length set that doesn't match the
actual length. So we only want to set Content-Length header if it isn't
already set.

Modifications:

If check around setting the Content-Length.

Result:

A HEAD request will no correctly return the specified Content-Length
instead of the body length.
2014-12-25 20:44:47 +01:00
Leonardo Freitas Gomes
75aa8475e1 Motivation: Sonar points out an equals comparison, where the types compared are different and don't share any common parent http://clinker.netty.io/sonar/drilldown/issues/io.netty:netty-parent:master?severity=CRITICAL#
Modifications:
Converted AsciiString into a String by calling toString() method before comparing with equals(). Also added a unit-test to show that it works.

Result:
Major violation is gone. Code is correct.
2014-12-16 06:59:48 +01:00
zcourts
a7a1b8e561 ensure getRawQuery is not null before appending
Motivation:

without this check then given a URI with path /path the resulting URL will be /path?null=

Modifications:

check that getRawQuery doesn't return null and only append if not

Result:

urls of the form /path will not have a null?= appended
2014-12-16 06:39:28 +01:00
Norman Maurer
99a703be88 Revert "Suppress channelReadComplete until MessageAggregator completes aggregating a message. https://github.com/netty/netty/issues/3168"
This reverts commit cb95a1331d.
2014-12-13 09:19:04 +01:00
Sam Young
cb95a1331d Suppress channelReadComplete until MessageAggregator completes aggregating a message. https://github.com/netty/netty/issues/3168
Motivation:
This fixes issue 3168 where HttpObjectAggregator does not suppress
channelReadComplete() when aggregation is not yet finished.

Modifications:
Ignore channelReadComplete until a message completes aggregation.
MessageAggregator currently tracks the currentMessage being aggregated.
This variable transitions to non-null when aggregation begins and back
to null when aggregation completes or fails. When the currentMessage is
null, it is safe to issue a channelReadComplete because the
corresponding channelRead will have completed aggregation.

Result:
channelReadComplete will only fire one time on each completed message
aggregation.
2014-12-13 07:58:19 +01:00
Frederic Bregier
cb6646da13 Fix AbstractDiskHttpData int conversion from long
Motivations:
The chunkSize might be oversized after comparison (size being > of int
capacity) if file size is bigger than an integer.

Modifications:
Change it to long.

Result:
There is no more int oversized.

Same fix for 4.1 and Master
2014-12-08 07:18:09 +01:00
Scott Mitchell
eb0e127ee9 Headers set/add/contains timeMillis methods
Motivation:
The new Headers interface contains methods to getTimeMillis but no add/set/contains variants.  These should be added for consistency.

Modifications:
- Add three new methods: addTimeMillis, setTimeMillis, containsTimeMillis to the Headers interface.
- Add a new method to the Headers.ValueConverter interface: T convertTimeMillis(long)
- Bring these new interfaces up the class hierarchy

Result:
All Headers classes have setters/getters for timeMillis.
2014-12-06 22:40:45 +09:00
Trustin Lee
97bf8a6d61 Change the type of HTTP string properties to AsciiString
Related: #3132

Motivation:

Changing the type of the string properties of HttpVersion and
HttpResponseStatus to AsciiString will give us the performance advantage
when encoding it into the wire.

Modifications:

- Change the type of the following properties to AsciiString:
  - HttpVersion.protocolName()
  - HttpVersion.text()
  - HttpResponseStatus.reasonPhrase()
- Inline their respective encode() methods because they are used only in
  the encoders.
- Fix the test failures incurred by the changes above

Result:

Getting close to the machine
2014-12-06 18:42:58 +09:00
Trustin Lee
377ef31bb1 Change the type of HttpMethod.name() to AsciiString
Related: #3132

Motivation:

Changing the type of HttpMethod.name() gives us the performance
advantage when encoding it into the wire.

Modifications:

- Change the type of HttpMethod.name()
- Inline HttpMethod.encode() because it's used only in a single place
  and it's trivial.

Result:

Getting close to the machine
2014-12-06 18:09:27 +09:00
Scott Mitchell
a8e5fb12fa HTTP/2 Draft 15
Motivation:
A new draft of the HTTP/2 spec has been released.

Modifications:
Make updates as defined in https://tools.ietf.org/html/draft-ietf-httpbis-http2-15

Result:
HTTP/2 codec is draft 15 compliant.
2014-11-23 13:00:00 -05:00
Scott Mitchell
95540bd49e HTTP Client Upgrade Handler Compare Issue
Motivation:
The HttpClientUpgradeHandler attempts to compare a supported codec against the input codec but the comparison logic is reversed.

Modification:
Negate the logic in HttpClientUpgradeHandler so an error is detected in the error condition.

Result:
HttpClientUpgradeHandler should not fail the upgrade when the input protocol is valid.
2014-11-22 15:55:24 +01:00
Trustin Lee
87537ce397 Add HttpStatusClass
Related: #3157

Motivation:

It should be convenient to have an easy way to classify an
HttpResponseStatus based on the first digit of the HTTP status code, as
defined in the RFC 2616:

- Information 1xx
- Success 2xx
- Redirection 3xx
- Client Error 4xx
- Server Error 5xx

Modification:

- Add HttpStatusClass
- Add HttpResponseStatus.codeClass() that returns the class of the HTTP
  status code
- Remove HttpResponseStatus.isInformational()

Result:

It's easier to determine the class of an HTTP status
2014-11-21 10:54:52 +09:00
Trustin Lee
5f8483646b Clean up 000d3a55c5
- Rename httpResponseStatus() to newStatus()
  - Move newStatus up so that static methods are grouped together
- Rename codeAsString to codeAsText
2014-11-20 19:08:16 +09:00
Daniel Bevenius
000d3a55c5 Adding codeAsText to HttpResponseStatus.
Motivation:
I found myself writing AsciiString constants in my code for
response statuses and thought that perhaps it might be nice to have
them defined by Netty instead.

Modifications:
Adding codeAsText to HttpResponseStatus that returns the status code as
AsciiText.

In addition, added the 421 Misdirected Request response code from
https://tools.ietf.org/html/draft-ietf-httpbis-http2-15#section-9.1.2

This response header was renamed in draft 15:
https://tools.ietf.org/html/draft-ietf-httpbis-http2-15#appendix-A.1
But the code itself was not changed, and I thought using the latest would
be better.

Result:
It is now possible to specify a status like this:
new DefaultHttp2Headers().status(HttpResponseStatus.OK.codeAsText());
2014-11-20 19:05:46 +09:00
Idel Pivnitskiy
9465db25ba Small performance improvements
Motivation:

Found performance issues via FindBugs and PMD.

Modifications:

- Removed unnecessary boxing/unboxing operations in DefaultTextHeaders.convertToInt(CharSequence) and DefaultTextHeaders.convertToLong(CharSequence). A boxed primitive is created from a string, just to extract the unboxed primitive value.
- Added a static modifier for DefaultHttp2Connection.ParentChangedEvent class. This class is an inner class, but does not use its embedded reference to the object which created it. This reference makes the instances of the class larger, and may keep the reference to the creator object alive longer than necessary.
- Added a static compiled Pattern to avoid compile it each time it is used when we need to replace some part of authority.
- Improved using of StringBuilders.

Result:

Performance improvements.
2014-11-19 23:44:25 -05:00
Jeff Pinner
3868645d7d SPDY: add support for pushed resources in SpdyHttpDecoder
Motivation:

The SPDY/3.1 spec does not adequate describe how to push resources
from the server. This was solidified in the HTTP/2 drafts by dividing
the push into two frames, a PushPromise containing the request,
followed by a Headers frame containing the response.

Modifications:

This commit modifies the SpdyHttpDecoder to support pushed resources
that are divided into multiple frames. The decoder will accept a
pushed SpdySynStreamFrame containing the request headers, followed by
a SpdyHeadersFrame containing the response headers.

Result:

The SpdyHttpDecoder will create an HttpRequest object followed by an
HttpResponse object when receiving pushed resources.
2014-11-15 21:47:43 +01:00
Roelof Naude
d220afa885 Cater for empty response bodies when performing response compression.
Motivation:
RFC 2616, 4.3 Message Body states that:
All 1xx (informational), 204 (no content), and 304 (not modified) responses MUST NOT include a
message-body. All other responses do include a message-body, although it MAY be of zero length.

Modifications:
HttpContentEncoder was previously modified to cater for HTTP 100 responses. This check is enhanced to
include HTTP 204 and 304 responses.

Result:
Empty response bodies will not be modified to include the compression footer. This footer messed with Chrome's
response parsing leading to "hanging" requests.
2014-11-13 08:02:54 +01:00
Idel Pivnitskiy
b2ca2148f9 Rewrite HttpObjectDecoder to make use of proper state machine
Motivation:

HttpObjectDecoder extended ReplayDecoder which is slightly slower then ByteToMessageDecoder.

Modifications:

- Changed super class of HttpObjectDecoder from ReplayDecoder to ByteToMessageDecoder.
- Rewrote decode() method of HttpObjectDecoder to use proper state machine.
- Changed private methods HeaderParser.parse(ByteBuf), readHeaders(ByteBuf) and readTrailingHeaders(ByteBuf), skipControlCharacters(ByteBuf) to consider available bytes.
- Set HeaderParser and LineParser as static inner classes.
- Replaced not safe actualReadableBytes() with buffer.readableBytes().

Result:

Improved performance of HttpObjectDecoder by approximately 177%.
2014-11-12 14:20:38 +01:00
Scott Mitchell
685075f1a0 HTTP/2 Data Compressor
Motivation:
The HTTP/2 codec currently does not provide an interface to compress data. There is an analogous case to this in the HTTP codec and it is expected to be used commonly enough that it will be beneficial to have the feature in the http2-codec.

Modifications:
- Add a class which extends DefaultHttp2ConnectionEncoder and provides hooks to an EmbeddedChannel
- Add a compressor element to the Http2Stream interface
- Update unit tests to utilize the new feature

Result:
HTTP/2 codec supports data compression.
2014-11-06 14:45:05 -05:00
Scott Mitchell
b33901c5a6 HTTP Content Encoder allow EmptyLastHttpContent
Motiviation:
The HttpContentEncoder does not account for a EmptyLastHttpContent being provided as input.  This is useful in situations where the client is unable to determine if the current content chunk is the last content chunk (i.e. a proxy forwarding content when transfer encoding is chunked).

Modifications:
- HttpContentEncoder should not attempt to compress empty HttpContent objects

Result:
HttpContentEncoder supports a EmptyLastHttpContent to terminate the response.
2014-11-05 23:32:26 -05:00
Trustin Lee
ceb06dc1b1 Remove non-standard header values from HttpHeaderValues
Motivation:

x-gzip and x-deflate are not standard header values, and thus should be
removed from HttpHeaderValues, which is meant to provide the standard
values only.

Modifications:

- Remove X_DEFLATE and X_GZIP from HttpHeaderValues
- Move X_DEFLATE and X_GZIP to HttpContentDecompressor and
  DelegatingDecompressorFrameListener
  - We have slight code duplication here, but it does less harm than
    having non-standard constant.

Result:

HttpHeaderValues contains only standard header values.
2014-11-01 02:51:34 +09:00
Trustin Lee
f793f395d6 Replace HttpHeaders.Names/Values with HttpHeaderNames/Values
Related: 4ce994dd4f

Motivation:

In 4.1, we were not able to change the type of the HTTP header name and
value constants from String to AsciiString due to backward compatibility
reasons.

Instead of breaking backward compatibility in 4.1, we introduced new
types called HttpHeaderNames and HttpHeaderValues which provides the
AsciiString version of the constants, and then deprecated
HttpHeaders.Names/Values.

We should make the same changes while deleting the deprecated classes
activaly.

Modifications:

- Remove HttpHeaders.Names/Values and RtspHeaders
- Add HttpHeaderNames/Values and RtspHeaderNames/Values
  - Make HttpHeaderValues.WEBSOCKET lowercased because it's actually
    lowercased in all WebSocket versions but the oldest one
- Do not use AsciiString.equalsIgnoreCase(CharSeq, CharSeq) if one of
  the parameters are AsciiString
  - Avoid using AsciiString.toString() repetitively
    - Change the parameter type of some methods from String to
      CharSequence

Result:

A user who upgraded from 4.0 to 4.1 first and removed the references to
the deprecated classes and methods can easily upgrade from 4.1 to 5.0.
2014-11-01 02:41:56 +09:00
Matthias Einwag
82461f0511 Added an option to use websockets without masking
Motivation:

The requirement for the masking of frames and for checks of correct
masking in the websocket specifiation have a large impact on performance.
While it is mandatory for browsers to use masking there are other
applications (like IPC protocols) that want to user websocket framing and proxy-traversing
characteristics without the overhead of masking. The websocket standard
also mentions that the requirement for mask verification on server side
might be dropped in future.

Modifications:

Added an optional parameter allowMaskMismatch for the websocket decoder
that allows a server to also accept unmasked frames (and clients to accept
masked frames).
Allowed to set this option through the websocket handshaker
constructors as well as the websocket client and server handlers.
The public API for existing components doesn't change, it will be
forwarded to functions which implicetly set masking as required in the
specification.
For websocket clients an additional parameter is added that allows to
disable the masking of frames that are sent by the client.

Result:

This update gives netty users the ability to create and use completely
unmasked websocket connections in addition to the normal masked channels
that the standard describes.
2014-10-25 22:17:41 +09:00
Trustin Lee
a63723b006 Fix a compilation error 2014-10-25 17:11:46 +09:00
Trustin Lee
1be42ca6e4 Overall cleanup of 2b191fe6e9 2014-10-25 16:59:41 +09:00
Norman Maurer
2b191fe6e9 Modify HttpObjectDecoder to allow parsing the HTTP headers in multiple steps.
Motivation:
At the moment the whole HTTP header must be parsed at once which can lead to multiple parsing of the same bytes. We can do better here and allow to parse it in multiple steps.

Modifications:

 - Not parse headers multiple times
 - Simplify the code
 - Eliminate uncessary String[] creations
 - Use readSlice(...).retain() when possible.

Result:

Performance improvements as shown in the included benchmark below.

Before change:
[nmaurer@xxx]~% ./wrk-benchmark
Running 2m test @ http://xxx:8080/plaintext
  16 threads and 256 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    21.55ms   15.10ms 245.02ms   90.26%
    Req/Sec   196.33k    30.17k  297.29k    76.03%
  373954750 requests in 2.00m, 50.15GB read
Requests/sec: 3116466.08
Transfer/sec:    427.98MB

After change:
[nmaurer@xxx]~% ./wrk-benchmark
Running 2m test @ http://xxx:8080/plaintext
  16 threads and 256 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    20.91ms   36.79ms   1.26s    98.24%
    Req/Sec   206.67k    21.69k  243.62k    94.96%
  393071191 requests in 2.00m, 52.71GB read
Requests/sec: 3275971.50
Transfer/sec:    449.89MB
2014-10-25 16:59:31 +09:00
George Agnelli
ac882d56e9 Don't close the connection whenever Expect: 100-continue is missing.
Motivation:

The 4.1.0-Beta3 implementation of HttpObjectAggregator.handleOversizedMessage closes the
connection if the client sent oversized chunked data with no Expect:
100-continue header. This causes a broken pipe or "connection reset by
peer" error in some clients (tested on Firefox 31 OS X 10.9.5,
async-http-client 1.8.14).

This part of the HTTP 1.1 spec (below) seems to say that in this scenario the connection
should not be closed (unless the intention is to be very strict about
how data should be sent).

http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html

"If an origin server receives a request that does not include an
Expect request-header field with the "100-continue" expectation,
the request includes a request body, and the server responds
with a final status code before reading the entire request body
from the transport connection, then the server SHOULD NOT close
the transport connection until it has read the entire request,
or until the client closes the connection. Otherwise, the client
might not reliably receive the response message. However, this
requirement is not be construed as preventing a server from
defending itself against denial-of-service attacks, or from
badly broken client implementations."

Modifications:

Change HttpObjectAggregator.handleOversizedMessage to close the
connection only if keep-alive is off and Expect: 100-continue is
missing. Update test to reflect the change.

Result:

Broken pipe and connection reset errors on the client are avoided when
oversized data is sent.
2014-10-24 21:49:39 +02:00
Trustin Lee
36b41570a4 Overall clean-up on Headers and its subtypes
Motivation:

- There are still various inspector warnings to fix.
- ValueConverter.convert() methods need to end with the type name like
  other methods in Headers, such as setInt() and addInt(), for more
  consistency

Modifications:

- Fix all inspector warnings
- Rename ValueConverter.convert() to convert<type>()

Result:

- Cleaner code
- Consistency
2014-10-22 15:08:12 +09:00
Trustin Lee
a1d7a84271 Handle an empty ByteBuf specially in HttpObjectEncoder
Related: #2983

Motivation:

It is a well known idiom to write an empty buffer and add a listener to
its future to close a channel when the last byte has been written out:

  ChannelFuture f = channel.writeAndFlush(Unpooled.EMPTY_BUFFER);
  f.addListener(ChannelFutureListener.CLOSE);

When HttpObjectEncoder is in the pipeline, this still works, but it
silently raises an IllegalStateException, because HttpObjectEncoder does
not allow writing a ByteBuf when it is expecting an HttpMessage.

Modifications:

- Handle an empty ByteBuf specially in HttpObjectEncoder, so that
  writing an empty buffer does not fail even if the pipeline contains an
  HttpObjectEncoder
- Add a test

Result:

An exception is not triggered anymore by HttpObjectEncoder, when a user
attempts to write an empty buffer.
2014-10-22 14:46:44 +09:00
Daniel Bevenius
b4604cdbbc CorsHandler should release HttpRequest after processing preflight/error.
Motivation:
Currently, when the CorsHandler processes a preflight request, or
respondes with an 403 Forbidden using the short-curcuit option, the
HttpRequest is not released which leads to a buffer leak.

Modifications:
Releasing the HttpRequest when done processing a preflight request or
responding with an 403.

Result:
Using the CorsHandler will not cause buffer leaks.
2014-10-22 06:36:52 +02:00
Scott Mitchell
2374e17c6e Netty Headers Class Restructure and Algorithm Updates
Motivation:
Headers within netty do not cleanly share a common class hierarchy.  As a result some header types support some operations
and don't support others.  The consolidation of the class hierarchy will allow for maintenance and scalability for new codec.
The existing hierarchy also has a few short comings such as it is not clear when data conversions are happening.  This
could result unintentionally getting back a collection or iterator where a conversion on each entry must happen.

The current headers algorithm also prepends all elements which means to find the first element or return a collection
in insertion order often requires a complete traversal followed by a collections.reverse call.

Modifications:
-Provide a generic base class which provides all the implementation for headers in netty
-Provide an extension to this class which allows for name type conversions to happen (to accommodate legacy CharSequence to String conversions)
-Update the headers interface to clarify when conversions will happen.
-Update the headers data structure so that appends are done to avoid unnecessary iteration or collection reversal.

Result:
-More unified class hierarchy for headers in netty
-Improved headers data structure and algorithms
-headers API more clearly identify when conversions are required.
2014-10-21 13:04:08 -04:00
Frederic Bregier
d6e7997f8d Master - Fix "=" character in HttpPostRequestDecoder
Motivation
Issue #3004 shows that "=" character was not supported as it should in
the HttpPostRequestDecoder in form-data boundary.

Modifications:
Add 2 methods in StringUtil

split with maxParts: String split with a max parts only (to prevent multiple '=' to
be source of extra split while not needed)
substringAfter: String part after delimiter (since first part is not needed)
Use those methods in HttpPostRequestDecoder. Change and the
HttpPostRequestDecoderTest to check using a boundary beginning with "=".

Results:
The fix implies more stability and fix the issue.
2014-10-18 01:14:28 +02:00
Trustin Lee
de9c81bf6e Add proxy support for client socket connections
Related issue: #1133

Motivation:

There is no support for client socket connections via a proxy server in
Netty.

Modifications:

- Add a new module 'handler-proxy'
- Add ProxyHandler and its subclasses to support SOCKS 4a/5 and HTTP(S)
  proxy connections
- Add a full parameterized test for most scenarios
- Clean up pom.xml

Result:

A user can make an outgoing connection via proxy servers with only
trivial effort.
2014-10-14 12:40:33 +09:00
Trustin Lee
9c125eecb1 Add the encoder/decoder getter methods to HttpClientCodec
Motivation:

There's no way for a user to get the encoder and the decoder of an
HttpClientCodec.  The lack of such getter methods makes it impossible to
remove the codec handlers from the pipeline correctly.

For example, a user could add more than one HttpClientCodec to the
pipeline, and then the user cannot easily decide which encoder and
decoder to remove.

Modifications:

- Add encoder() and decoder() method to HttpClientCodec which returns
  HttpRequestEncoder and HttpResponseDecoder respectively
- Also made the same changes to HttpServerCodec

Result:

A user can distinguish the handlers added by multiple HttpClientCodecs
easily.
2014-10-14 12:33:44 +09:00
Matthias Einwag
a82508d422 Add verification for websocket subprotocol on the client side.
Motivation:

Websocket clients can request to speak a specific subprotocol. The list of
subprotocols the client understands are sent to the server. The server
should select one of the protocols an reply this with the websocket
handshake response. The added code verifies that the reponded subprotocol
is valid.

Modifications:

Added verification of the subprotocol received from the server against the
subprotocol(s) that the user requests. If the user requests a subprotocol
but the server responds none or a non-requested subprotocol this is an
error and the handshake fails through an exception. If the user requests
no subprotocol but the server responds one this is also marked as an
error.

Addiontionally a getter for the WebSocketClientHandshaker in the
WebSocketClientProtocolHandler is added to enable the user of a
WebSocketClientProtocolHandler to extract the used negotiated subprotocol.

Result:

The subprotocol field which is received from a websocket server is now
properly verified on client side and clients and websocket connection
attempts will now only succeed if both parties can negotiate on a
subprotocol.
If the client sends a list of multiple possible subprotocols it can
extract the negotiated subprotocol through the added handshaker getter (WebSocketClientProtocolHandler.handshaker().actualSubprotocol()).
2014-10-13 07:31:23 +02:00
Matthias Einwag
9dd8e19376 Add a test for handover from HTTP to Websocket
Motivation:
I was not fully reassured that whether everything works correctly when a websocket client receives the websocket handshake HTTP response and a websocket frame in a single ByteBuf (which can happen when the server sends a response directly or shortly after the connect). In this case some parts of the ByteBuf must be processed by HTTP decoder and the remaining by the websocket decoder.

Modification:
Adding a test that verifies that in this scenaria the handshake and the message are correctly interpreted and delivered by Netty.

Result:
One more test for Netty.
The test succeeds - No problems
2014-10-13 07:19:12 +02:00
Matthias Einwag
30db808d0f Fix the leak in the WebSocketClientProtocolHandshakeHandler
Motivation:
The WebSocketClientProtocolHandshakeHandler never releases the received handshake response.

Modification:
Release the message in a finally block.

Result:
No more leak
2014-10-12 20:25:52 +02:00
Matthias Einwag
b9e507c9cc Avoid vectored writes for small websocket messages
Motivation:
The WebSocket08FrameEncoder contains an optimization path for small messages which copies the message content into the header buffer to avoid vectored writes. However this path is in the current implementation never taken because the target buffer is preallocated only for exactly the size of the header.

Modification:
For messages below a certain treshold allocate the buffer so that the message can be directly copied. Thereby the optimized path is taken.

Result:
A speedup of about 25% for 100byte messages. Declines with bigger message sizes. I have currently set the treshold to 1kB which is a point where I could still see a few percent speedup, but we should also avoid burning too many CPU cycles.
2014-10-12 20:12:18 +02:00
Matthias Einwag
301f18c793 Improve WebSocket performance
Motivation:

Websocket performance is to a large account determined through the masking
and unmasking of frames. The current behavior of this in Netty can be
improved.

Modifications:

Perform the XOR operation not bytewise but in int blocks as long as
possible. This reduces the number of necessary operations by 4. Also don't
read the writerIndex in each iteration.
Added a unit test for websocket decoding and encoding for verifiation.

Result:

A large performance gain (up to 50%) in websocket throughput.
2014-10-12 19:54:07 +02:00
Matthias Einwag
2a5adc0b2b Send a websocket close frame with status code when receiving invalid frames
Motivation:

According to the websocket specification peers may send a close frame when
they detect a protocol violation (with status code 1002). The current
implementation simply closes the connection. This update should add this
functionality. The functionality is optional - but it might help other
implementations with debugging when they receive such a frame.

Modification:

When a protocol violation in the decoder is detected and a close was not
already initiated by the remote peer a close frame is
sent.

Result:

Remotes which will send an invalid frame will now get a close frame that
indicates the protocol violation instead of only seeing a closed
connection.
2014-09-29 20:05:09 +02:00
Norman Maurer
ae8493a567 Allow to access uri of QueryStringDecoder. Related to [#2896]
Motivation:

Sometimes it is useful to be able to access the uri that was used to initialize the QueryStringDecoder.

Modifications:

Add method which allows to retrieve the uri.

Result:

Allow to retrieve the uri that was used to create the QueryStringDecoder.
2014-09-19 20:08:32 +02:00
Scott Mitchell
96a044fabe HTTP/2 Data Decompression
Motivation:
The HTTP/2 codec does not provide a way to decompress data. This functionality is supported by the HTTP codec and is expected to be a commonly used feature.

Modifications:
-The Http2FrameReader will be modified to allow hooks for decompression
-New classes which detect the decompression from HTTP/2 header frames and uses that decompression when HTTP/2 data frames come in
-New unit tests

Result:
The HTTP/2 codec will provide a means to support data decompression
2014-09-14 08:43:13 -04:00
Scott Mitchell
9b811a24e8 Correcting HttpDecoder SuppressWarnings parameter
Motiviation:
The HttpContentDecoder.getTargetContentEncoding has a SuppressWarnings(unused) on its parameter.
This should be SuppressWarnings(UnusedParameters).

Modifications:
SuppressWarnings(unused) -> SuppressWarnings(UnusedParameters)

Result:
Correctly suppressing warnings due to HttpContentDecoder.getTargetContentEncoding
2014-09-12 07:25:25 +02:00
Scott Mitchell
6c148456ba HTTP Content Decoder Cleanup Bug
Motiviation:
The HTTP content decoder's cleanup method is not cleaning up the decoder correctly.
The cleanup method is currently doing a readOutbound on the EmbeddedChannel but
for decoding the call should be readInbound.

Modifications:
-Change readOutbound to readInbound in the cleanup method

Result:
The cleanup method should be correctly releaseing unused resources
2014-09-10 08:48:10 -04:00