Commit Graph

6389 Commits

Author SHA1 Message Date
Trustin Lee
61eddd5b74 Add log messages when dump starts
.. to make it easier to find the right dump file for a test when there
are multiple dump files.
2014-12-12 11:55:34 +09:00
Trustin Lee
94a64c09cd Make sure to notify handshake success even if SSLEngine is closed
Related:

e9685ea45a

Motivation:

SslHandler.unwrap() does not evaluate the handshake status of
SSLEngine.unwrap() when the status of SSLEngine.unwrap() is CLOSED.

It is not correct because the status does not reflect the state of the
handshake currently in progress, accoding to the API documentation of
SSLEngineResult.Status.

Also, sslCloseFuture can be notified earlier than handshake notification
because we call sslCloseFuture.trySuccess() before evaluating handshake
status.

Modifications:

- Notify sslCloseFuture after the unwrap loop is finished
- Add more assertions to SocketSslEchoTest

Result:

Potentially fix the regression caused by:
- e9685ea45a
2014-12-12 11:55:34 +09:00
Trustin Lee
ed7cc5bee6 Generate heap and thread dump when some tests fail
Motivation:

We have a few sporadic test failures which are only easily reproduceable
in our CI machine.  To get more information about the failure, we need
heap and full thread dump at the moment of failure.

Modifications:

- Add TestUtils.dump() method to dump heap and threads
- Modify SocketGatheringWriteTest and SocketSslEchoTest to call
  TestUtils.dump() on failure

Result:

We get more information about the test failure.
2014-12-12 10:35:19 +09:00
Scott Mitchell
1293aba28e HTTP/2 Draft 16
Motivation:
HTTP/2 draft 16 has been released https://tools.ietf.org/html/draft-ietf-httpbis-http2-16.

Modifications:
The HTTP/2 codec should be updated to support draft 16.

Result:
HTTP/2 codec is draft 16 compliant.
2014-12-11 18:58:59 -05:00
Scott Mitchell
2cf4ee9322 HTTP/2 Sonar Bugs
Motivation:
Clinker provides a Sonar tool which detects potential bugs or problems in the code.  These problems were reported here http://clinker.netty.io/sonar/drilldown/issues/io.netty:netty-parent:master?

Modifications:
Make the recommended changes as reported by Sonar

Result:
Better or more standard code.  Less Sonar problem reports for HTTP/2 codec.
2014-12-11 08:10:27 -05:00
Norman Maurer
140a32bcb3 Allow to lazy create a DefaultFileRegion from a File
Motivation:

We only provided a constructor in DefaultFileRegion that takes a FileChannel which means the File itself needs to get opened on construction. This has the problem that if you want to write a lot of Files very fast you may end up with may open FD's even if they are not needed yet. This can lead to hit the open FD limit of the OS.

Modifications:

Add a new constructor to DefaultFileRegion which allows to construct it from a File. The FileChannel will only be obtained when transferTo(...) is called or the DefaultFileRegion is explicit open'ed via open() (this is needed for the native epoll transport)

Result:

Less resource usage when writing a lot of DefaultFileRegion.
2014-12-11 12:06:52 +01:00
Norman Maurer
398e7a9b08 Ensure buffer is not released when call array() / memoryAddress()
Motivation:

Before we missed to check if a buffer was released before we return the backing byte array or memoryaddress. This could lead to JVM crashes when someone tried various bulk operations on the Unsafe*ByteBuf implementations.

Modifications:

Always check if the buffer is released before all to return the byte array and memoryaddress.

Result:

No more JVM crashes because of released buffers when doing bulk operations on Unsafe*ByteBuf implementations.
2014-12-11 11:31:05 +01:00
Trustin Lee
a0862bc5fb Make SslHandler work when autoRead is turned off
Related: #2958

Motivation:

SslHandler currently does not issue a read() request when it is
handshaking. It makes a connection with autoRead off stall, because a
user's read() request can be used to read the handshake response which
is invisible to the user.

Modifications:

- SslHandler now issues a read() request when:
  - the current handshake is in progress and channelReadComplete() is
    invoked
  - the current handshake is complete and a user issued a read() request
    during handshake
- Rename flushedBeforeHandshakeDone to flushedBeforeHandshake for
  consistency with the new variable 'readDuringHandshake'

Result:

SslHandler should work regardless whether autoRead is on or off.
2014-12-11 17:54:39 +09:00
Trustin Lee
d1612f67ad Add SslHandler.renegotiate()
Related: #3125

Motivation:

We did not expose a way to initiate TLS renegotiation and to get
notified when the renegotiation is done.

Modifications:

