Author: violetagg
Date: Fri Oct 28 11:18:05 2016
New Revision: 1767004
URL: http://svn.apache.org/viewvc?rev=1767004&view=rev
Log:
Introduce a new method o.a.coyote.InputBuffer.doRead(ApplicationBufferHandler)
Modified:
tomcat/tc8.5.x/trunk/ (props changed)
tomcat/tc8.5.x/trunk/java/org/apache/catalina/connector/InputBuffer.java
tomcat/tc8.5.x/trunk/java/org/apache/coyote/InputBuffer.java
tomcat/tc8.5.x/trunk/java/org/apache/coyote/Request.java
tomcat/tc8.5.x/trunk/java/org/apache/coyote/ajp/AjpProcessor.java
tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/Http11InputBuffer.java
tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/filters/BufferedInputFilter.java
tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/filters/IdentityInputFilter.java
tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/filters/SavedRequestInputFilter.java
tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/filters/VoidInputFilter.java
tomcat/tc8.5.x/trunk/java/org/apache/coyote/http2/Stream.java
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/ApplicationBufferHandler.java
Propchange: tomcat/tc8.5.x/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Oct 28 11:18:05 2016
@@ -1 +1 @@
-/tomcat/trunk:1734785,1734799,1734845,1734928,1735041,1735044,1735480,1735577,1735597,1735599-1735600,1735615,1736145,1736162,1736209,1736280,1736297,1736299,1736489,1736646,1736703,1736836,1736849,1737104-1737105,1737112,1737117,1737119-1737120,1737155,1737157,1737192,1737280,1737339,1737632,1737664,1737715,1737748,1737785,1737834,1737860,1737903,1737959,1738005,1738007,1738014-1738015,1738018,1738022,1738039,1738043,1738059-1738060,1738147,1738149,1738174-1738175,1738261,1738589,1738623-1738625,1738643,1738816,1738850,1738855,1738946-1738948,1738953-1738954,1738979,1738982,1739079-1739081,1739087,1739113,1739153,1739172,1739176,1739191,1739474,1739726,1739762,1739775,1739814,1739817-1739818,1739975,1740131,1740324,1740465,1740495,1740508-1740509,1740520,1740535,1740707,1740803,1740810,1740969,1740980,1740991,1740997,1741015,1741033,1741036,1741058,1741060,1741080,1741147,1741159,1741164,1741173,1741181,1741190,1741197,1741202,1741208,1741213,1741221,1741225,1741232,1741409,1741501
,1741677,1741892,1741896,1741984,1742023,1742042,1742071,1742090,1742093,1742101,1742105,1742111,1742139,1742146,1742148,1742166,1742181,1742184,1742187,1742246,1742248-1742251,1742263-1742264,1742268,1742276,1742369,1742387,1742448,1742509-1742512,1742917,1742919,1742933,1742975-1742976,1742984,1742986,1743019,1743115,1743117,1743124-1743125,1743134,1743425,1743554,1743679,1743696-1743698,1743700-1743701,1744058,1744064-1744065,1744125,1744194,1744229,1744270,1744323,1744432,1744684,1744697,1744705,1744713,1744760,1744786,1745083,1745142-1745143,1745145,1745177,1745179-1745180,1745227,1745248,1745254,1745337,1745467,1745473,1745576,1745735,1745744,1746304,1746306-1746307,1746319,1746327,1746338,1746340-1746341,1746344,1746427,1746441,1746473,1746490,1746492,1746495-1746496,1746499-1746501,1746503-1746507,1746509,1746549,1746551,1746554,1746556,1746558,1746584,1746620,1746649,1746724,1746939,1746989,1747014,1747028,1747035,1747210,1747225,1747234,1747253,1747404,1747506,1747536,1747
924,1747980,1747993,1748001,1748253,1748452,1748547,1748629,1748676,1748715,1749287,1749296,1749328,1749373,1749465,1749506,1749508,1749665-1749666,1749763,1749865-1749866,1749898,1749978,1749980,1750011,1750015,1750056,1750480,1750617,1750634,1750692,1750697,1750700,1750703,1750707,1750714,1750718,1750723,1750774,1750899,1750975,1750995,1751061,1751097,1751173,1751438,1751447,1751463,1751702,1752212,1752737,1752745,1753078,1753080,1753358,1753363,1754111,1754140-1754141,1754281,1754310,1754445,1754467,1754494,1754496,1754528,1754532-1754533,1754613,1754714,1754874,1754941,1754944,1754950-1754951,1755005,1755007,1755009,1755132,1755180-1755181,1755185,1755190,1755204-1755206,1755208,1755214,1755224,1755227,1755230,1755629,1755646-1755647,1755650,1755653,1755675,1755680,1755683,1755693,1755717,1755731-1755737,1755812,1755828,1755884,1755890,1755918-1755919,1755942,1755958,1755960,1755970,1755993,1756013,1756019,1756039,1756056,1756083-1756114,1756175,1756288-1756289,1756408-1756410,1
756778,1756798,1756878,1756898,1756939,1757123-1757124,1757126,1757128,1757132-1757133,1757136,1757145,1757167-1757168,1757175,1757180,1757182,1757195,1757271,1757278,1757347,1757353-1757354,1757363,1757374,1757399,1757406,1757408,1757485,1757495,1757499,1757527,1757578,1757684,1757722,1757727,1757790,1757799,1757813,1757853,1757883,1757903,1757976,1757997,1758000,1758058,1758072-1758075,1758078-1758079,1758223,1758257,1758261,1758276,1758292,1758369,1758378-1758383,1758421,1758423,1758425-1758427,1758430,1758443,1758448,1758459,1758483,1758486-1758487,1758499,1758525,1758556,1758580,1758582,1758584,1758588,1758842,1759019,1759212,1759224,1759227,1759252,1759274,1759513-1759516,1759611,1759757,1759785-1759790,1760005,1760022,1760109-1760110,1760135,1760200-1760201,1760227,1760300,1760397,1760446,1760454,1760640,1760648,1761057,1761422,1761491,1761498,1761500-1761501,1761550,1761553,1761572,1761574,1761625-1761626,1761628,1761682,1761740,1761752,1762051-1762053,1762123,1762168,176217
2,1762182,1762201-1762202,1762204,1762208,1762288,1762296,1762324,1762348,1762353,1762362,1762374,1762492,1762503,1762505,1762541,1762608,1762710,1762753,1762766,1762769,1762944,1762947,1762953,1763167,1763179,1763232,1763259,1763271-1763272,1763276-1763277,1763319-1763320,1763370,1763372,1763375,1763377,1763393,1763412,1763430,1763450,1763462,1763511-1763512,1763516,1763518,1763520,1763529,1763574,1763634-1763635,1763718,1763786,1763798-1763799,1764083,1764425,1764646,1764648-1764649,1764659,1764663,1764682,1764862,1764866-1764867,1764870,1764897,1765133,1765299,1765358,1765439,1765447,1765495,1765502,1765569-1765571,1765579,1765582,1765589-1765590,1765794,1765801,1765813,1765815,1766276,1766514,1766533,1766535,1766664,1766675,1766698
+/tomcat/trunk:1734785,1734799,1734845,1734928,1735041,1735044,1735480,1735577,1735597,1735599-1735600,1735615,1736145,1736162,1736209,1736280,1736297,1736299,1736489,1736646,1736703,1736836,1736849,1737104-1737105,1737112,1737117,1737119-1737120,1737155,1737157,1737192,1737280,1737339,1737632,1737664,1737715,1737748,1737785,1737834,1737860,1737903,1737959,1738005,1738007,1738014-1738015,1738018,1738022,1738039,1738043,1738059-1738060,1738147,1738149,1738174-1738175,1738261,1738589,1738623-1738625,1738643,1738816,1738850,1738855,1738946-1738948,1738953-1738954,1738979,1738982,1739079-1739081,1739087,1739113,1739153,1739172,1739176,1739191,1739474,1739726,1739762,1739775,1739814,1739817-1739818,1739975,1740131,1740324,1740465,1740495,1740508-1740509,1740520,1740535,1740707,1740803,1740810,1740969,1740980,1740991,1740997,1741015,1741033,1741036,1741058,1741060,1741080,1741147,1741159,1741164,1741173,1741181,1741190,1741197,1741202,1741208,1741213,1741221,1741225,1741232,1741409,1741501
,1741677,1741892,1741896,1741984,1742023,1742042,1742071,1742090,1742093,1742101,1742105,1742111,1742139,1742146,1742148,1742166,1742181,1742184,1742187,1742246,1742248-1742251,1742263-1742264,1742268,1742276,1742369,1742387,1742448,1742509-1742512,1742917,1742919,1742933,1742975-1742976,1742984,1742986,1743019,1743115,1743117,1743124-1743125,1743134,1743425,1743554,1743679,1743696-1743698,1743700-1743701,1744058,1744064-1744065,1744125,1744194,1744229,1744270,1744323,1744432,1744684,1744697,1744705,1744713,1744760,1744786,1745083,1745142-1745143,1745145,1745177,1745179-1745180,1745227,1745248,1745254,1745337,1745467,1745473,1745576,1745735,1745744,1746304,1746306-1746307,1746319,1746327,1746338,1746340-1746341,1746344,1746427,1746441,1746473,1746490,1746492,1746495-1746496,1746499-1746501,1746503-1746507,1746509,1746549,1746551,1746554,1746556,1746558,1746584,1746620,1746649,1746724,1746939,1746989,1747014,1747028,1747035,1747210,1747225,1747234,1747253,1747404,1747506,1747536,1747
924,1747980,1747993,1748001,1748253,1748452,1748547,1748629,1748676,1748715,1749287,1749296,1749328,1749373,1749465,1749506,1749508,1749665-1749666,1749763,1749865-1749866,1749898,1749978,1749980,1750011,1750015,1750056,1750480,1750617,1750634,1750692,1750697,1750700,1750703,1750707,1750714,1750718,1750723,1750774,1750899,1750975,1750995,1751061,1751097,1751173,1751438,1751447,1751463,1751702,1752212,1752737,1752745,1753078,1753080,1753358,1753363,1754111,1754140-1754141,1754281,1754310,1754445,1754467,1754494,1754496,1754528,1754532-1754533,1754613,1754714,1754874,1754941,1754944,1754950-1754951,1755005,1755007,1755009,1755132,1755180-1755181,1755185,1755190,1755204-1755206,1755208,1755214,1755224,1755227,1755230,1755629,1755646-1755647,1755650,1755653,1755675,1755680,1755683,1755693,1755717,1755731-1755737,1755812,1755828,1755884,1755890,1755918-1755919,1755942,1755958,1755960,1755970,1755993,1756013,1756019,1756039,1756056,1756083-1756114,1756175,1756288-1756289,1756408-1756410,1
756778,1756798,1756878,1756898,1756939,1757123-1757124,1757126,1757128,1757132-1757133,1757136,1757145,1757167-1757168,1757175,1757180,1757182,1757195,1757271,1757278,1757347,1757353-1757354,1757363,1757374,1757399,1757406,1757408,1757485,1757495,1757499,1757527,1757578,1757684,1757722,1757727,1757790,1757799,1757813,1757853,1757883,1757903,1757976,1757997,1758000,1758058,1758072-1758075,1758078-1758079,1758223,1758257,1758261,1758276,1758292,1758369,1758378-1758383,1758421,1758423,1758425-1758427,1758430,1758443,1758448,1758459,1758483,1758486-1758487,1758499,1758525,1758556,1758580,1758582,1758584,1758588,1758842,1759019,1759212,1759224,1759227,1759252,1759274,1759513-1759516,1759611,1759757,1759785-1759790,1760005,1760022,1760109-1760110,1760135,1760200-1760201,1760227,1760300,1760397,1760446,1760454,1760640,1760648,1761057,1761422,1761491,1761498,1761500-1761501,1761550,1761553,1761572,1761574,1761625-1761626,1761628,1761682,1761740,1761752,1762051-1762053,1762123,1762168,176217
2,1762182,1762201-1762202,1762204,1762208,1762288,1762296,1762324,1762348,1762353,1762362,1762374,1762492,1762503,1762505,1762541,1762608,1762710,1762753,1762766,1762769,1762944,1762947,1762953,1763167,1763179,1763232,1763259,1763271-1763272,1763276-1763277,1763319-1763320,1763370,1763372,1763375,1763377,1763393,1763412,1763430,1763450,1763462,1763511-1763512,1763516,1763518,1763520,1763529,1763559,1763574,1763634-1763635,1763718,1763786,1763798-1763799,1764083,1764425,1764646,1764648-1764649,1764659,1764663,1764682,1764862,1764866-1764867,1764870,1764897,1765133,1765299,1765358,1765439,1765447,1765495,1765502,1765569-1765571,1765579,1765582,1765589-1765590,1765794,1765801,1765813,1765815,1766276,1766514,1766533,1766535,1766664,1766675,1766698
Modified:
tomcat/tc8.5.x/trunk/java/org/apache/catalina/connector/InputBuffer.java
URL:
http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/catalina/connector/InputBuffer.java?rev=1767004&r1=1767003&r2=1767004&view=diff
==============================================================================
--- tomcat/tc8.5.x/trunk/java/org/apache/catalina/connector/InputBuffer.java
(original)
+++ tomcat/tc8.5.x/trunk/java/org/apache/catalina/connector/InputBuffer.java
Fri Oct 28 11:18:05 2016
@@ -36,6 +36,7 @@ import org.apache.tomcat.util.buf.B2CCon
import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.buf.CharChunk;
import org.apache.tomcat.util.collections.SynchronizedStack;
+import org.apache.tomcat.util.net.ApplicationBufferHandler;
import org.apache.tomcat.util.res.StringManager;
/**
@@ -48,7 +49,7 @@ import org.apache.tomcat.util.res.String
*/
public class InputBuffer extends Reader
implements ByteChunk.ByteInputChannel, CharChunk.CharInputChannel,
- CharChunk.CharOutputChannel {
+ CharChunk.CharOutputChannel, ApplicationBufferHandler {
/**
* The string manager for this package.
@@ -75,6 +76,7 @@ public class InputBuffer extends Reader
* The byte buffer.
*/
private final ByteChunk bb;
+ private ByteBuffer tempRead;
/**
@@ -146,6 +148,8 @@ public class InputBuffer extends Reader
public InputBuffer(int size) {
this.size = size;
+ tempRead = ByteBuffer.allocate(size);
+ tempRead.flip();
bb = new ByteChunk(size);
bb.setLimit(size);
bb.setByteInputChannel(this);
@@ -314,8 +318,10 @@ public class InputBuffer extends Reader
state = BYTE_STATE;
}
- int result = coyoteRequest.doRead(bb);
-
+ int result = coyoteRequest.doRead(this);
+ bb.setBytes(tempRead.array(), tempRead.arrayOffset() +
tempRead.position(),
+ tempRead.remaining());
+ tempRead.position(0).limit(0);
return result;
}
@@ -594,4 +600,22 @@ public class InputBuffer extends Reader
}
}
+
+
+ @Override
+ public void setByteBuffer(ByteBuffer buffer) {
+ tempRead = buffer;
+ }
+
+
+ @Override
+ public ByteBuffer getByteBuffer() {
+ return tempRead;
+ }
+
+
+ @Override
+ public void expand(int size) {
+ // no-op
+ }
}
Modified: tomcat/tc8.5.x/trunk/java/org/apache/coyote/InputBuffer.java
URL:
http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/coyote/InputBuffer.java?rev=1767004&r1=1767003&r2=1767004&view=diff
==============================================================================
--- tomcat/tc8.5.x/trunk/java/org/apache/coyote/InputBuffer.java (original)
+++ tomcat/tc8.5.x/trunk/java/org/apache/coyote/InputBuffer.java Fri Oct 28
11:18:05 2016
@@ -19,6 +19,7 @@ package org.apache.coyote;
import java.io.IOException;
import org.apache.tomcat.util.buf.ByteChunk;
+import org.apache.tomcat.util.net.ApplicationBufferHandler;
/**
* This class is only for internal use in the protocol implementation. All
@@ -40,4 +41,20 @@ public interface InputBuffer {
* @throws IOException If an I/O error occurs reading from the input stream
*/
public int doRead(ByteChunk chunk) throws IOException;
+
+ /**
+ * Read from the input stream into the ByteBuffer provided by the
+ * ApplicaitonBufferHandler.
+ * IMPORTANT: the current model assumes that the protocol will 'own' the
+ * ByteBuffer and return a pointer to it.
+ *
+ * @param handler ApplicaitonBufferHandler that provides the buffer to read
+ * data into.
+ *
+ * @return The number of bytes that have been added to the buffer or -1 for
+ * end of stream
+ *
+ * @throws IOException If an I/O error occurs reading from the input stream
+ */
+ public int doRead(ApplicationBufferHandler handler) throws IOException;
}
Modified: tomcat/tc8.5.x/trunk/java/org/apache/coyote/Request.java
URL:
http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/coyote/Request.java?rev=1767004&r1=1767003&r2=1767004&view=diff
==============================================================================
--- tomcat/tc8.5.x/trunk/java/org/apache/coyote/Request.java (original)
+++ tomcat/tc8.5.x/trunk/java/org/apache/coyote/Request.java Fri Oct 28
11:18:05 2016
@@ -29,6 +29,7 @@ import org.apache.tomcat.util.buf.UDecod
import org.apache.tomcat.util.http.MimeHeaders;
import org.apache.tomcat.util.http.Parameters;
import org.apache.tomcat.util.http.ServerCookies;
+import org.apache.tomcat.util.net.ApplicationBufferHandler;
import org.apache.tomcat.util.res.StringManager;
/**
@@ -512,6 +513,31 @@ public final class Request {
if (n > 0) {
bytesRead+=n;
}
+ return n;
+ }
+
+
+ /**
+ * Read data from the input buffer and put it into
ApplicationBufferHandler.
+ *
+ * The buffer is owned by the protocol implementation - it will be reused
on
+ * the next read. The Adapter must either process the data in place or copy
+ * it to a separate buffer if it needs to hold it. In most cases this is
+ * done during byte->char conversions or via InputStream. Unlike
+ * InputStream, this interface allows the app to process data in place,
+ * without copy.
+ *
+ * @param handler The destination to which to copy the data
+ *
+ * @return The number of bytes copied
+ *
+ * @throws IOException If an I/O error occurs during the copy
+ */
+ public int doRead(ApplicationBufferHandler handler) throws IOException {
+ int n = inputBuffer.doRead(handler);
+ if (n > 0) {
+ bytesRead+=n;
+ }
return n;
}
Modified: tomcat/tc8.5.x/trunk/java/org/apache/coyote/ajp/AjpProcessor.java
URL:
http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/coyote/ajp/AjpProcessor.java?rev=1767004&r1=1767003&r2=1767004&view=diff
==============================================================================
--- tomcat/tc8.5.x/trunk/java/org/apache/coyote/ajp/AjpProcessor.java (original)
+++ tomcat/tc8.5.x/trunk/java/org/apache/coyote/ajp/AjpProcessor.java Fri Oct
28 11:18:05 2016
@@ -43,6 +43,7 @@ import org.apache.tomcat.util.buf.Messag
import org.apache.tomcat.util.http.MimeHeaders;
import org.apache.tomcat.util.net.AbstractEndpoint;
import org.apache.tomcat.util.net.AbstractEndpoint.Handler.SocketState;
+import org.apache.tomcat.util.net.ApplicationBufferHandler;
import org.apache.tomcat.util.net.SSLSupport;
import org.apache.tomcat.util.net.SocketWrapperBase;
import org.apache.tomcat.util.res.StringManager;
@@ -1395,6 +1396,23 @@ public class AjpProcessor extends Abstra
empty = true;
return chunk.getLength();
}
+
+ @Override
+ public int doRead(ApplicationBufferHandler handler) throws IOException
{
+
+ if (endOfStream) {
+ return -1;
+ }
+ if (empty) {
+ if (!refillReadBuffer(true)) {
+ return -1;
+ }
+ }
+ ByteChunk bc = bodyBytes.getByteChunk();
+ handler.setByteBuffer(ByteBuffer.wrap(bc.getBuffer(),
bc.getStart(), bc.getLength()));
+ empty = true;
+ return handler.getByteBuffer().remaining();
+ }
}
Modified:
tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/Http11InputBuffer.java
URL:
http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/Http11InputBuffer.java?rev=1767004&r1=1767003&r2=1767004&view=diff
==============================================================================
--- tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/Http11InputBuffer.java
(original)
+++ tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/Http11InputBuffer.java
Fri Oct 28 11:18:05 2016
@@ -292,6 +292,16 @@ public class Http11InputBuffer implement
}
+ @Override
+ public int doRead(ApplicationBufferHandler handler) throws IOException {
+
+ if (lastActiveFilter == -1)
+ return inputStreamInputBuffer.doRead(handler);
+ else
+ return activeFilters[lastActiveFilter].doRead(handler);
+
+ }
+
// ------------------------------------------------------- Protected
Methods
@@ -1073,6 +1083,29 @@ public class Http11InputBuffer implement
return length;
}
+
+ @Override
+ public int doRead(ApplicationBufferHandler handler) throws IOException
{
+
+ if (byteBuffer.position() >= byteBuffer.limit()) {
+ // The application is reading the HTTP request body which is
+ // always a blocking operation.
+ if (!fill(true))
+ return -1;
+ }
+
+ int length = byteBuffer.remaining();
+ handler.setByteBuffer(byteBuffer.duplicate());
+ byteBuffer.position(byteBuffer.limit());
+
+ return length;
+ }
+ }
+
+
+ @Override
+ public void setByteBuffer(ByteBuffer buffer) {
+ byteBuffer = buffer;
}
Modified:
tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/filters/BufferedInputFilter.java
URL:
http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/filters/BufferedInputFilter.java?rev=1767004&r1=1767003&r2=1767004&view=diff
==============================================================================
---
tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/filters/BufferedInputFilter.java
(original)
+++
tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/filters/BufferedInputFilter.java
Fri Oct 28 11:18:05 2016
@@ -26,12 +26,13 @@ import org.apache.coyote.InputBuffer;
import org.apache.coyote.Request;
import org.apache.coyote.http11.InputFilter;
import org.apache.tomcat.util.buf.ByteChunk;
+import org.apache.tomcat.util.net.ApplicationBufferHandler;
/**
* Input filter responsible for reading and buffering the request body, so that
* it does not interfere with client SSL handshake messages.
*/
-public class BufferedInputFilter implements InputFilter {
+public class BufferedInputFilter implements InputFilter,
ApplicationBufferHandler {
// -------------------------------------------------------------- Constants
@@ -42,7 +43,7 @@ public class BufferedInputFilter impleme
// ----------------------------------------------------- Instance Variables
private ByteBuffer buffered;
- private final ByteChunk tempRead = new ByteChunk(1024);
+ private ByteBuffer tempRead;
private InputBuffer buffer;
private boolean hasRead = false;
@@ -82,11 +83,11 @@ public class BufferedInputFilter impleme
public void setRequest(Request request) {
// save off the Request body
try {
- while (buffer.doRead(tempRead) >= 0) {
+ while (buffer.doRead(this) >= 0) {
buffered.mark().position(buffered.limit()).limit(buffered.capacity());
- buffered.put(tempRead.getBytes(), tempRead.getStart(),
tempRead.getLength());
+ buffered.put(tempRead);
buffered.limit(buffered.position()).reset();
- tempRead.recycle();
+ tempRead = null;
}
} catch(IOException | BufferOverflowException ioe) {
// No need for i18n - this isn't going to get logged anywhere
@@ -110,6 +111,20 @@ public class BufferedInputFilter impleme
return chunk.getLength();
}
+ /**
+ * Fills the given ByteBuffer with the buffered request body.
+ */
+ @Override
+ public int doRead(ApplicationBufferHandler handler) throws IOException {
+ if (isFinished()) {
+ return -1;
+ }
+
+ handler.setByteBuffer(buffered);
+ hasRead = true;
+ return buffered.remaining();
+ }
+
@Override
public void setBuffer(InputBuffer buffer) {
this.buffer = buffer;
@@ -124,7 +139,6 @@ public class BufferedInputFilter impleme
buffered.position(0).limit(0);
}
}
- tempRead.recycle();
hasRead = false;
buffer = null;
}
@@ -149,4 +163,22 @@ public class BufferedInputFilter impleme
public boolean isFinished() {
return hasRead || buffered.remaining() <= 0;
}
+
+
+ @Override
+ public void setByteBuffer(ByteBuffer buffer) {
+ tempRead = buffer;
+ }
+
+
+ @Override
+ public ByteBuffer getByteBuffer() {
+ return tempRead;
+ }
+
+
+ @Override
+ public void expand(int size) {
+ // no-op
+ }
}
Modified:
tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
URL:
http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java?rev=1767004&r1=1767003&r2=1767004&view=diff
==============================================================================
---
tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
(original)
+++
tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
Fri Oct 28 11:18:05 2016
@@ -18,6 +18,7 @@ package org.apache.coyote.http11.filters
import java.io.EOFException;
import java.io.IOException;
+import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Locale;
import java.util.Set;
@@ -30,6 +31,7 @@ import org.apache.tomcat.util.buf.ByteCh
import org.apache.tomcat.util.buf.HexUtils;
import org.apache.tomcat.util.buf.MessageBytes;
import org.apache.tomcat.util.http.MimeHeaders;
+import org.apache.tomcat.util.net.ApplicationBufferHandler;
import org.apache.tomcat.util.res.StringManager;
/**
@@ -38,7 +40,7 @@ import org.apache.tomcat.util.res.String
*
* @author Remy Maucherat
*/
-public class ChunkedInputFilter implements InputFilter {
+public class ChunkedInputFilter implements InputFilter,
ApplicationBufferHandler {
private static final StringManager sm = StringManager.getManager(
ChunkedInputFilter.class.getPackage().getName());
@@ -73,27 +75,9 @@ public class ChunkedInputFilter implemen
/**
- * Position in the buffer.
- */
- protected int pos = 0;
-
-
- /**
- * Last valid byte in the buffer.
- */
- protected int lastValid = 0;
-
-
- /**
- * Read bytes buffer.
- */
- protected byte[] buf = null;
-
-
- /**
* Byte chunk used to read bytes.
*/
- protected final ByteChunk readChunk = new ByteChunk();
+ protected ByteBuffer readChunk;
/**
@@ -189,24 +173,83 @@ public class ChunkedInputFilter implemen
int result = 0;
- if (pos >= lastValid) {
+ if (readChunk == null || readChunk.position() >= readChunk.limit()) {
+ if (readBytes() < 0) {
+ throwIOException(sm.getString("chunkedInputFilter.eos"));
+ }
+ }
+
+ if (remaining > readChunk.remaining()) {
+ result = readChunk.remaining();
+ remaining = remaining - result;
+ chunk.setBytes(readChunk.array(), readChunk.arrayOffset() +
readChunk.position(), result);
+ readChunk.position(readChunk.limit());
+ } else {
+ result = remaining;
+ chunk.setBytes(readChunk.array(), readChunk.arrayOffset() +
readChunk.position(), remaining);
+ readChunk.position(readChunk.position() + remaining);
+ remaining = 0;
+ //we need a CRLF
+ if ((readChunk.position() + 1) >= readChunk.limit()) {
+ //if we call parseCRLF we overrun the buffer here
+ //so we defer it to the next call BZ 11117
+ needCRLFParse = true;
+ } else {
+ parseCRLF(false); //parse the CRLF immediately
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ public int doRead(ApplicationBufferHandler handler) throws IOException {
+ if (endChunk) {
+ return -1;
+ }
+
+ checkError();
+
+ if(needCRLFParse) {
+ needCRLFParse = false;
+ parseCRLF(false);
+ }
+
+ if (remaining <= 0) {
+ if (!parseChunkHeader()) {
+
throwIOException(sm.getString("chunkedInputFilter.invalidHeader"));
+ }
+ if (endChunk) {
+ parseEndChunk();
+ return -1;
+ }
+ }
+
+ int result = 0;
+
+ if (readChunk == null || readChunk.position() >= readChunk.limit()) {
if (readBytes() < 0) {
throwIOException(sm.getString("chunkedInputFilter.eos"));
}
}
- if (remaining > (lastValid - pos)) {
- result = lastValid - pos;
+ if (remaining > readChunk.remaining()) {
+ result = readChunk.remaining();
remaining = remaining - result;
- chunk.setBytes(buf, pos, result);
- pos = lastValid;
+ if (readChunk != handler.getByteBuffer()) {
+ handler.setByteBuffer(readChunk.duplicate());
+ }
+ readChunk.position(readChunk.limit());
} else {
result = remaining;
- chunk.setBytes(buf, pos, remaining);
- pos = pos + remaining;
+ if (readChunk != handler.getByteBuffer()) {
+ handler.setByteBuffer(readChunk.duplicate());
+ handler.getByteBuffer().limit(readChunk.position() +
remaining);
+ }
+ readChunk.position(readChunk.position() + remaining);
remaining = 0;
//we need a CRLF
- if ((pos+1) >= lastValid) {
+ if ((readChunk.position() + 1) >= readChunk.limit()) {
//if we call parseCRLF we overrun the buffer here
//so we defer it to the next call BZ 11117
needCRLFParse = true;
@@ -238,7 +281,7 @@ public class ChunkedInputFilter implemen
long swallowed = 0;
int read = 0;
// Consume extra bytes : parse the stream until the end chunk is found
- while ((read = doRead(readChunk)) >= 0) {
+ while ((read = doRead(this)) >= 0) {
swallowed += read;
if (maxSwallowSize > -1 && swallowed > maxSwallowSize) {
throwIOException(sm.getString("inputFilter.maxSwallow"));
@@ -246,7 +289,7 @@ public class ChunkedInputFilter implemen
}
// Return the number of extra bytes which were consumed
- return lastValid - pos;
+ return readChunk.remaining();
}
@@ -255,7 +298,7 @@ public class ChunkedInputFilter implemen
*/
@Override
public int available() {
- return lastValid - pos;
+ return readChunk != null ? readChunk.remaining() : 0;
}
@@ -274,8 +317,9 @@ public class ChunkedInputFilter implemen
@Override
public void recycle() {
remaining = 0;
- pos = 0;
- lastValid = 0;
+ if (readChunk != null) {
+ readChunk.position(0).limit(0);
+ }
endChunk = false;
needCRLFParse = false;
trailingHeaders.recycle();
@@ -309,13 +353,7 @@ public class ChunkedInputFilter implemen
* @throws IOException Read error
*/
protected int readBytes() throws IOException {
-
- int nRead = buffer.doRead(readChunk);
- pos = readChunk.getStart();
- lastValid = pos + nRead;
- buf = readChunk.getBytes();
-
- return nRead;
+ return buffer.doRead(this);
}
@@ -342,15 +380,16 @@ public class ChunkedInputFilter implemen
while (!eol) {
- if (pos >= lastValid) {
+ if (readChunk == null || readChunk.position() >=
readChunk.limit()) {
if (readBytes() <= 0)
return false;
}
- if (buf[pos] == Constants.CR || buf[pos] == Constants.LF) {
+ byte chr = readChunk.get(readChunk.position());
+ if (chr == Constants.CR || chr == Constants.LF) {
parseCRLF(false);
eol = true;
- } else if (buf[pos] == Constants.SEMI_COLON && !extension) {
+ } else if (chr == Constants.SEMI_COLON && !extension) {
// First semi-colon marks the start of the extension. Further
// semi-colons may appear to separate multiple
chunk-extensions.
// These need to be processed as part of parsing the
extensions.
@@ -358,7 +397,7 @@ public class ChunkedInputFilter implemen
extensionSize++;
} else if (!extension) {
//don't read data after the trailer
- int charValue = HexUtils.getDec(buf[pos]);
+ int charValue = HexUtils.getDec(chr);
if (charValue != -1 && readDigit < 8) {
readDigit++;
result = (result << 4) | charValue;
@@ -379,7 +418,7 @@ public class ChunkedInputFilter implemen
// Parsing the CRLF increments pos
if (!eol) {
- pos++;
+ readChunk.position(readChunk.position() + 1);
}
}
@@ -410,18 +449,19 @@ public class ChunkedInputFilter implemen
boolean crfound = false;
while (!eol) {
- if (pos >= lastValid) {
+ if (readChunk == null || readChunk.position() >=
readChunk.limit()) {
if (readBytes() <= 0) {
throwIOException(sm.getString("chunkedInputFilter.invalidCrlfNoData"));
}
}
- if (buf[pos] == Constants.CR) {
+ byte chr = readChunk.get(readChunk.position());
+ if (chr == Constants.CR) {
if (crfound) {
throwIOException(sm.getString("chunkedInputFilter.invalidCrlfCRCR"));
}
crfound = true;
- } else if (buf[pos] == Constants.LF) {
+ } else if (chr == Constants.LF) {
if (!tolerant && !crfound) {
throwIOException(sm.getString("chunkedInputFilter.invalidCrlfNoCR"));
}
@@ -430,7 +470,7 @@ public class ChunkedInputFilter implemen
throwIOException(sm.getString("chunkedInputFilter.invalidCrlf"));
}
- pos++;
+ readChunk.position(readChunk.position() + 1);
}
}
@@ -454,13 +494,13 @@ public class ChunkedInputFilter implemen
byte chr = 0;
// Read new bytes if needed
- if (pos >= lastValid) {
+ if (readChunk == null || readChunk.position() >= readChunk.limit()) {
if (readBytes() <0) {
throwEOFException(sm.getString("chunkedInputFilter.eosTrailer"));
}
}
- chr = buf[pos];
+ chr = readChunk.get(readChunk.position());
// CRLF terminates the request
if (chr == Constants.CR || chr == Constants.LF) {
@@ -480,13 +520,13 @@ public class ChunkedInputFilter implemen
while (!colon) {
// Read new bytes if needed
- if (pos >= lastValid) {
+ if (readChunk == null || readChunk.position() >=
readChunk.limit()) {
if (readBytes() <0) {
throwEOFException(sm.getString("chunkedInputFilter.eosTrailer"));
}
}
- chr = buf[pos];
+ chr = readChunk.get(readChunk.position());
if ((chr >= Constants.A) && (chr <= Constants.Z)) {
chr = (byte) (chr - Constants.LC_OFFSET);
}
@@ -497,7 +537,7 @@ public class ChunkedInputFilter implemen
trailingHeaders.append(chr);
}
- pos++;
+ readChunk.position(readChunk.position() + 1);
}
int colonPos = trailingHeaders.getEnd();
@@ -518,15 +558,15 @@ public class ChunkedInputFilter implemen
while (space) {
// Read new bytes if needed
- if (pos >= lastValid) {
+ if (readChunk == null || readChunk.position() >=
readChunk.limit()) {
if (readBytes() <0) {
throwEOFException(sm.getString("chunkedInputFilter.eosTrailer"));
}
}
- chr = buf[pos];
+ chr = readChunk.get(readChunk.position());
if ((chr == Constants.SP) || (chr == Constants.HT)) {
- pos++;
+ readChunk.position(readChunk.position() + 1);
// If we swallow whitespace, make sure it counts towards
the
// limit placed on trailing header size
int newlimit = trailingHeaders.getLimit() -1;
@@ -544,13 +584,13 @@ public class ChunkedInputFilter implemen
while (!eol) {
// Read new bytes if needed
- if (pos >= lastValid) {
+ if (readChunk == null || readChunk.position() >=
readChunk.limit()) {
if (readBytes() <0) {
throwEOFException(sm.getString("chunkedInputFilter.eosTrailer"));
}
}
- chr = buf[pos];
+ chr = readChunk.get(readChunk.position());
if (chr == Constants.CR || chr == Constants.LF) {
parseCRLF(true);
eol = true;
@@ -562,7 +602,7 @@ public class ChunkedInputFilter implemen
}
if (!eol) {
- pos++;
+ readChunk.position(readChunk.position() + 1);
}
}
@@ -570,13 +610,13 @@ public class ChunkedInputFilter implemen
// is a LWS, then it's a multiline header
// Read new bytes if needed
- if (pos >= lastValid) {
+ if (readChunk == null || readChunk.position() >=
readChunk.limit()) {
if (readBytes() <0) {
throwEOFException(sm.getString("chunkedInputFilter.eosTrailer"));
}
}
- chr = buf[pos];
+ chr = readChunk.get(readChunk.position());
if ((chr != Constants.SP) && (chr != Constants.HT)) {
validLine = false;
} else {
@@ -620,4 +660,22 @@ public class ChunkedInputFilter implemen
throw new IOException(sm.getString("chunkedInputFilter.error"));
}
}
+
+
+ @Override
+ public void setByteBuffer(ByteBuffer buffer) {
+ readChunk = buffer;
+ }
+
+
+ @Override
+ public ByteBuffer getByteBuffer() {
+ return readChunk;
+ }
+
+
+ @Override
+ public void expand(int size) {
+ // no-op
+ }
}
Modified:
tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/filters/IdentityInputFilter.java
URL:
http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/filters/IdentityInputFilter.java?rev=1767004&r1=1767003&r2=1767004&view=diff
==============================================================================
---
tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/filters/IdentityInputFilter.java
(original)
+++
tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/filters/IdentityInputFilter.java
Fri Oct 28 11:18:05 2016
@@ -24,6 +24,7 @@ import org.apache.coyote.InputBuffer;
import org.apache.coyote.Request;
import org.apache.coyote.http11.InputFilter;
import org.apache.tomcat.util.buf.ByteChunk;
+import org.apache.tomcat.util.net.ApplicationBufferHandler;
import org.apache.tomcat.util.res.StringManager;
/**
@@ -118,6 +119,40 @@ public class IdentityInputFilter impleme
result = -1;
}
}
+
+ return result;
+
+ }
+
+ @Override
+ public int doRead(ApplicationBufferHandler handler) throws IOException {
+
+ int result = -1;
+
+ if (contentLength >= 0) {
+ if (remaining > 0) {
+ int nRead = buffer.doRead(handler);
+ if (nRead > remaining) {
+ // The chunk is longer than the number of bytes remaining
+ // in the body; changing the chunk length to the number
+ // of bytes remaining
+
handler.getByteBuffer().limit(handler.getByteBuffer().position() + (int)
remaining);
+ result = (int) remaining;
+ } else {
+ result = nRead;
+ }
+ if (nRead > 0) {
+ remaining = remaining - nRead;
+ }
+ } else {
+ // No more bytes left to be read : return -1 and clear the
+ // buffer
+ if (handler.getByteBuffer() != null) {
+ handler.getByteBuffer().position(0).limit(0);
+ }
+ result = -1;
+ }
+ }
return result;
Modified:
tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/filters/SavedRequestInputFilter.java
URL:
http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/filters/SavedRequestInputFilter.java?rev=1767004&r1=1767003&r2=1767004&view=diff
==============================================================================
---
tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/filters/SavedRequestInputFilter.java
(original)
+++
tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/filters/SavedRequestInputFilter.java
Fri Oct 28 11:18:05 2016
@@ -18,10 +18,12 @@
package org.apache.coyote.http11.filters;
import java.io.IOException;
+import java.nio.ByteBuffer;
import org.apache.coyote.InputBuffer;
import org.apache.coyote.http11.InputFilter;
import org.apache.tomcat.util.buf.ByteChunk;
+import org.apache.tomcat.util.net.ApplicationBufferHandler;
/**
* Input filter responsible for replaying the request body when restoring the
@@ -63,6 +65,18 @@ public class SavedRequestInputFilter imp
return writeLength;
}
+ @Override
+ public int doRead(ApplicationBufferHandler handler) throws IOException {
+ if(input.getOffset()>= input.getEnd())
+ return -1;
+
+ ByteBuffer byteBuffer = handler.getByteBuffer();
+ byteBuffer.position(byteBuffer.limit()).limit(byteBuffer.capacity());
+ input.substract(byteBuffer);
+
+ return byteBuffer.remaining();
+ }
+
/**
* Set the content length on the request.
*/
Modified:
tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/filters/VoidInputFilter.java
URL:
http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/filters/VoidInputFilter.java?rev=1767004&r1=1767003&r2=1767004&view=diff
==============================================================================
---
tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/filters/VoidInputFilter.java
(original)
+++
tomcat/tc8.5.x/trunk/java/org/apache/coyote/http11/filters/VoidInputFilter.java
Fri Oct 28 11:18:05 2016
@@ -23,6 +23,7 @@ import org.apache.coyote.InputBuffer;
import org.apache.coyote.Request;
import org.apache.coyote.http11.InputFilter;
import org.apache.tomcat.util.buf.ByteChunk;
+import org.apache.tomcat.util.net.ApplicationBufferHandler;
/**
* Void input filter, which returns -1 when attempting a read. Used with a GET,
@@ -54,6 +55,11 @@ public class VoidInputFilter implements
return -1;
}
+ @Override
+ public int doRead(ApplicationBufferHandler handler) throws IOException {
+ return -1;
+ }
+
// ---------------------------------------------------- InputFilter Methods
Modified: tomcat/tc8.5.x/trunk/java/org/apache/coyote/http2/Stream.java
URL:
http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/coyote/http2/Stream.java?rev=1767004&r1=1767003&r2=1767004&view=diff
==============================================================================
--- tomcat/tc8.5.x/trunk/java/org/apache/coyote/http2/Stream.java (original)
+++ tomcat/tc8.5.x/trunk/java/org/apache/coyote/http2/Stream.java Fri Oct 28
11:18:05 2016
@@ -33,6 +33,7 @@ import org.apache.coyote.http2.HpackDeco
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.buf.ByteChunk;
+import org.apache.tomcat.util.net.ApplicationBufferHandler;
import org.apache.tomcat.util.res.StringManager;
public class Stream extends AbstractStream implements HeaderEmitter {
@@ -765,6 +766,62 @@ public class Stream extends AbstractStre
// Increment client-side flow control windows by the number of
bytes
// read
+ handler.writeWindowUpdate(Stream.this, written, true);
+
+ return written;
+ }
+
+ @Override
+ public int doRead(ApplicationBufferHandler applicationBufferHandler)
throws IOException {
+
+ ensureBuffersExist();
+
+ int written = -1;
+
+ // Ensure that only one thread accesses inBuffer at a time
+ synchronized (inBuffer) {
+ while (inBuffer.position() == 0 && !isInputFinished()) {
+ // Need to block until some data is written
+ try {
+ if (log.isDebugEnabled()) {
+
log.debug(sm.getString("stream.inputBuffer.empty"));
+ }
+ inBuffer.wait();
+ if (reset) {
+ // TODO: i18n
+ throw new IOException("HTTP/2 Stream reset");
+ }
+ } catch (InterruptedException e) {
+ // Possible shutdown / rst or similar. Use an
+ // IOException to signal to the client that further I/O
+ // isn't possible for this Stream.
+ throw new IOException(e);
+ }
+ }
+
+ if (inBuffer.position() > 0) {
+ // Data is available in the inBuffer. Copy it to the
+ // outBuffer.
+ inBuffer.flip();
+ written = inBuffer.remaining();
+ if (log.isDebugEnabled()) {
+ log.debug(sm.getString("stream.inputBuffer.copy",
+ Integer.toString(written)));
+ }
+ inBuffer.get(outBuffer, 0, written);
+ inBuffer.clear();
+ } else if (isInputFinished()) {
+ return -1;
+ } else {
+ // Should never happen
+ throw new IllegalStateException();
+ }
+ }
+
+ applicationBufferHandler.setByteBuffer(ByteBuffer.wrap(outBuffer,
0, written));
+
+ // Increment client-side flow control windows by the number of
bytes
+ // read
handler.writeWindowUpdate(Stream.this, written, true);
return written;
Modified:
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/ApplicationBufferHandler.java
URL:
http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/ApplicationBufferHandler.java?rev=1767004&r1=1767003&r2=1767004&view=diff
==============================================================================
---
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/ApplicationBufferHandler.java
(original)
+++
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/ApplicationBufferHandler.java
Fri Oct 28 11:18:05 2016
@@ -20,10 +20,12 @@ import java.nio.ByteBuffer;
/**
* Callback interface to be able to expand buffers when buffer overflow
- * exceptions happen
+ * exceptions happen or to replace buffers
*/
public interface ApplicationBufferHandler {
+ public void setByteBuffer(ByteBuffer buffer);
+
public ByteBuffer getByteBuffer();
public void expand(int size);
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]