You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2009/05/21 15:22:40 UTC
svn commit: r777111 - in /httpcomponents/httpcore/branches/4.0.x: ./
httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/
httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/
httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/
Author: olegk
Date: Thu May 21 13:22:39 2009
New Revision: 777111
URL: http://svn.apache.org/viewvc?rev=777111&view=rev
Log:
Backported HTTPCORE-193, HTTPCORE-197 to 4.0.x branch
Modified:
httpcomponents/httpcore/branches/4.0.x/RELEASE_NOTES.txt
httpcomponents/httpcore/branches/4.0.x/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkDecoder.java
httpcomponents/httpcore/branches/4.0.x/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSession.java
httpcomponents/httpcore/branches/4.0.x/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkDecoder.java
Modified: httpcomponents/httpcore/branches/4.0.x/RELEASE_NOTES.txt
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/branches/4.0.x/RELEASE_NOTES.txt?rev=777111&r1=777110&r2=777111&view=diff
==============================================================================
--- httpcomponents/httpcore/branches/4.0.x/RELEASE_NOTES.txt (original)
+++ httpcomponents/httpcore/branches/4.0.x/RELEASE_NOTES.txt Thu May 21 13:22:39 2009
@@ -1,3 +1,17 @@
+Changes since 4.0
+-------------------
+
+* [HTTPCORE-197] Fixed bug causing the non-blocking ChunkDecoder to report some data stream as
+ truncated under special conditions.
+ Contributed by Denis Rogov <denrogov at gmail.com> and Oleg Kalnichevski <olegk at apache.org>
+
+* SSLIOSession#isAppOutputReady and SSLIOSession#isAppInputReady no longer ignore the application
+ event mask causing I/O event notifications for unrequested type of events.
+ Contributed by Oleg Kalnichevski <olegk at apache.org>
+
+* [HTTPCORE-193] Fixed problem with SSLIOSession incorrectly handling of end-of-stream condition.
+ Contributed by Asankha C. Perera <asankha at apache.org> and Oleg Kalnichevski <olegk at apache.org>
+
Release 4.0
-------------------
Modified: httpcomponents/httpcore/branches/4.0.x/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkDecoder.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/branches/4.0.x/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkDecoder.java?rev=777111&r1=777110&r2=777111&view=diff
==============================================================================
--- httpcomponents/httpcore/branches/4.0.x/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkDecoder.java (original)
+++ httpcomponents/httpcore/branches/4.0.x/httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/ChunkDecoder.java Thu May 21 13:22:39 2009
@@ -199,11 +199,18 @@
}
int maxLen = this.chunkSize - this.pos;
int len = this.buffer.read(dst, maxLen);
- if (maxLen > 0 && len == 0 && this.endOfStream) {
- throw new MalformedChunkCodingException("Truncated chunk");
+ if (len > 0) {
+ this.pos += len;
+ totalRead += len;
+ } else {
+ if (!this.buffer.hasData() && this.endOfStream) {
+ this.state = COMPLETED;
+ this.completed = true;
+ throw new MalformedChunkCodingException("Truncated chunk "
+ + "( expected size: " + this.chunkSize
+ + "; actual size: " + this.pos + ")");
+ }
}
- this.pos += len;
- totalRead += len;
if (this.pos == this.chunkSize) {
// At the end of the chunk
Modified: httpcomponents/httpcore/branches/4.0.x/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSession.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/branches/4.0.x/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSession.java?rev=777111&r1=777110&r2=777111&view=diff
==============================================================================
--- httpcomponents/httpcore/branches/4.0.x/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSession.java (original)
+++ httpcomponents/httpcore/branches/4.0.x/httpcore-nio/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSession.java Thu May 21 13:22:39 2009
@@ -36,6 +36,7 @@
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ByteChannel;
+import java.nio.channels.SelectionKey;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
@@ -72,6 +73,7 @@
private int appEventMask;
private SessionBufferStatus appBufferStatus;
+ private boolean endOfStream;
private volatile int status;
public SSLIOSession(
@@ -163,6 +165,9 @@
if (result.getStatus() == Status.CLOSED) {
this.status = CLOSED;
}
+ if (result.getStatus() == Status.BUFFER_UNDERFLOW && this.endOfStream) {
+ this.status = CLOSED;
+ }
break;
case NEED_TASK:
Runnable r = this.sslEngine.getDelegatedTask();
@@ -246,6 +251,9 @@
if (result.getStatus() == Status.CLOSED) {
this.status = CLOSED;
}
+ if (result.getStatus() == Status.BUFFER_UNDERFLOW && this.endOfStream) {
+ this.status = CLOSED;
+ }
if (result.getStatus() == Status.OK) {
decrypted = true;
}
@@ -256,19 +264,21 @@
public synchronized boolean isAppInputReady() throws IOException {
int bytesRead = receiveEncryptedData();
if (bytesRead == -1) {
- this.status = CLOSED;
+ this.endOfStream = true;
}
doHandshake();
decryptData();
// Some decrypted data is available or at the end of stream
- return this.inPlain.position() > 0 || this.status != ACTIVE;
+ return (this.appEventMask & SelectionKey.OP_READ) > 0
+ && (this.inPlain.position() > 0 || (this.endOfStream && this.status == ACTIVE));
}
/**
* @throws IOException - not thrown currently
*/
public synchronized boolean isAppOutputReady() throws IOException {
- return this.status == ACTIVE
+ return (this.appEventMask & SelectionKey.OP_WRITE) > 0
+ && this.status == ACTIVE
&& this.sslEngine.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING;
}
@@ -324,10 +334,10 @@
this.inPlain.compact();
return n;
} else {
- if (this.status == ACTIVE) {
- return 0;
- } else {
+ if (this.endOfStream) {
return -1;
+ } else {
+ return 0;
}
}
}
Modified: httpcomponents/httpcore/branches/4.0.x/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkDecoder.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/branches/4.0.x/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkDecoder.java?rev=777111&r1=777110&r2=777111&view=diff
==============================================================================
--- httpcomponents/httpcore/branches/4.0.x/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkDecoder.java (original)
+++ httpcomponents/httpcore/branches/4.0.x/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkDecoder.java Thu May 21 13:22:39 2009
@@ -354,6 +354,39 @@
assertTrue(decoder.isCompleted());
}
+ public void testReadingWitSmallBuffer() throws Exception {
+ String s = "10\r\n1234567890123456\r\n" +
+ "40\r\n12345678901234561234567890123456" +
+ "12345678901234561234567890123456\r\n0\r\n";
+ ReadableByteChannel channel = new ReadableByteChannelMockup(
+ new String[] {s}, "US-ASCII");
+ HttpParams params = new BasicHttpParams();
+
+ SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, params);
+ HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+ ChunkDecoder decoder = new ChunkDecoder(channel, inbuf, metrics);
+
+ ByteBuffer dst = ByteBuffer.allocate(1024);
+ ByteBuffer tmp = ByteBuffer.allocate(10);
+
+ int bytesRead = 0;
+ while (dst.hasRemaining() && !decoder.isCompleted()) {
+ int i = decoder.read(tmp);
+ if (i > 0) {
+ bytesRead += i;
+ tmp.flip();
+ dst.put(tmp);
+ tmp.compact();
+ }
+ }
+
+ assertEquals(80, bytesRead);
+ assertEquals("12345678901234561234567890123456" +
+ "12345678901234561234567890123456" +
+ "1234567890123456", convert(dst));
+ assertTrue(decoder.isCompleted());
+ }
+
public void testEndOfStreamConditionReadingFooters() throws Exception {
String s = "10\r\n1234567890123456\r\n" +
"5\r\n12345\r\n5\r\n12345\r\n0\r\n";