- Add SslHandler.renegotiate() so that a user can initiate TLS
  renegotiation and get the future that's notified on completion
- Make SslHandler.handshakeFuture() return the future for the most
  recent handshake so that a user can get the future of the last
  renegotiation
- Add the test for renegotiation to SocketSslEchoTest

Result:

Both client-initiated and server-initiated renegotiations are now
supported properly.
2014-12-10 18:47:53 +09:00
Trustin Lee
85ec4d9cc4 Trigger channelWritabilityChanged() later to avoid reentrance
Related: #3212

Motivation:

When SslHandler and ChunkedWriteHandler exists in a pipeline together,
it is possible that ChunkedWriteHandler.channelWritabilityChanged()
invokes SslHandler.flush() and vice versa. Because they can feed each
other (i.e. ChunkedWriteHandler.channelWritabilityChanged() ->
SslHandler.flush() -> ChunkedWriteHandler.channelWritabilityChanged() ->
..), they can fall into an inconsistent state due to reentrance (e.g.
bad MAC record at the remote peer due to incorrect ordering.)

Modifications:

- Trigger channelWritabilityChanged() using EventLoop.execute() when
  there's a chance where channelWritabilityChanged() can cause a
  reentrance issue
- Fix test failures caused by the modification

Result:

Fix the handler reentrance issues related with a
channelWritabilityChanged() event
2014-12-10 18:36:53 +09:00
Scott Mitchell
7f9fb95702 HTTP/2 Unit Test race condition
Motivation:
The Http2ConnectionRoundtripTest.noMoreStreamIdsShouldSendGoAway unit test had a race condition where it would sometimes receive a SETINGS_ACK message that was not anticipated. This caused the test to fail because of bad test code.

Modifications:
The bad unit test should be updated to handle the message exchange for a good connection setup, and then the GO_AWAY frame.

Result:
Http2ConnectionRoundtripTest.noMoreStreamIdsShouldSendGoAway should no longer sporadically fail.
2014-12-09 16:24:21 -05:00
Trustin Lee
047176bc3f Call ctx.flush() at least once in ChunkedWriteHandler.flush()
Related: #3219

Motivation:

ChunkedWriteHandler.flush() does not call ctx.flush() when channel is
not writable. This can be a problem when other handler / non-Netty
thread writes messages simultaneously, because
ChunkedWriteHandler.flush() might have no chance to observe
channel.isWritable() returns true and thus the channel is never flushed.

Modifications:

- Ensure that ChunkedWriteHandler.flush() calls ctx.flush() at least
  once.

Result:

A stall connection issue, that occurs when certain combination of
handlers exist in a pipeline, has been fixed. (e.g. SslHandler and
ChunkedWriteHandler)
2014-12-09 18:17:23 +09:00
nmittler
124983afb5 Refactoring HTTP/2 Flow Control interfaces.
Motivation:

The terminology used with inbound/outbound is a little confusing since
it's not discussed in the spec. We should switch to using local/remote
instead. Also there is some asymmetry between the inbound/outbound
interfaces which could probably be cleaned up.

Modifications:

Changing the interface names and making a common Http2FlowController
interface for most of the methods.

Result:

The HTTP/2 flow control interfaces should be more clear.
2014-12-08 09:16:06 -08:00
Daniel Bevenius
ed09fb10bc Fixing minor typo in FastThreadLocal javadoc. 2014-12-08 14:24:07 +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
Trustin Lee
69e25d21f6 Make PendingWriteQueue.recycle() update its state before triggering an event
Related: #3212

Motivation:

PendingWriteQueue.recycle() updates its data structure after triggering
a channelWritabilityChanged() event. It causes a rare corruption such as
double free when channelWritabilityChanged() method accesses the
PendingWriteQueue.

Modifications:

Update the state of PendingWriteQueue before triggering an event.

Result:

Fix a rare double-free problem
2014-12-07 23:24:19 +09:00
Trustin Lee
a337589c91 Trigger exceptionCaught() when VoidChannelPromise fails
Related: #3190

Motivation:

When an outbound handler method raises an exception, its promise is
marked as failed.  If the promise is done already, the exception is
logged.

When the promise is void, exceptionCaught() must be triggered to notify
a user. However, ChannelHandlerInvokerUtil simply swallows it.

Modifications:

Do not swallow an exception when the promise is void.

Result:

A user who uses a void promise for an outbound operation will be
notified on failure.
2014-12-07 16:07:33 +09:00
Trustin Lee
7e2ae8758c Fire channelRead() event immediately in OIO message channels
Related: #3189

Motivation:

OIO transport implementations block for at most 1 second to wait for
additional messages (or accepted connections).

