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 2005/04/07 23:26:11 UTC

svn commit: r160474 - in jakarta/httpclient/trunk/http-common/src: java/org/apache/http/impl/NIOHttpDataReceiver.java test/org/apache/http/impl/TestNIOHttpTransmitterAndReceiver.java test/org/apache/http/mockup/HttpDataReceiverMockup.java

Author: olegk
Date: Thu Apr  7 14:26:09 2005
New Revision: 160474

URL: http://svn.apache.org/viewcvs?view=rev&rev=160474
Log:
Fixed a serious bug in NIOHttpDataReceiver#readLine

Modified:
    jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOHttpDataReceiver.java
    jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestNIOHttpTransmitterAndReceiver.java
    jakarta/httpclient/trunk/http-common/src/test/org/apache/http/mockup/HttpDataReceiverMockup.java

Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOHttpDataReceiver.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOHttpDataReceiver.java?view=diff&r1=160473&r2=160474
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOHttpDataReceiver.java (original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOHttpDataReceiver.java Thu Apr  7 14:26:09 2005
@@ -35,6 +35,7 @@
 import java.nio.channels.ReadableByteChannel;
 import java.nio.charset.Charset;
 import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CoderResult;
 import java.nio.charset.CodingErrorAction;
 
 import org.apache.http.io.HttpDataReceiver;
@@ -161,7 +162,17 @@
                 // read up to the end of line
                 int origLimit = this.buffer.limit();
                 this.buffer.limit(i + 1);
-                chardecoder.decode(this.buffer, tmp, true);
+                for (;;) {
+                    CoderResult result = chardecoder.decode(this.buffer, tmp, true);
+                    if (result.isOverflow()) {
+                        tmp.flip();
+                        line.append(tmp.array(), tmp.position(), tmp.remaining());
+                        tmp.clear();
+                    }
+                    if (result.isUnderflow()) {
+                        break;
+                    }
+                }
                 this.buffer.limit(origLimit);
             } else {
                 // end of line not found

Modified: jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestNIOHttpTransmitterAndReceiver.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestNIOHttpTransmitterAndReceiver.java?view=diff&r1=160473&r2=160474
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestNIOHttpTransmitterAndReceiver.java (original)
+++ jakarta/httpclient/trunk/http-common/src/test/org/apache/http/impl/TestNIOHttpTransmitterAndReceiver.java Thu Apr  7 14:26:09 2005
@@ -31,6 +31,7 @@
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
 
 import org.apache.http.io.HttpDataReceiver;
 import org.apache.http.io.HttpDataTransmitter;
@@ -85,7 +86,7 @@
         HttpDataReceiver receiver2 = 
             new HttpDataReceiverMockup (Channels.newChannel(in), 200000000); 
         try {
-            HttpDataReceiver receiver3 = new HttpDataReceiverMockup(null, 1024); 
+            HttpDataReceiver receiver3 = new HttpDataReceiverMockup((ReadableByteChannel)null, 1024); 
             fail("IllegalArgumentException should have been thrown");
         } catch (IllegalArgumentException ex) {
             //expected
@@ -182,6 +183,40 @@
         assertNull(receiver.readLine());
     }
     
+    public void testBasicReadWriteLineLargeBuffer() throws Exception {
+        
+        String[] teststrs = new String[5];
+        teststrs[0] = "Hello";
+        teststrs[1] = "This string should be much longer than the size of the output buffer " +
+                "which is only 16 bytes for this test";
+        StringBuffer buffer = new StringBuffer();
+        for (int i = 0; i < 15; i++) {
+            buffer.append("123456789 ");
+        }
+        buffer.append("and stuff like that");
+        teststrs[2] = buffer.toString();
+        teststrs[3] = "";
+        teststrs[4] = "And goodbye";
+        
+        HttpDataTransmitterMockup transmitter = new HttpDataTransmitterMockup(); 
+        for (int i = 0; i < teststrs.length; i++) {
+            transmitter.writeLine(teststrs[i]);
+        }
+        //this write operation should have no effect
+        transmitter.writeLine(null);
+        transmitter.flush();
+        
+        HttpDataReceiverMockup receiver = new HttpDataReceiverMockup(transmitter.getData(), 1024);
+
+        assertTrue(receiver.isDataAvailable(0));
+        
+        for (int i = 0; i < teststrs.length; i++) {
+            assertEquals(teststrs[i], receiver.readLine());
+        }
+        assertNull(receiver.readLine());
+        assertNull(receiver.readLine());
+    }
+
     public void testReadWriteBytes() throws Exception {
         // make the buffer larger than that of transmitter
         byte[] out = new byte[40];

Modified: jakarta/httpclient/trunk/http-common/src/test/org/apache/http/mockup/HttpDataReceiverMockup.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/test/org/apache/http/mockup/HttpDataReceiverMockup.java?view=diff&r1=160473&r2=160474
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/test/org/apache/http/mockup/HttpDataReceiverMockup.java (original)
+++ jakarta/httpclient/trunk/http-common/src/test/org/apache/http/mockup/HttpDataReceiverMockup.java Thu Apr  7 14:26:09 2005
@@ -28,9 +28,21 @@
                 BUFFER_SIZE);
     }
 
+    public HttpDataReceiverMockup(final byte[] bytes, int buffersize) {
+        super();
+        init(Channels.newChannel(
+                new ByteArrayInputStream(bytes)),
+                buffersize);
+    }
+
+    public HttpDataReceiverMockup(final String s, final String charset, int buffersize) 
+        throws UnsupportedEncodingException {
+        this(s.getBytes(charset), buffersize);
+    }
+    
     public HttpDataReceiverMockup(final String s, final String charset) 
         throws UnsupportedEncodingException {
         this(s.getBytes(charset));
-    }
     
+    }
 }