Commit Graph

864 Commits

Author SHA1 Message Date
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
Norman Maurer
a765753ae6 [#2847] Correctly encode HTTP to SPDY if X-SPDY-Associated-To-Stream-ID is not present
Motivation:

Because of a bug a NPE was thrown when tried to encode HTTP to SPDY and no X-SPDY-Associated-To-Stream-ID was present.

Modifications:

Use 0 as default value when X-SPDY-Associated-To-Stream-ID not present.

Result:

No NPE anymore.
2014-08-31 21:08:25 +02:00
Scott Mitchell
63d5925d6e HTTP/2 to HTTP priority translation
Motivation:

The priority information reported by the HTTP/2 to HTTP tranlsation layer is not correct in all situations.
The HTTP translation layer is not using the Http2Connection.Listener interface to track tree restructures.
This incorrect information is being sent up to clients and is misleading.

Modifications:
-Restructure InboundHttp2ToHttpAdapter to allow a default data/header mode
-Extend this interface to provide an optional priority translation layer

Result:
-Priority information being correctly reported in HTTP/2 to HTTP translation layer
-Cleaner code with seperation of concerns (optional priority conversion).
2014-08-26 14:06:02 -07:00
Scott Mitchell
892944eba8 HTTP/2 draft 14 HTTP message flow
Motivation:

HTTP/2 draft 14 came out a couple of weeks ago and we need to keep up
with the spec.

Modifications:
-Revert back to dispatching FullHttpMessage objects instead of individual HttpObjects
-Corrections to HttpObject comparitors to support test cases
-New test cases to support sending headers immediatley
-Bug fixes cleaned up to ensure the message flow is terminated properly

Result:
Netty HTTP/2 to HTTP/1.x translation layer will support the HTTP/2 draft message flow.
2014-08-25 11:34:15 -07:00
Norman Maurer
d332c00e2f Reduce memory copies in spdy compression implementation.
Motivation:

Currently we do more memory copies then needed.

Modification:

- Directly use heap buffers to reduce memory copy
- Correctly release buffers to fix buffer leak

Result:

Less memory copies and no leaks
2014-08-21 11:32:36 +02:00
plucury
a2416481e3 Allow ChunkedInput to provide the progress of its transfer
Related issue: #2741 and #2151

Motivation:

There is no way for ChunkedWriteHandler to know the progress of the
transfer of a ChannelInput. Therefore, ChannelProgressiveFutureListener
cannot get exact information about the progress of the transfer.

If you add a few methods that optionally provides the transfer progress
to ChannelInput, it becomes possible for ChunkedWriteHandler to notify
ChannelProgressiveFutureListeners.

If the input has no definite length, we can still use the progress so
far, and consider the length of the input as 'undefined'.

Modifications:

- Add ChunkedInput.progress() and ChunkedInput.length()
- Modify ChunkedWriteHandler to use progress() and length() to notify
  the transfer progress

Result:

ChunkedWriteHandler now notifies ChannelProgressiveFutureListener.
2014-08-14 16:55:35 -07:00
Norman Maurer
3f10ed3082 [#2768] Correctly duplicate buffer for CloseWebSocketFrames
Motivation:

The _0XFF_0X00 buffer is not duplicated and empty after the first usage preventing the connection close to happen on subsequent close frames.

Modifications:

Correctly duplicate the buffer.

Result:

Multiple CloseWebSocketFrames are handled correctly.
2014-08-14 09:54:52 +02:00
Scott Mitchell
b41b11c53d Introduced HTTP/2 frame to HTTP/1.x translation layer.
Motivation:

The HTTP/2 codec currently provides direct callbacks to access stream events/data. The HTTP/2 codec provides the protocol support for HTTP/2 but it does not pass messages up the context pipeline. It would be nice to have a decoder which could collect the data framed by HTTP/2 and translate this into traditional HTTP type objects. This would allow the traditional Netty context pipeline to be used to separate processing concerns (i.e. HttpContentDecompressor).  It would also be good to have a layer which can translate FullHttp[Request|Response] objects into HTTP/2 frame outbound events.

Modifications:

Introduce a new InboundHttp2ToHttpAdapter and supporting classes which will translate HTTP/2 stream events/data into HttpObject objects. Introduce a new DelegatingHttp2HttpConnectionHandler which will translate FullHttp[Request|Response] objects to HTTP/2 frame events.

Result:

Introduced HTTP/2 frame events to HttpObject layer.
Introduced FullHttp[Request|Response] to HTTP/2 frame events.
Introduced new unit tests to support new code.
Updated HTTP/2 client example to use new code.
Miscelaneous updates and bug fixes made to support new code.
2014-08-12 12:31:26 -07:00
Jeff Pinner
f7e183f8e4 SPDY: fix SpdySessionHandler::updateSendWindowSize
In Netty 3, downstream writes of SPDY data frames and upstream reads of
SPDY window udpate frames occur on different threads.

When receiving a window update frame, we synchronize on a java object
(SpdySessionHandler::flowControlLock) while sending any pending writes
that are now able to complete.

When writing a data frame, we check the send window size to see if we
are allowed to write it to the socket, or if we have to enqueue it as a
pending write. To prevent races with the window update frame, this is
also synchronized on the same SpdySessionHandler::flowControlLock.

In Netty 4, upstream and downstream operations on any given channel now
occur on the same thread. Since java locks are re-entrant, this now
allows downstream writes to occur while processing window update frames.

In particular, when we receive a window update frame that unblocks a
pending write, this write completes which triggers an event notification
on the response, which in turn triggers a write of a data frame. Since
this is on the same thread it re-enters the lock and modifies the send
window. When the write completes, we continue processing pending writes
without knowledge that the window size has been decremented.
2014-08-11 11:13:22 +02:00
Trustin Lee
168e81e9cd Fix a bug where SpdySession.getActiveStreams() returns incorrect set
Related issue: #2743

Motivation:

When there are more than one stream with the same priority, the set
returned by SpdySession.getActiveStream() will not include all of them,
because it uses TreeSet and only compares the priority of streams. If
two different streams have the same priority, one of them will be
discarded by TreeSet.

Modification:

- Rename getActiveStreams() to activeStreams()
- Replace PriorityComparator with StreamComparator

Result:

Two different streams with the same priority are compared correctly.
2014-08-05 17:46:13 -07:00
Trustin Lee
6ecca2722e Add test cases for HttpContentCompressor
- Ported from 386a06dbfa
2014-08-05 15:48:14 -07:00
Norman Maurer
2258b32549 [#2732] HttpRequestEncoder may produce invalid uri if uri parameters are included.
Motivation:

If the requests contains uri parameters but not path the HttpRequestEncoder does produce an invalid uri while try to add the missing path.

Modifications:

Correctly handle the case of uri with paramaters but no path.

Result:

HttpRequestEncoder produce correct uri in all cases.
2014-08-05 10:14:06 +02:00
Trustin Lee
c5ae3e3dcb Use our own URL shortener wherever possible 2014-07-31 17:06:30 -07:00
Jeff Pinner
6935c07ce1 SPDY: fix pushed response NullPointerException 2014-07-21 07:50:22 +02:00
Idel Pivnitskiy
6860019f41 Fix NPE problems
Motivation:

Now Netty has a few problems with null values.

Modifications:

- Check HAProxyProxiedProtocol in HAProxyMessage constructor and throw NPE if it is null.
If HAProxyProxiedProtocol is null we will set AddressFamily as null. So we will get NPE inside checkAddress(String, AddressFamily) and it won't be easy to understand why addrFamily is null.
- Check File in DiskFileUpload.toString().
If File is null we will get NPE when calling toString() method.
- Check Result<String> in MqttDecoder.decodeConnectionPayload(...).
If !mqttConnectVariableHeader.isWillFlag() || !mqttConnectVariableHeader.hasUserName() || !mqttConnectVariableHeader.hasPassword() we will get NPE when we will try to create new instance of MqttConnectPayload.
- Check Unsafe before calling unsafe.getClass() in PlatformDependent0 static block.
- Removed unnecessary null check in WebSocket08FrameEncoder.encode(...).
Because msg.content() can not return null.
- Removed unnecessary null check in DefaultStompFrame(StompCommand) constructor.
Because we have this check in the super class.
- Removed unnecessary null checks in ConcurrentHashMapV8.removeTreeNode(TreeNode<K,V>).
- Removed unnecessary null check in OioDatagramChannel.doReadMessages(List<Object>).
Because tmpPacket.getSocketAddress() always returns new SocketAddress instance.
- Removed unnecessary null check in OioServerSocketChannel.doReadMessages(List<Object>).
Because socket.accept() always returns new Socket instance.
- Pass Unpooled.buffer(0) instead of null inside CloseWebSocketFrame(boolean, int) constructor.
If we will pass null we will get NPE in super class constructor.
- Added throw new IllegalStateException in GlobalEventExecutor.awaitInactivity(long, TimeUnit) if it will be called before GlobalEventExecutor.execute(Runnable).
Because now we will get NPE. IllegalStateException will be better in this case.
- Fixed null check in OpenSslServerContext.setTicketKeys(byte[]).
Now we throw new NPE if byte[] is not null.

Result:

Added new null checks when it is necessary, removed unnecessary null checks and fixed some NPE problems.
2014-07-20 12:55:08 +02:00
Idel Pivnitskiy
dd26d47adc Small performance improvements
Modifications:

- Added a static modifier for CompositeByteBuf.Component.
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.
- Removed unnecessary boxing/unboxing operations in HttpResponseDecoder, RtspResponseDecoder, PerMessageDeflateClientExtensionHandshaker and PerMessageDeflateServerExtensionHandshaker
A boxed primitive is created from a String, just to extract the unboxed primitive value.
- Removed unnecessary 3 times calculations in DiskAttribute.addContent(...).
- Removed unnecessary checks if file exists before call mkdirs() in NativeLibraryLoader and PlatformDependent.
Because the method mkdirs() has this check inside.
- Removed unnecessary `instanceof AsciiString` check in StompSubframeAggregator.contentLength(StompHeadersSubframe) and StompSubframeDecoder.getContentLength(StompHeaders, long).
Because StompHeaders.get(CharSequence) always returns java.lang.String.
2014-07-20 09:24:56 +02:00
Gernot Pansy
d8a78424b3 Fixed NPE in WebSocket00FrameDecoder if end couldn't be found in text frame
Motivation:
When we receive an incomplete WebSocketFrame we need to make sure to wait for more data. Because we not did this we could produce a NPE.

Modification:
Make sure we not try to add null into the RecyclableArrayList

Result:
no more NPE on incomplete frames.
2014-07-16 20:04:21 +02:00
Norman Maurer
edc7abb461 [#2650] Allow to disable http header validation in SpdyHttpDecoder and SpdyHttpCodec
Motivation:

HTTP header validation can be expensive so we should allow to disable it like we do in HttpObjectDecoder.

Modification:

Add constructor argument to disable validation.

Result:
Performance improvement
2014-07-11 08:31:39 +02:00
Norman Maurer
dfa5a88978 Reuse previous created HttpHeaders by HttpObjectAggregator
Motivation:

HttpObjectAggregator currently creates a new FullHttpResponse / FullHttpRequest for each message it needs to aggregate. While doing so it also creates 2 DefaultHttpHeader instances (one for the headers and one for the trailing headers). This is bad for two reasons:
  - More objects are created then needed and also populate the headers is not for free
  - Headers may get validated even if the validation was disabled in the decoder

Modification:

- Wrap the previous created HttpResponse / HttpRequest and so reuse the original HttpHeaders
- Reuse the previous created trailing HttpHeader.
- Fix a bug where the trailing HttpHeader was incorrectly mixed in the headers.

Result:

- Less GC
- Faster HttpObjectAggregator implementation
2014-07-11 07:23:58 +02:00
Norman Maurer
639db72839 Fix buffer leak in test introduced by 282d6e73b8 2014-07-10 06:43:09 +02:00
fboucher38
282d6e73b8 Add WebSocket Extension handlers for client and server.
Add permessage-deflate and deflate-frame WebSocket extension
implementations.

Motivation:

Need to compress HTTP WebSocket frames payload.

Modifications:

- Move UTF8 checking of WebSocketFrames from frame decoder to and
external handler.
- Change ZlibCodecFactory in order to use ZLib implentation instead of
JDK if windowSize or memLevel is different from the default one.
- Add WebSocketServerExtensionHandler and
WebSocketClientExtensionHandler to handle WebSocket Extension headers.
- Add DeflateFrame and PermessageDeflate extension implementations.
2014-07-09 16:28:40 +02:00
Norman Maurer
696e355a70 Move generic code to HttpOrSpdyChooser to simplify implementations
Motivation:

HttpOrSpdyChooser can be simplified so the user not need to implement getProtocol(...) method.

Modification:

Add implementation for the method. The user can override it if necessary.

Result:

Easier usage of HttpOrSpdyChooser.
2014-07-07 09:44:50 +02:00
Trustin Lee
330404da07 Fix most inspector warnings
Motivation:

It's good to minimize potentially broken windows.

Modifications:

Fix most inspector warnings from our profile

Result:

Cleaner code
2014-07-02 19:04:11 +09:00
Norman Maurer
bebcf81687 Fix compile error 2014-06-28 22:27:15 +02:00
Jay
db3c592e6a Maintain decoder result in HttpObjectAggregator
Motivation:
DecodeResult is dropped when aggregate HTTP messages.

Modification:

Make sure we not drop the DecodeResult while aggregate HTTP messages.

Result:

Correctly include the DecodeResult for later processing.
2014-06-28 22:09:46 +02:00
Trustin Lee
6071c9c267 Remove the deprecated methods in SPDY and HTTP
No need to keep ABI compatibility since we are working on a
backward-incompatible branch
2014-06-27 16:55:23 +09:00
Alexey Parfenov
087d329d07 Fix integer overflow in HttpObjectEncoder when handling chunked encoding and FileRegion > Integer.MAX_VALUE
Motivation:

Due to integer overflow bug, writes of FileRegions to http server pipeline (eg like one from HttpStaticFileServer example) with length greater than Integer.MAX_VALUE are ignored in 1/2 of cases (ie no data gets sent to client)

Modification:

Correctly handle chunk sized > Integer.MAX_VALUE

Result:

Be able to use FileRegion > Integer.MAX_VALUE when using chunked encoding.
2014-06-24 12:01:27 +02:00
Trustin Lee
24e17d1832 Remove 'get' prefix from all HTTP/SPDY messages
Motivation:

Persuit for the consistency in method naming

Modifications:

- Remove the 'get' prefix from all HTTP/SPDY message classes
- Fix some inspector warnings

Result:

Consistency
2014-06-24 18:41:27 +09:00
Trustin Lee
760bbc7ea6 Refactor FastThreadLocal to simplify TLV management
Motivation:

When Netty runs in a managed environment such as web application server,
Netty needs to provide an explicit way to remove the thread-local
variables it created to prevent class loader leaks.

FastThreadLocal uses different execution paths for storing a
thread-local variable depending on the type of the current thread.
It increases the complexity of thread-local removal.

Modifications:

- Moved FastThreadLocal and FastThreadLocalThread out of the internal
  package so that a user can use it.
- FastThreadLocal now keeps track of all thread local variables it has
  initialized, and calling FastThreadLocal.removeAll() will remove all
  thread-local variables of the caller thread.
- Added FastThreadLocal.size() for diagnostics and tests
- Introduce InternalThreadLocalMap which is a mixture of hard-wired
  thread local variable fields and extensible indexed variables
- FastThreadLocal now uses InternalThreadLocalMap to implement a
  thread-local variable.
- Added ThreadDeathWatcher.unwatch() so that PooledByteBufAllocator
  tells it to stop watching when its thread-local cache has been freed
  by FastThreadLocal.removeAll().
- Added FastThreadLocalTest to ensure that removeAll() works
- Added microbenchmark for FastThreadLocal and JDK ThreadLocal
- Upgraded to JMH 0.9

Result:

- A user can remove all thread-local variables Netty created, as long as
  he or she did not exit from the current thread. (Note that there's no
  way to remove a thread-local variable from outside of the thread.)
- FastThreadLocal exposes more useful operations such as isSet() because
  we always implement a thread local variable via InternalThreadLocalMap
  instead of falling back to JDK ThreadLocal.
- FastThreadLocalBenchmark shows that this change improves the
  performance of FastThreadLocal even more.
2014-06-19 21:17:46 +09:00
Trustin Lee
de2872f7f7 Introduce TextHeaders and AsciiString
Motivation:

We have quite a bit of code duplication between HTTP/1, HTTP/2, SPDY,
and STOMP codec, because they all have a notion of 'headers', which is a
multimap of string names and values.

Modifications:

- Add TextHeaders and its default implementation
- Add AsciiString to replace HttpHeaderEntity
  - Borrowed some portion from Apache Harmony's java.lang.String.
- Reimplement HttpHeaders, SpdyHeaders, and StompHeaders using
  TextHeaders
- Add AsciiHeadersEncoder to reuse the encoding a TextHeaders
  - Used a dedicated encoder for HTTP headers for better performance
    though
- Remove shortcut methods in SpdyHeaders
- Remove shortcut methods in SpdyHttpHeaders
- Replace SpdyHeaders.getStatus() with HttpResponseStatus.parseLine()

Result:

- Removed quite a bit of code duplication in the header implementations.
- Slightly better performance thanks to improved header validation and
  hash code calculation
2014-06-14 17:14:30 +09:00
belliottsmith
7d37af5dfb Introduce FastThreadLocal which uses an EnumMap and a predefined fixed set of possible thread locals
Motivation:
Provide a faster ThreadLocal implementation

Modification:
Add a "FastThreadLocal" which uses an EnumMap and a predefined fixed set of possible thread locals (all of the static instances created by netty) that is around 10-20% faster than standard ThreadLocal in my benchmarks (and can be seen having an effect in the direct PooledByteBufAllocator benchmark that uses the DEFAULT ByteBufAllocator which uses this FastThreadLocal, as opposed to normal instantiations that do not, and in the new RecyclableArrayList benchmark);

Result:
Improved performance
2014-06-13 11:02:16 +02:00
Frederic Bregier
89ed1517f5 [#2542] HTTP post request decoder does not support quoted boundaries
Motivation:
According to RFC2616 section 19, boundary string could be quoted, but
currently the PostRequestDecoder does not support it while it should.

Modifications:
Once the boundary is found, one check is made to verify if the boundary
is "quoted", and if so, it is "unqoted".

Note: in following usage of this boundary (as delimiter), quote seems no
more allowed according to the same RFC, so the reason that only the
boundary definition is corrected.

Result:
Now the boundary could be whatever quoted or not. A Junit test case
checks it.
2014-06-08 12:07:44 +02:00
Frederic Bregier
c16de8fcbc [#2544] Correctly parse Multipart-mixed POST HTTP request in case of entity ends with odd number of 0x0D
Motivation:
When an attribute is ending with an odd number of CR (0x0D), the decoder
add an extra CR in the decoded attribute and should not.

Modifications:
Each time a CR is detected, the next byte was tested to be LF or not. If
not, in a number of places, the CR byte was lost while it should not be.
When a CR is detected, if the next byte is not LF, the CR byte should be
saved as the position point to the next byte (not LF). When a CR is
detected, if there is not yet other available bytes, the position is
reset to the position of CR (since a LF could follow).

A new Junit test case is added, using DECODER and variable number of CR
in the final attribute (testMultipartCodecWithCRasEndOfAttribute).

Result:
The attribute is now correctly decoded with the right number of CR
ending bytes.
2014-06-08 11:22:51 +02:00
Trustin Lee
2e98566916 Introduce MessageAggregator and DecoderResultProvider
Motivation:

We have different message aggregator implementations for different
protocols, but they are very similar with each other.  They all stems
from HttpObjectAggregator.  If we provide an abstract class that provide
generic message aggregation functionality, we will remove their code
duplication.

Modifications:

- Add MessageAggregator which provides generic message aggregation
- Reimplement all existing aggregators using MessageAggregator
- Add DecoderResultProvider interface and extend it wherever possible so
  that MessageAggregator respects the state of the decoded message

Result:

Less code duplication
2014-06-05 16:39:59 +09:00
Josh Hoyt
2c38e6b5d9 codec-http: Document the semantics of HttpResponseStatus equality and comparison 2014-05-30 07:52:58 +02:00
nmittler
086dc9140a Adding a general handler for upgrading protocols
Adding full implementation for cleartext upgrade from HTTP to HTTP/2.
2014-05-19 07:30:18 -07:00
Daniel Bevenius
b1a51f0669 Adding short-curcuit option for CORS
Motivation:
CORS request are currently processed, and potentially failed, after the
target ChannelHandler(s) have been invoked. This might not be desired, for
example a HTTP PUT or POST might have been performed.

Modifications:
Added a shortCurcuit option to CorsConfig which when set will
cause a validation of the HTTP request's 'Origin' header and verify that
it is valid according to the configuration. If found invalid an 403
"Forbidden" response will be returned and not further processing will
take place.

This is indeed no help for non browser request, like using curl, which
can set the 'Origin' header.

Result:
Users can now configure if the 'Origin' header should be validated
upfront and have the request rejected before any further processing
takes place.
2014-05-06 12:06:34 +02:00
Norman Maurer
e1becd2147 Fix buffer leak introduced by #2462
Motivation:
Because of not correctly release a buffer before null out the reference a memory leak shows up.

Modifications:
Correct call buffer.release() before null out reference.

Result:
No more leak
2014-05-06 10:06:19 +02:00
Jeff Pinner
1aca3863eb SPDY: ensure SpdyHeaderBlockRawDecoder always reads entire input 2014-05-05 07:32:37 +02:00
Jeff Pinner
3f50a9cde3 SPDY: release headerBlock in SpdyFrameCodec 2014-05-05 07:26:39 +02:00
Jeff Pinner
78963635ba SPDY: remove unused code in SpdyHeaderBlockRawEncoder 2014-05-05 07:01:23 +02:00
Sun Ning
31b01c87e4 Made websocket maxFramePayloadSize configurable from WebSocketServerProtocolHandler.
Motivation:

Currently there's no way to configure maxFramePayloadSize from
WebSocketServerProtocolHandler, which is the most used entry point of
WebSocket server.

Modifications:

Added another constructor for maxFramePayloadSize.

Result:

We can configure max frame size for websocket packet in
WebSocketServerProtocolHandler. It will also keep backward compatibility
with default max size: 65536. (65536 is hard-coded max size in previous
version of Netty)
2014-05-05 06:24:40 +02:00
Jeff Pinner
c09d85f699 SPDY: allow subclassing of SpdyFrameCodec 2014-05-03 14:44:08 +02:00
Norman Maurer
8599ab5bdb Remove ContinuationWebSocketFrame.aggregatedText()
Motivation:
Before we aggregated the full text in the WebSocket08FrameDecoder just to fill in the ContinuationWebSocketFrame.aggregatedText(). The problem was that there was no upper-limit and so it would be possible to see an OOME if the remote peer sends a TextWebSocketFrame + a never ending stream of ContinuationWebSocketFrames. Furthermore the aggregation does not really belong in the WebSocket08FrameDecoder, as we provide an extra ChannelHandler for this anyway (WebSocketFrameAggregator).

Modification:
Remove the ContinuationWebSocketFrame.aggregatedText() method and corresponding constructor. Also refactored WebSocket08FrameDecoder a bit to me more efficient which is now possible as we not need to aggregate here.

Result:
No more risk of OOME because of frames.
2014-04-30 14:49:37 +02:00
Daniel Bevenius
32e0170041 Adding support for echoing the request origin for CORS.
Motivation:
When CORS has been configured to allow "*" origin, and at the same time
is allowing credentials/cookies, this causes an error from the browser
because when the response 'Access-Control-Allow-Credentials' header
is true, the 'Access-Control-Allow-Origin' must be an actual origin.

Modifications:
Changed CorsHandler setOrigin method to check for the combination of "*"
origin and allowCredentials, and if the check matches echo the CORS
request's 'Origin' value.

Result:
This addition enables the echoing of the request 'Origin' value as the
'Access-Control-Allow-Origin' value when the server has been configured
to allow any origin in combination with allowCredentials.

This allows client requests to succeed when expecting the server to
be able to handle "*" origin and at the same time be able to send cookies
by setting 'xhr.withCredentials=true'. A concrete example of this is
the SockJS protocol which expects behaviour.
2014-04-25 18:20:18 +02:00
Trustin Lee
872d4c5bc1 Synchronized between 4.1 and master again (part 2)
Motivation:
4 and 5 were diverged long time ago and we recently reverted some of the
early commits in master.  We must make sure 4.1 and master are not very
different now.

Modification:
Remove ChannelHandlerInvoker.writeAndFlush(...) and the related
implementations.

Result:
4.1 and master got closer.
2014-04-25 15:07:12 +09:00
Trustin Lee
d2614cfc01 Synchronized between 4.1 and master
Motivation:

4 and 5 were diverged long time ago and we recently reverted some of the
early commits in master.  We must make sure 4.1 and master are not very
different now.

Modification:

Fix found differences

Result:

4.1 and master got closer.
2014-04-25 00:36:01 +09:00
Norman Maurer
cc320a4be6 [#2401] Improve documentation of HttpObjectAggregator
Motivation:
Make it more clear what the output of HttpObjectAggregator is and that it need to come after the encoder in the pipeline.

Modifications:
Change javadocs to make things more clear.

Result:
Better docs
2014-04-17 15:42:47 +02:00
Norman Maurer
7a55436aa4 Fix missed buffer leaks in SpdyFrameDecoderTest
Motivation:
 Fix leaks reported during running SpdyFrameDecoderTest

Modifications:
Make sure the produced buffers of SpdyFrameDecoder and SpdyFrameDecoderTest are released

Result:

No more leak reports during run the tests.
2014-04-16 14:03:01 +02:00
Norman Maurer
f9884ded7c Fix buffer leaks in SpdyFrameDecoderTest
Motivation:

Fix leaks reported during running SpdyFrameDecoderTest

Modifications:
Make sure the produced buffer of SpdyFrameDecoder is released

Result:

No more leak reports during run the tests.
2014-04-16 10:48:12 +02:00
Norman Maurer
f443754af6 Fix buffer leaks in SPDY test
Motivation:

Fix leaks reported during SPDY test.

Modifications:

Use ReferenceCountUtil.releaseLater(...) to make sure everything is released once the tests are done.

Result:

No more leak reports during run the tests.
2014-04-16 06:49:25 +02:00
Norman Maurer
58423a448a Add missing override annotations 2014-04-15 20:15:30 +02:00
Jeff Pinner
350c8ef42a SPDY: refactor frame codec implementation
Motivation:

Currently, the SPDY frame encoding and decoding code is based upon
the ChannelHandler abstraction. This requires maintaining multiple
versions for 3.x and 4.x (and possibly 5.x moving forward).

Modifications:

The SPDY frame encoding and decoding code is separated from the
ChannelHandler and SpdyFrame abstractions. Also test coverage is
improved.

Result:

SpdyFrameCodec now implements the ChannelHandler abstraction and is
responsible for creating and handling SpdyFrame objects.
2014-04-15 18:42:08 +02:00
Daniel Bevenius
7c6f862d98 Adding origins whitelist support for CORS
Motivation:
Currently the CORS support only handles a single origin, or a wildcard
origin. This task should enhance Netty's CORS support to allow multiple
origins to be specified. Just being allowed to specify one origin is
particulary limiting when a site support both http and https for
example.

Modifications:
- Updated CorsConfig and its Builder to accept multiple origins.

Result:
Users are now able to configure multiple origins for CORS.

[https://github.com/netty/netty/issues/2346]
2014-03-30 19:40:59 +02:00
Brendt Lucas
98bc7b7859 [#2234] Use QueryStringDecoder.decodeComponent to decode url-encoded data instead of Java's URLDecoder.
Motivation:
Previously, we used URLDecoder.decode(...) to decode url-encoded data. This generates a lot of garbage and takes a considerable amount of time.

Modifications:
Replace URLDecoder.decode(...) with QueryStringDecoder.decodeComponent(...)

Result:
Less garbage to GC and faster decode processing.
2014-03-22 14:02:35 +01:00
Daniel Bevenius
27671e0dbd Fixing CorsConfigTest failure under Java 8.
Motivation:
When running the build with Java 8 the following error occurred:

java: reference to preflightResponseHeader is ambiguous
  both method
  <T>preflightResponseHeader(java.lang.CharSequence,java.lang.Iterable<T>)
  in io.netty.handler.codec.http.cors.CorsConfig.Builder and method
  <T>preflightResponseHeader(java.lang.String,java.util.concurrent.Callable<T>)
  in io.netty.handler.codec.http.cors.CorsConfig.Builder match

The offending class was CorsConfigTest and its shouldThrowIfValueIsNull
which contained the following line:
withOrigin("*").preflightResponseHeader("HeaderName", null).build();

Modifications:
Updated the offending method with to supply a type, and object array, to
avoid the error.

Result:
After this I was able to build with Java 7 and Java 8
2014-03-22 07:20:10 +01:00
Daniel Bevenius
321e770c9b Adding support for specifying preflight response headers.
Motivation:

An intermediary like a load balancer might require that a Cross Origin
Resource Sharing (CORS) preflight request have certain headers set.
As a concrete example the Elastic Load Balancer (ELB) requires the
'Date' and 'Content-Length' header to be set or it will fail with a 502
error code.

This works is an enhancement of https://github.com/netty/netty/pull/2290

Modifications:

CorsConfig has been extended to make additional HTTP response headers
configurable for preflight responses. Since some headers, like the
'Date' header need to be generated each time, m0wfo suggested using a
Callable.

Result:

By default, the 'Date' and 'Content-Lenght' headers will be sent in a
preflight response. This can be overriden and users can specify
any headers that might be required by different intermediaries.
2014-03-21 15:05:29 +01:00
Frederic Bregier
ef53227836 [#2305] Fix issue related to decoding post request raized an exception due to a split of information by chunk not correctly taken into account by the decoder
Motivation:

If the last item analyzed in a previous received HttpChunk/HttpContent was a part of an attribute's name, the read index was not set to the new right place and therefore raizing an exception in some case (since the "new" name analyzed is empty, which is not allowed so the exception).

What appears there is that the read index should be reset to the last valid position encountered whatever the case. Currently it was set when only when there is an attribute not already finished (name is ok, but content is possibly not).

Therefore the issue is that elements could be rescanned multiple times (including completed elements) and moreover some bad decoding can occur such as when in a middle of an attribute's name.

Modifications:

To fix this issue, since "firstpos" contains the last "valid" read index of the decoding (when finding a '&', '=', 'CR/LF'), we should add the setting of the read index for the following cases:

'lastchunk' encountered, therefore finishing the current buffer
any other cases than current attribute is not finished (name not found yet in particular)
So adding for this 2 cases:

undecodedChunk.readerIndex(firstpos);

Result:

Now the decoding is done once, content is added from chunk/content to chunk/content, name is decoded correctly even if in the middle of 2 chunks/contents.
A Junit test code was added: testChunkCorrect that should not raized any exception.
2014-03-14 09:46:58 +01:00
David Dossot
c31e8f59ba added support for empty query parameters 2014-03-10 06:29:45 +01:00