However, because AbstractOioMessageChannel defers the channelRead()
events for the messages read so far until there's nothing to read up to
maxMessagesPerRead, any read operation will be followed by a 1-second
delay.

Modifications:

Fire channelRead() events as soon as doRead() returns so that there is
no 1 second delay between the actual read and the channelRead() event.

Result:

No more weird 1-second delay
2014-12-07 12:12:19 +09: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
216cbd9e31 Fix Java 6 compatibility issue in DnsNameResolver
Related: #3173

Motivation:

DnsNameResolver was using InetSocketAddress.getHostString() which is
only available since Java 7.

Modifications:

Use InetSocketAddress.getHostName() in lieu of getHostString() when the
current Java version is less than 7.

Result:

DnsNameResolver runs fine on Java 6.
2014-12-06 22:33: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
Trustin Lee
13ad58aed7 Fix a bug where Recycler's capacity can increase beyond its maximum
Related: #3166

Motivation:

When the recyclable object created at one thread is returned at the
other thread, it is stored in a WeakOrderedQueue.

The objects stored in the WeakOrderedQueue is added back to the stack by
WeakOrderedQueue.transfer() when the owner thread ran out of recyclable
objects.

However, WeakOrderedQueue.transfer() does not have any mechanism that
prevents the stack from growing beyond its maximum capacity.

Modifications:

- Make WeakOrderedQueue.transfer() increase the capacity of the stack
  only up to its maximum
- Add tests for the cases where the recyclable object is returned at the
  non-owner thread
- Fix a bug where Stack.scavengeSome() does not scavenge the objects
  when it's the first time it ran out of objects and thus its cursor is
  null.
- Overall clean-up of scavengeSome() and transfer()

Result:

The capacity of Stack never increases beyond its maximum.
2014-12-06 17:58:53 +09:00
Greg Gibeling
47319d3cfc Lazily check for root, avoids unnecessary errors & resources
Motivation:

io.netty.util.internal.PlatformDependent.isRoot() depends on the IS_ROOT field which is filled in during class initialization. This spawns processes and consumes resources, which are not generally necessary to the complete functioning of that class.

Modifications:

This switches the class to use lazy initialization this field inside of the isRoot() method using double-checked locking (http://en.wikipedia.org/wiki/Double-checked_locking).

Result:

The first call to isRoot() will be slightly slower, at a tradeoff that class loading is faster, uses fewer resources and platform errors are avoided unless necessary.
2014-12-05 10:02:39 +01:00
Daniel Norberg
4e09c305ab example: memcache: fix set command
Motivation:

The example MemcacheClient set command doesn't work.

Modifications:

Fill the extras field buffer with zeros so that it gets written to the
request payload.

Result:

The example MemcacheClient set command works.
2014-12-05 08:59:55 +01:00
Trustin Lee
c797e7bdc5 Fix a race condition where handler is removed before unregistration
Related: #3156

Motivation:

Let's say we have a channel with the following pipeline configuration:

  HEAD --> [E1] H1 --> [E2] H2 --> TAIL

when the channel is deregistered, the channelUnregistered() methods of
H1 and H2 will be invoked from the executor thread of E1 and E2
respectively. To ensure that the channelUnregistered() methods are
invoked from the correct thread, new one-time tasks will be created
accordingly and be scheduled via Executor.execute(Runnable).

As soon as the one-time tasks are scheduled,
DefaultChannelPipeline.fireChannelUnregistered() will start to remove
all handlers from the pipeline via teardownAll(). This process is
performed in reversed order of event propagation. i.e. H2 is removed
first, and then H1 is removed.

If the channelUnregistered() event has been passed to H2 before H2 is
removed, a user does not see any problem.

If H2 has been removed before channelUnregistered() event is passed to
H2, a user will often see the following confusing warning message:

  An exceptionCaught() event was fired, and it reached at the tail of
  the pipeline. It usually means the last handler in the pipeline did
  not handle the exception.

Modifications:

To ensure that the handlers are removed *after* all events are
propagated, traverse the pipeline in ascending order before performing
the actual removal.

Result:

A user does not get the confusing warning message anymore.
2014-12-05 16:12:34 +09:00
Scott Mitchell
2d10b252f9 HTTP/2 Inbound Flow Control Connection Window Issues
Motivation:
The inbound flow control code was returning too many bytes to the connection window.  This was resulting in GO_AWAYs being generated by peers with the error code indicating a flow control issue.  Bytes were being returned to the connection window before the call to returnProcessedBytes. All of the state representing the connection window was not updated when a local settings event occurred.

Modifications:
The DefaultHttp2InboundFlowController will be updated to correct the above defects.
The unit tests will be updated to reflect the changes.

Result:
Inbound flow control algorithm does not cause peers to send flow control errors for the above mentioned cases.
2014-12-04 14:10:11 -05:00
Trustin Lee
91da1e35ab Add missing @Override annotation 2014-12-04 20:52:55 +09:00
Trustin Lee
1f703285e3 Fix checkstyle 2014-12-04 18:40:56 +09:00
Trustin Lee
0ee7e61734 Overall clean-up of the initial SniHandler/DomainNameMapping work
- Parameterize DomainNameMapping to make it useful for other use cases
  than just mapping to SslContext
- Move DomainNameMapping to io.netty.util
- Clean-up the API documentation
- Make SniHandler.hostname and sslContext volatile because they can be
  accessed by non-I/O threads
2014-12-04 18:19:50 +09:00
Trustin Lee
078072632a Fix dependency issues with hamcrest
Motivation:

We use 3 (!) libraries to build mock objects - easymock, mockito, jmock.
Mockito and jMock pulls in the different versions of Hamcrest, and it
conflicts with the version pulled by jUnit.

Modifications:

- Replace mockito-all with mockito-core to avoid pulling in outdated
  jUnit and Hamcrest
- Exclude junit-dep when pulling in jmock-junit4, because it pulls an
  outdated Hamcrest version
- Pull in the hamcrest-library version used by jUnit explicitly

Result:

No more dependency hell that results in NoSuchMethodError during the
tests
2014-12-04 17:53:35 +09:00
Sun Ning
bd63697687 Added support for SSL Server Name Indication.
Motivation:

When we need to host multiple server name with a single IP, it requires
the server to support Server Name Indication extension to serve clients
with proper certificate. So the SniHandler will host multiple
SslContext(s) and append SslHandler for requested hostname.

Modification:

* Added SniHandler to host multiple certifications in a single server
* Test case

Result:

User could use SniHandler to host multiple certifcates at a time.
It's server-side only.
2014-12-03 11:07:44 +01:00
Ronald Chen
a5b7169eb4 Rocumented decoder pitfalls to avoid mistakes found in [#3184] 2014-12-01 20:25:38 +01:00
Sam Young
02bf56e3da Add @SafeVarargs to PromiseAggregator#add and PromiseNotifier#(...) https://github.com/netty/netty/issues/3147
Motivation:

8fbc513 introduced stray warnings in callsites of
PromiseAggregator#add and PromiseNotifier#(...).

Modifications:

This commit adds the @SafeVarargs annotation to PromiseAggregator#add
and PromiseNotifier#(...). As Netty is built with JDK7, this is a
recognized annotation and should not affect runtime VM versions 1.5 and
1.6.

Result:

Building Netty with JDK7 will no longer produce warnings in the
callsites mentioned above.
2014-12-01 19:59:03 +01:00
Trustin Lee
9acf4a800a Copy the resolver configuration when cloning Bootstrap
Motivation:

Bootstrap.clone() does not copy the resolver configuration.

Modifications:

Copy the resolver configuration when cloning.

Result:

Bug fixed
2014-12-01 19:48:59 +09:00
Jay
7b39968f57 Check the bindFuture before writing a DNS query
Related: #3149

Motivation:

DnsQueryContext, using the DatagramChannel bound in DnsNameResolver,
blindly writes to the channel without checking the bind future for
success.

Modifications:

Check the bindFuture before writing a DNS query to a DatagramChannel

Result:

Bug fixed
2014-12-01 19:44:25 +09:00
Frank Barber
e9bcc518fc Prevent channel re-registration from firing channelActive
Motivation:

AbstractUnsafe considers two possibilities during channel registration. First,
the channel may be an outgoing connection, in which case it will be registered
before becoming active. Second, the channel may be an incoming connection in,
which case the channel will already be active when it is registered. To handle
the second case, AbstractUnsafe checks if the channel is active after
registration and calls ChannelPipeline.fireChannelActive() if so.  However, if
an active channel is deregistered and then re-registered this logic causes a
second fireChannelActive() to be invoked. This is unexpected; it is reasonable
for handlers to assume that this method will only be invoked once per channel.

Modifications:

This change introduces a flag into AbstractUnsafe to recognize if this is the
first or a subsequent registration. ChannelPipeline.fireChannelActive() is only
possible for the first registration.

Result:

ChannelPipeline.fireChannelActive() is only called once.
2014-11-30 20:09:03 +01:00
Ronald Chen
dd3036be02 replaced broken &lt with < and same for gt 2014-11-29 19:31:05 +01:00
Graham Edgecombe
d6c3b3063f Use Triple DES in JdkSslContext cipher suite list.
Motivation:

JdkSslContext used SSL_RSA_WITH_DES_CBC_SHA in its cipher suite list.
OpenSslServerContext used DES-CBC3-SHA in the same place in its cipher suite
list, which is equivalent to SSL_RSA_WITH_3DES_EDE_CBC_SHA.

This means the lists were out of sync. Furthermore, using
SSL_RSA_WITH_DES_CBC_SHA is not desirable as it uses DES, a weak cipher. Triple
DES should be used instead.

Modifications:

Replace SSL_RSA_WITH_DES_CBC_SHA with SSL_RSA_WITH_3DES_EDE_CBC_SHA in
JdkSslContext.

Result:

The JdkSslContext and OpenSslServerContext cipher suite lists are now in sync.
Triple DES is used instead of DES, which is stronger.
2014-11-27 06:45:23 +01:00
Trustin Lee
8baeff159d Remove or de-prioritize RC4 from default cipher suites
Motivation:

RC4 is not a recommended cipher suite anymore, as the recent research
reveals, such as:

- http://www.isg.rhul.ac.uk/tls/

Modifications:

- Remove most RC4 cipher suites from the default cipher suites
- For backward compatibility, leave RC4-SHA, while de-prioritizing it

Result:

Potentially safer default
2014-11-25 17:13:05 +09:00
Scott Mitchell
deb815f6cb HTTP/2 Prohibitied Cihpers Allowed
Motivation:
The Http2SecurityUtil class lists a few ciphers that are explicitly prohibited by the HTTP/2 specification because of their characteristics.

Modifications:
Remove the ciphers that are prohibited.

Results:
Cipher suite used for HTTP/2 codec is compatible with HTTP/2 spec.
2014-11-24 19:06:14 -05:00
Scott Mitchell
198f8fa95e HTTP/2 throw statement missed
Motivation:
The DefaultHttp2FrameWriter has an exception generated but is missing the throw keyword.

Modifications:
Insert the missing throw keyword.

Result:
Exception thrown when it was intended to be thrown.
2014-11-23 20:45:47 -05: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
df7a1223f4 Fix awful naming 2014-11-22 07:47:06 +09:00
Trustin Lee
d87be08933 Add back IntObjectMap.values(Class<V>)
Motivation:

Although the new IntObjectMap.values() that returns Collection is
useful, the removed values(Class<V>) that returns an array is also
useful. It's also good for backward compatibility.

Modifications:

- Add IntObjectMap.values(Class<V>) back
- Miscellaneous improvements
  - Cache the collection returned by IntObjectHashMap.values()
  - Inspector warnings
- Update the IntObjectHashMapTest to test both values()

Result:

- Backward compatibility
- Potential performance improvement of values()
2014-11-22 07:40:32 +09:00
nmittler
c9e5238ea6 HTTP/2 inbound flow control requests too many bytes in WINDOW_UPDATE.
Motivation:
The DefaultHttp2InboundFlowController uses processedBytes to determine
when to send the WINDOW_UPDATE, but uses window to determine the delta
to send in the request. This is incorrect since we shouldn't be
requesting bytes that haven't been processed.

Modifications:
Changed DefaultHttp2InboundFlowController to use processedBytes in the
calculation of the delta to send in the WINDOW_UPDATE request.

Result:
Inbound flow control only asks for bytes that have been processed in
WINDOW_UPDATE.
2014-11-21 08:15:27 -08:00
nmittler
171fbf3b41 Race condition with completion of Channel closeFuture and unregistration.
Motivation:
AbstractChannel.close() completes the closeFuture and then proceeds to
schedule a task to fireChannelInactive and unregister the channel. If
the user shuts down the EventLoop as a result of the closeFuture
completing this can result in a RejectedExecutionException when the
unregister task is scheduled.  This is mostly noise, but it does
somewhat pollute the logs.

Modifications:
Changed AbstractChannel.close() to not complete the channelFuture and
promise until after the unregistration task is scheduled.

Result:
Noisy error log should no longer be an issue.
2014-11-21 15:07:02 +01:00
Trustin Lee
4ba2ce3cbb Do not write LastHttpContent twice in HttpStaticFileServer example
Related: #3122

Motivation:

The HttpStaticFileServer example writes the LastHttpContent twice at the
end of the transfer.  HttpChunkedInput already produces a
LastHttpContent at the end of the stream, so there's no reason to write
another.

Modifications:

Do not write LastHttpContent in HttpStaticFileServerHandler when
HttpChunkedInput is used to transfer a file.

Result:

HttpStaticFileServer does not violates the protocol anymore.
2014-11-21 11:46:18 +09: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